用某些熵生成随机数序列
Generate random number sequence with certain entropy
我需要生成数字的部分随机序列,以使整体序列具有一定的熵水平。
例如。如果我将生成的数据馈送到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
您可以稍微简化问题 - 让我们再次考虑一个参数案例,其中查找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 p
和1-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。)
- 为什么随机数生成器不在void函数中随机化数字,而在main函数中随机化
- 大量序列中核苷酸类型的快速计数
- 从给定种子生成相同的随机数序列C++
- 使用给定种子生成的随机数序列是否保证在标准版本中相同?
- 在C++中重新启动随机数序列
- 如果我们在不同的机器上将 c++11 mt19937 播种为相同,我们会得到相同的随机数序列吗?
- 用某些熵生成随机数序列
- 在random_device和seed_seq之间做出决定,为多个随机数序列生成种子
- C 与C#重置后生成相同的随机数序列
- 如何使用 std::rand 生成非重复的随机数序列
- 如何在多种类型的编译器和内核上生成相同的随机数序列<random>?
- C++中的序列随机数
- 获取C++序列中的随机数
- 骰子滚动程序在每次运行时生成相同的随机数序列
- 用相同的种子在不同的操作系统上实现相同的随机数序列
- 试图在每次迭代中产生一个唯一的随机数序列
- 生成不同的正态分布的随机数序列
- 伪随机数生成器为同一种子产生不同的序列
- C/ c++算法在不同平台上从相同的种子产生相同的伪随机数序列
- 如何生成不会产生超过 X 个连续元素的随机数序列