按可预测的顺序随机播放项目 [已关闭]

Shuffle items in a predictable sequence [closed]

提问人:Blaine_ 提问时间:10/3/2018 最后编辑:Blaine_ 更新时间:10/4/2018 访问量:96

问:


想改进这个问题吗?通过编辑这篇文章来更新问题,使其仅关注一个问题。

5年前关闭。

我有 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);
}
PHP 排序随机 序列

评论

0赞 RiggsFolly 10/3/2018
您是否从数据库中获取这些 ID?我的意思是它们是来自表格行的 id 吗?
0赞 Blaine_ 10/3/2018
不,它们存储在文件中
2赞 Alex Kapustin 10/3/2018
你已经做了什么?
0赞 Mast 10/3/2018
所以,你想排序吗?不想排序?想随机化吗?函数名称充其量是可疑的。pseudoRandomSort
0赞 Blaine_ 10/4/2018
@AlexKapustin,我这样做了:在共享主机上随机化 0.02 个 ID 大约需要 10 000 秒,我想知道是否有更快、更优雅的方式public function pseudoRandomSort(&$ids, $var1) { $sorted = array(); foreach ($ids as $id) { $sorted[md5($id.$var1)] = $id; } ksort($sorted); $ids = array_values($sorted); }

答:

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]); }