识别产生相同结果的交换序列

时间:2011-10-10 12:39:50

标签: algorithm permutation

我有一个关联数组,我存储键值对,我可以在其上执行交换操作:

swap(a, b)    // a <-> b
  {
    temp = map.value(b);
    map.value(b) = map.value(a);
    map.value(a) = temp;
  }

现在,给定一系列交换,我想知道我执行的下一次交换是否会导致关联数组进入以前的状态:

e.g。序列:

1 <-> 2
2 <-> 1

1 <-> 2
2 <-> 3
3 <-> 1
2 <-> 3

两者都什么都不做。

我希望能够通过查看交换序列本身来检测这一点。我猜这种问题有数学公式,但我似乎无法弄明白。

我发现第一个例子一个循环而第二个一个循环,所以“在有向图中检测循环”可能是解决方案的一部分,但是我不确定这将如何适合我正在寻找的算法。

算法也适用于交错的无关互换,最简单的例子是:

1 <-> 2
100 <-> 200
2 <-> 1
200 <-> 100

1 个答案:

答案 0 :(得分:0)

这是permutations的应用(并不是图论的应用)。

由于这些是键值对,因此可能它们可能是稀疏的数字集,如上一个例子(1,2,100,200),甚至是字符串:

 Dancer <-> Vixen
 Prancer <-> Blitzen
 Comet <-> Donner
 Vixen <-> Rudolph
 Prancer <-> Dasher
 Comet <-> Cupid
 Vixen <-> Dasher
 Cupid <-> Donner
 Vixen <-> Blitzen
 Prancer <-> Dasher
 Dancer <-> Rudolph
 Prancer <-> Rudolph
 Comet <-> Cupid
 Prancer <-> Vixen

以及数字,我会做的是以下(至少有两种方法可以做到这一点):

  1. 扫描序列以获得交换密钥的列表L和映射ML,使得L [ML [k]] = k。在上面的例子中,L = [Dancer,Vixen,Prancer,Blitzen,Comet,Donner,Rudolph,Dasher,Cupid]和ML = {Dancer:0,Vixen:1,Prancer:2,Blitzen:3,Comet:4,唐纳:5,鲁道夫:6,Dasher:7,丘比特:8}
  2. 然后:

    一个。程序解决方案:

    2A。按顺序在ML地图上执行交换。 3A。为了检查排列是否完整地保留了映射,验证ML [L [i]] = i对于0和N-1之间的每个整数i,其中N = L的长度。

    B中。矩阵解决方案:

    将每个交换表示为置换矩阵,使用列表L和映射ML从交换密钥转换 - &gt;整数索引。例如,Dancer&lt; - &gt; Vixen交换元素0和1,它由置换矩阵表示:

     010000000
     100000000
     001000000
     000100000
     000010000
     000001000
     000000100
     000000010
     000000001
    

    )并乘以置换矩阵。然后检查最后是否有单位矩阵。


    “A”解决方案效率更高,但带有矩阵的“B”解决方案本质上更具数学性。