提问人:Blaine_ 提问时间:10/3/2018 最后编辑:Blaine_ 更新时间:10/4/2018 访问量:96
按可预测的顺序随机播放项目 [已关闭]
Shuffle items in a predictable sequence [closed]
问:
我有 10 000 个 ID,这些 ID 最初是以标准的升序方式排序的。 我需要以特定方式洗牌这些 ID,以便以后可以复制生成的序列。
显然,如果我使用 rand() 或 mt_rand(),序列每次都不同,所以我需要某种方法,以可预测的结果洗牌项目。
这是我之前尝试过的:
public function pseudoRandomSort(&$ids, $var1)
{
$sorted = array();
foreach ($ids as $id) {
$sorted[md5($id.$var1)] = $id;
}
ksort($sorted);
$ids = array_values($sorted);
}
这种方法有效,但我正在寻找更优雅、更快捷的东西
UPD:感谢 @Andrew 提到$seed概念。 在此基础上,我制作了一种简单而快速的方法,以可预测的顺序对项目进行洗牌:
public function predictableShuffle(&$ids, $seed)
{
srand($seed);
shuffle($ids);
}
答:
2赞
Andrei
10/3/2018
#1
您正在寻找 Fisher-Yates 洗牌或至少是它的变体。
你必须根据种子来洗牌。因为存储种子比存储整个 X 数字序列要容易得多。
最简单的实现如下所示:
$items = [1, 2, 3, 4];
function shuffleSeed(&$items, $seed) {
$items = array_values($items);
mt_srand($seed);
$count = count($items);
for ($i = $count - 1; $i > 0; $i--) {
$j = mt_rand(0, $i);
list($items[$i], $items[$j]) = [$items[$j], $items[$i]];
}
}
shuffleSeed($items, 3);
var_dump($items);
既然你说性能在这里很重要,这可能不好用,你必须混合搭配。试一试,看看它的表现如何。
评论
0赞
Blaine_
10/4/2018
谢谢!使用这种方法在共享主机上随机化 10 000 个项目大约需要 0.01 秒。这个时机是可以接受的。它看起来更优雅,比我之前的临时解决方法快 2 倍左右。我只是稍微最小化了代码:mt_srand($seed); foreach (array_keys($items) as $i) { $j = mt_rand(0, $i); list($items[$i], $items[$j]) = array($items[$j], $items[$i]); }
评论
pseudoRandomSort
public function pseudoRandomSort(&$ids, $var1) { $sorted = array(); foreach ($ids as $id) { $sorted[md5($id.$var1)] = $id; } ksort($sorted); $ids = array_values($sorted); }