固定密度为 1s 的伪随机数生成器

Posted

技术标签:

【中文标题】固定密度为 1s 的伪随机数生成器【英文标题】:Pseudo Random Number generator with fixed density of 1s 【发布时间】:2011-01-04 20:52:35 【问题描述】:

我正在寻找生成伪随机数的方法 [可能具有低“随机性”] 或 具有固定汉明权重[固定密度为 1] 的伪随机比特序列。 我发现了一些关于使用具有我需要的汉明权重的种子的简单线性同余生成器的建议,但是没有给出为什么这是正确的理由[为什么汉明权重在线性同余变换下是不变的]

谁能解释这一点或给我另一种方式?

谢谢...

【问题讨论】:

另见***.com/questions/2075912/…。要求略有不同,但您可能会发现其中一些代码很有用。 【参考方案1】:

我还没有听说过使用 LCG 来生成固定的汉明权重(我在学校没有深入了解汉明码,所以我也不太惊讶 :)。

在任何情况下,生成一堆具有固定汉明权重的位都相当简单。这是一段 python 代码,它将返回一个具有特定权重的 n 位数字。这也应该很容易翻译成其他语言(除了 python 整数是任意大的事实)。

from random import randrange

def get_ham_and_bits(weight, nbits=32):
    "Get n-bits with a fixed hamming weight"
    if weight > nbits: 
        return 1 < nbits

    result = 0
    for i in xrange(weight):
        bit = 1 << randrange(nbits)

        # only flip bits that aren't already flipped. delete the loop to
        # make this return a random weight instead of a fixed weight
        while bit & result != 0: 
            bit = 1 << randrange(nbits)

        # An XOR might be a better idea here, especially if you remove the loop.
        result |= bit
    return result

【讨论】:

【参考方案2】:

编辑:python 让洗牌变得容易

from random import shuffle

def gen(ham, bits=32):
    # generate a list with the correct number of 1's
    x = [1]*ham+[0]*(bits-ham)
    shuffle(x)
    # convert back to a number
    return int(''.join(map(str,x)),2)

>> print('\n'.join(bin(gen(5,15)) for x in range(10)))
0b101100100001000
0b100110010010
0b100110110000000
0b10010101100
0b11101100000
0b100100001000110
0b10000010101001
0b110000011100000
0b100011100010
0b100000011100010

这是一种可能的方式(基本上,生成基本字符串的随机排列:

    生成一个随机因数 N 直到您的位深度。 将阶乘转换为排列索引列表

    将您的排列列表转换为位数组(以伪 python 说明):

    [x

【讨论】:

【参考方案3】:

使用伪随机数生成器 (PRNG),即使是具有低权重种子的简单生成器也绝对不是一个好的解决方案。 PRNG不保持种子的Hamming权重不变,PRNG的整个思想就是去除种子的信息。

如果您想将位设置为 n 中的 1,您的问题是 thesetwo 问题的变体。如果 k 远小于 n,则改组解决方案为 O(n)。我认为以下解决方案是 O(k)。

它基于this answer,在python中

from random import sample

def konesoutofn(k, n):
    output=0
    for d in sample(xrange(n), k):output+=(1<<d)
    return output

x=konesoutofn(4,32)
print(bin(x))

如果您希望将大约 k 位设置为 1,其中 k/n 是每个位为 1 的概率,那么您必须查看 Bernouilli 和几何分布。

【讨论】:

以上是关于固定密度为 1s 的伪随机数生成器的主要内容,如果未能解决你的问题,请参考以下文章

在Python中为概率密度函数生成随机数

randrandi和randn的区别?

是否有随机访问的伪随机数生成器之类的东西? (最好是开源的)

跨平台一致的伪随机数

函数rand,randn,randi

如何根据概率密度函数生成随机数