种子洗牌可以逆转吗?

时间:2014-06-17 11:04:28

标签: php arrays shuffle

采取这个函数,这是种子Fisher-Yates shuffle(顺序是随机的,但是在同一种子的情况下可重现):

function seeded_shuffle(array &$items, $seed = false) {
    $items = array_values($items);
    mt_srand($seed ? $seed : time());
    for ($i = count($items) - 1; $i > 0; $i--) {
        $j = mt_rand(0, $i);
        list($items[$i], $items[$j]) = array($items[$j], $items[$i]);
    }
}

这个算法可以逆转吗?即,给定种子值和混洗数组,数组可以“未洗脑”到其原始顺序吗?如果是这样,怎么样?

(问题出现了in the comments here。)

1 个答案:

答案 0 :(得分:7)

原来答案是肯定的,非常简单:

function seeded_unshuffle(array &$items, $seed) {
    $items = array_values($items);

    mt_srand($seed);
    $indices = [];
    for ($i = count($items) - 1; $i > 0; $i--) {
        $indices[$i] = mt_rand(0, $i);
    }

    foreach (array_reverse($indices, true) as $i => $j) {
        list($items[$i], $items[$j]) = [$items[$j], $items[$i]];
    }
}

使用已知种子生成相同的随机数序列,然后反向遍历。