【问题标题】:generating a random dice roll using LFSR使用 LFSR 生成随机骰子
【发布时间】:2013-07-19 19:56:42
【问题描述】:

我的代码使用从互联网上下载的左反馈移位寄存器生成随机数:

#define POLY_MASK_32 0xB4BCD35C
#define POLY_MASK_31 0x7A5BC2E3

#include <iostream>

typedef unsigned int uint;

uint lfsr32, lfsr31;

int shift_lfsr(uint *lfsr,  uint polymonial_mask)
{
    int feedback;

    feedback = *lfsr & 1;
    *lfsr >>= 1;
    if (feedback == 1)
        *lfsr ^= polymonial_mask;
    return *lfsr;
}

void init_lfsrs(void)
{
    lfsr32 = 0xABCDE; //seed values
    lfsr31 = 0x23456789;
}

int get_random(void)
{
    /*this random number generator shifts the 32-bit LFSR twice before XORing
      it with the 31-bit LFSR. the bottom 16 bits are used for the random number*/
    shift_lfsr(&lfsr32, POLY_MASK_32);
    return(shift_lfsr(&lfsr32, POLY_MASK_32) ^ shift_lfsr(&lfsr31, POLY_MASK_31));
}

void main(void)
{
    int random_value[10];

    init_lfsrs();
    for(int i = 0; i < 10; i++)
    {
        random_value[i] = get_random();
        std::cout << random_value[i] << std::endl;
    }
}

我不完全理解这里发生了什么,但我知道它会以非重复序列产生一个 32 位数字。我认为它需要前 16 位作为显示的数字。

我想要做的是从中产生一个 1-6 之间的数字...任何人都可以帮忙吗?

编辑我还打算将 2 个种子值更改为 srand(time) rand() 数字,这样它就不会每次都以相同的方式开始。这是正确的,我该怎么做?

【问题讨论】:

  • 自 C++11 以来,C++ 在标准库中具有非常好的pseudo-random number generation 功能。检查uniform_int_distribution的示例代码。
  • 我被要求尽可能随机地实现一个随机数。本来打算使用random.org,但遇到了问题,不想连接互联网。这似乎是一个很好的解决方法......然后我被卡住了
  • 实际上,软件生成的所有“随机”数字都不是随机的。它们只是伪随机的。如果你真的想创建完全随机数,你必须使用硬件生成器。如果您需要软件,C rand() 函数或任何其他函数都是一个很好的解决方案。
  • 制作好的伪随机数生成器是困难。对于核心理论,我推荐The Art of Computer Programming的第3章。对于更简单的解决方案,我推荐xkcd.com/221... ;)
  • 至于使用rand为你的生成器做种子,当然种子越随机越好,但调试时也更难预测值。

标签: c++ random


【解决方案1】:

要产生一个介于 1 和 6 之间的随机数,请执行此操作

 int myRandomNumber = 1 + (random_value[i] % 6);

为什么会这样?

random_value[i] % 6

将产生一个介于 0 和 5 之间的值,因此我们将其加 1 以获得介于 1 和 6 之间的值。

阅读模数运算符

http://www.cprogramming.com/tutorial/modulus.html

一般来说,要在某个闭集 [a, b] 中产生一个随机数,你会这样做

int myRandomNumber = a + ( random_value[i] % (b - a + 1) )

【讨论】:

  • 这实际上是一种非常糟糕(有偏见)的随机数生成方式,除非 random_value 的最大值恰好可以被 6 整除。以下是解释原因:eternallyconfuzzled.com/arts/jsw_art_rand.aspx
  • 这只是非常轻微的偏见。对于大多数用途来说,这很好。 (对于 6 的情况,前 3 个值与 32 位整数的后 3 个值的比率为 715,827,883 与 715,827,882,或者仅比 5 高出 1400 亿分之一的可能性。)
  • 事实上,无论你如何分割从 0 .. 2^32-1 的范围,你都会有一些偏差,除非你简单地抛出一个范围从get_random() 返回值,因此您细分了 6 个完全相等的范围。
猜你喜欢
  • 2017-08-22
  • 2013-02-15
  • 1970-01-01
  • 1970-01-01
  • 2014-02-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多