2014-06-17 55 views
4

拿这个功能,这是一个种子费雪耶茨洗牌(顺序是随机的,但可重复给予相同的种子):种子洗牌可以颠倒吗?

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)。

回答

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

使用已知的种子就产生相同的随机数序列,并遍历它相反。

+0

干得好!非常感谢! :-) – nils