我怎样才能确保当我改变拼图时,我仍然会得到一个均匀的排列?

时间:2010-04-16 14:31:03

标签: puzzle permutation shuffle

我有兴趣实现14-15 puzzlealt text

我正在按递增的顺序创建一个值为0 - 15的数组:

S = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}

现在,我想要做的就是改变它们以创建一个新的拼图实例。但是,我知道如果我创建一个“奇怪的排列”而不是无法解决的电路板。

维基百科说我需要创建一个具有均匀排列的拼图。我相信这意味着我只需要确保我进行偶数交换?

我如何修改Fisher-Yates,以确保我最终得到一个均匀的排列?如果我对数组中的每个元素进行交换,这将是16个交换,我相信这将是一个偶数排列。但是,我是否需要关注自己交换?有没有其他方法可以确保我有一个有效的谜题?

4 个答案:

答案 0 :(得分:4)

你应该可以使用Fischer-Yates。

  • 使用Fischer-Yates生成随机排列。
  • 检查是否均匀。
  • 如果不是偶数,则交换排列的前两个元素。

考虑偶数置换P = x1 x2 .... xn。

Fischer yates以1 / n的概率生成P!

它生成x2 x1 ... xn,概率为1 / n!。

因此,上述过程产生排列P的概率是2 / n! = 1 /(n!/ 2)

n!/ 2是偶数排列的数量。

因此,上述过程以相同的概率产生偶数排列。

检查排列是否均匀:计算排列中inversions个数的奇偶校验。

答案 1 :(得分:1)

这是我在这里已经回答的问题:

“这个问题基本上归结为做一个小扭曲的标准混洗算法。

关键的观察是,为了解决15个难题,排列的奇偶性和空白平方的奇偶性必须相同。

首先使用标准算法为此目的创建随机排列。例如Knuth shuffle算法:Random Permutations

使用Knuth的shuffle(或Fisher-Yates shuffle)的优势在于它涉及交换数字,因此您可以轻松跟踪排列的奇偶校验。每次交换都保持奇偶校验(如果您交换1和3),或更改奇偶校验(如果您交换1和2)。

将空白方块放在与排列奇偶校验相同的奇偶校验上,然后就完成了。如果置换具有奇数奇偶校验,则将空白放置为奇数平方(1,3,5,......随机选择)。如果排列具有偶数奇偶校验,则将空白放在偶数平方上。“

此外,“实际上,大约每4个连续生成的排列将包含两个偶数和两个奇数排列,因此即使每次迭代成本也可以忽略不计。”

您还可以查看此网站:http://eusebeia.dyndns.org/epermute

答案 2 :(得分:0)

我不会真的尝试改变算法本身,无论如何这对于这个应用程序来说可能都没有意义。从我看到的有两种选择:

  1. 重新洗牌直到你得到一个均匀的排列。这可能会平均丢掉一半的排列(好吧,也许多一点),但额外的工作很可能是微不足道的。
  2. 使用游戏的动作自行洗牌。也就是说,只做几百个随机动作。既然你没有拿出所有的碎片并重新组装它们,你就无法生成一个无法解决的状态。

答案 3 :(得分:0)

Fisher-Yates取决于将任何元素与任何其他元素交换的能力。由于这违反了拼图的物理特性,我认为你不能在这里使用它。

天真的解决方案是做你手动做的事情,随机选择一个与空的相邻的瓷砖并与之交换。我不知道为了获得好的洗牌,你需要做多少次互换。