用某些熵生成随机数序列

Generate random number sequence with certain entropy

本文关键字:随机数序列      更新时间:2023-10-16

我需要生成数字的部分随机序列,以使整体序列具有一定的熵水平。

例如。如果我将生成的数据馈送到GZIP中,它将能够压缩它。实际上,这将是代码的确切应用,测试数据压缩机。

我正在用C 进行编程,并想到我想到的第一个想法是初始化带有随机种子的STD :: MT19937 prngs,然后随机选择一个prng,然后随机制作随机的lenght模式。STD :: MT19937每次使用相同的种子重置,因此它总是会产生相同的模式:

#include <iostream>
#include <random>
#include <vector>
int main() {
    std::random_device rd;
    std::vector<std::mt19937> rngs;
    std::vector<int> seeds;
    std::uniform_int_distribution<int> patternrg(0,31);
    std::uniform_int_distribution<int> lenghtrg(1,64);
    std::uniform_int_distribution<int> valuerg(0,255);
    for(int i = 0; i < 32; ++i) {
        seeds.push_back(rd());
        rngs.emplace_back(seeds.back());
    }
    for(;;) {
        // Choose generator and pattern lenght randomly.
        auto gen = patternrg(rd);
        auto len = lenghtrg(rd);
        rngs[gen].seed(seeds[gen]);
        for(int i = 0; i < len; ++i) {
            std::cout << valuerg( rngs[gen] )<<"n";
        }
    }
}

上面的代码是生成可压缩随机性的第一个要求,但第二个要求更难:如何控制级熵/随机性?

让我写几个句子,您可以找到有用的句子。假设我们要用给定的熵进行一次点数。因此,它是0或1,您想要的熵等于e

h(10 | p)= -p log 2 (p) - (1- p)log 2 (1- p),其中 p可能是获得1.简单测试 - 如果p = 1/2,则将获得1-最大熵的熵。那么你选择e等于1以下的某些值,求解方程

-p log 2 (p) - (1- p)log 2 (1- p)= e

并恢复p,然后您可以使用Bernoulli发行版开始采样。简单的演示在这里。在C 中,一个人可以使用标准库例程。

好吧,假设您想用给定的熵采样一个字节。它有256个值,熵

h(byte | vec {p})= -sum(1 ... 256)>)。

再次,如果所有组合都是均衡的(p i = 1/256),您将获得-256/256 log 2 (1/256)= 8,这是最大熵。如果您现在修复了熵(例如,我希望它是7),那么P i 的解决方案数量无限,没有给定熵的单个唯一实现。

您可以稍微简化问题 - 让我们再次考虑一个参数案例,其中查找1的概率是p,并且查找0 IS(1 -P)的概率。因此,从256个结果开始,我们现在得到了其中的9个-00000000,00000001、00000011、00000111、0000111111,00001111,00011111,00111111111111111111111111111111111111111111111111111111111111。对于每种情况,我们都可以编写概率,计算熵,将其分配给您想要的任何东西,然后求解以找到p

采样相对容易 - 第一步是通过离散分布进行9组组合的样品,第二步将是使用Fisher -Yates Shuffle在字节内进行的洗牌位。

可以使用相同的方法,例如32bits或64bits-您有33或65个情况,构造熵,分配给您想要的任何东西,找到p,示例其中一个,然后抽样值内的洗牌位。

现在没有代码,但是如果有兴趣...

,我稍后可能会写一些代码

更新

牢记固定熵的另一个特殊属性。即使对于单个位的简单情况,如果您尝试解决

-p log 2 (p) - (1- p)log 2 (1- p)= e

对于给定的e,您将获得两个答案,并且很容易理解为什么 - 方程为对称WRT p1-p(或用0s和0s替换0s)。换句话说,对于熵而言,如果您使用大多数零或大部分的信息传输信息,那是无关紧要的。对于自然文本之类的事物是不正确的。

熵率(就输出字节而不是人类可读字符而不是人类可读字符),但是(对于许多发电机小于256的发电机)是一个很好的近似值,说这是的熵(5位5位以选择序列加6的长度)除以<<strong>平均长度(65/2)的平均长度,或每个字节可能的8个位置为0.338位。(这大大低于平常的英语文本。)您可以通过定义更多序列降低从每个级别绘制的子序列的典型长度来提高熵率。(如果子序列通常只是一个字符,或数百个序列编号,则一定会将熵率降低到此估计值以下,并将其限制为每个字节8位。)

另一个易于调节的序列类涉及绘制 bytes来自[0, n ]的概率 p p &lt; 1/(<em(><em)> n 1),对于0,其他可能同样可能。这给出了熵率 h =(1- p )ln( n /(1- p )) - p ln p ,位于[ln n ,ln( n 1)上),所以可以通过选择 n 然后适当地选择 n 来选择任何所需的费率。(如果您想要熵的,请记住使用LG而不是LN。)