【发布时间】:2009-11-06 04:07:38
【问题描述】:
我正在为我正在处理的 C++ 项目实现Knuth shuffle。我试图从我的洗牌中获得最公正的结果(而且我不是(伪)随机数生成方面的专家)。我只是想确保这是最公正的 shuffle 实现。
draw_t 是字节类型(typedef'd to unsigned char)。 items 是列表中的项目数。我在下面包含了random::get( draw_t max ) 的代码。
for( draw_t pull_index = (items - 1); pull_index > 1; pull_index-- )
{
draw_t push_index = random::get( pull_index );
draw_t push_item = this->_list[push_index];
draw_t pull_item = this->_list[pull_index];
this->_list[push_index] = pull_item;
this->_list[pull_index] = push_item;
}
我使用的随机函数已被修改以消除modulo bias。 RAND_MAX 分配给 random::_internal_max。
draw_t random::get( draw_t max )
{
if( random::_is_seeded == false )
{
random::seed( );
}
int rand_value = random::_internal_max;
int max_rand_value = random::_internal_max - ( max - ( random::_internal_max % max ) );
do
{
rand_value = ::rand( );
} while( rand_value >= max_rand_value );
return static_cast< draw_t >( rand_value % max );
}
【问题讨论】:
-
旁注:c++ STL 包含算法
random_shuffle。以防万一你不知道。 -
我不知道 STL 的实现。我还没有花时间学习 STL(我只是一个 Win32/.NET 人),我希望这个项目有一个最小的学习曲线(时间限制),但我会把它带入考虑。
-
你的随机数生成器可以有多少种不同的状态?如果小于52!那么就会有永远无法产生的洗牌(注意 2^32 甚至 2^64 比 52 小得多!)。您需要使用状态数多于 52 的 RNG!如果您想获得公正的结果:也许可以试试 Mersenne Twister。
-
C++ STL 也(现在)包含了非常棒的 RNG,用于此目的
标签: c++ algorithm shuffle random knuth