【发布时间】:2013-10-29 12:28:43
【问题描述】:
所以,
问题
pseudo-random numbers 众所周知。 “伪”实际上意味着,尽管它们通常是随机的(即不可预测的),但它们的顺序仍然是相同的,其中使用了相同的生成器初始化值。例如,在 PHP 中有 mt_srand() 函数可以做到这一点。示例:
mt_srand(1);
var_dump(mt_rand(), mt_rand(), mt_rand());
-不管我们启动脚本多少次:生成的三个数字的顺序总是相同的。
现在,我的问题是如何做同样的事情 - 但要对数组进行洗牌。 IE。我想创建一个函数,它将接受输入数组来随机播放和种子。在相同的种子值内,洗牌必须具有连续的相同顺序。 IE。让我们调用该函数shuffleWithSeed() - 然后以下应该适用于每个脚本启动:
$input = ['foo', 'bar', 'baz'];
$test = shuffleWithSeed($input, 1000);//1000 is just some constant value
var_dump($test); //let it be ['bar', 'foo', 'baz']
$test = shuffleWithSeed($test, 1000);
var_dump($test); //let it be ['baz', 'foo', 'bar']
$test = shuffleWithSeed($test, 1000);
var_dump($test); //let it be ['baz', 'bar', 'foo']
//...
-即无论我们为数组洗牌多少次——我希望下一个脚本启动的排序顺序在一个seed 值内总是相同的。
我的方法
我想到了这个算法:
- 用传递的
seed初始化随机数生成器 - 生成
N随机数,其中N是$input成员的数量 - 对第 2 步中的数字进行排序
- 使对应的数字依赖于
$input键。
我已经实现了:
function shuffleWithSeed(array $input, $seed=null)
{
if(!isset($seed))
{
shuffle($input);
return $input;
}
if(!is_int($seed))
{
throw new InvalidArgumentException('Invalid seed value');
}
mt_srand($seed);
$random = [];
foreach($input as $key=>$value)
{
$random[$key] = mt_rand();
}
asort($random);
$random = array_combine(array_keys($random), array_values($input));
ksort($random);
return $random;
}
-现在,还发现了Fisher-Yates 算法-但不确定它是否可以使用伪随机数(即使用种子)
问题
如您所见,我在函数中进行了两种排序——第一种是按值,第二种是按键。
- 这可以用一种方式完成吗?还是根本没有排序?输入数组可能很大,所以我想避免这种情况。
- 但是,可能是我的算法不好?如果是,还有哪些其他选项可以建议?
【问题讨论】:
标签: php arrays algorithm random