确实,算法 is¹ 的wikipedia's description 是错误的。帕尔默自己的描述是
-
第 0 步。将顶点排列成一个圆圈。
-
第 1 步。查看边界,例如逆时针方向,寻找连续的不相邻顶点,即间隙。如果没有间隙,则以边界上的跨越循环退出。否则,从间隙的顶点到可能相邻或不相邻的另一对连续顶点(可能的间隙 2)寻找一对交叉弦。
如果找到,(即间隙 1 很好!),只需以明显的方式重新排列顶点的圆形顺序,使两个弦成为边界上的边,并将间隙切换到内部。每次我们成功地玩这种纵横交错的游戏时,顶点圆形排列的边界上的一两个间隙都会被两条边代替。否则,对下一个间隙重复第 1 步。
继续直到跨越循环在边界上,或者直到每个间隙都坏了。
你需要一对交叉和弦,即你需要边
v_i <-> v_j
v_{i+1} <-> v_{j+1}
这样,通过将部分从v_{i+1} 反转为v_j(包括),您可以移动顶点v_j - 在图中与v_i 相邻 - 在您的循环中靠近v_i,并且顶点v_{i+1} - 在图中与v_{j+1} 相邻 - 在循环中移动到v_{j+1} 旁边。因此,我们在图中获得了两个新的循环邻居对,(v_i, v_j) 和 (v_{i+1}, v_{j+1}),并可能破坏 一个 在图中相邻的循环邻居对,@ 987654333@。图中相邻的循环邻居对的数量每一步增加 1 或 2,因此算法终止。
由于维基百科的错误索引,将v_j 移动到v_i 旁边和v_{i+1} 到v_{j+1} 旁边不需要生成一对在图中相邻的新循环邻居,因此算法不需要终止。
那么让我们来看看你的例子
E = { (1,2), (1,3), (1,6), (3,2), (3,4), (5,2), (5,4), (6,4), (6,5) }
最初将其排列为1426351(没有相邻的邻居)。
图中第一对不相邻的循环邻居是(1,4) = (v_1,v_2)。扫描索引j > 2 使得v_j 与v_1 和v_{j+1} 与v_2 相邻,第一个此类事件是j = 3。现在反转循环中的4...2部分(在这种情况下,4和2之间没有顶点),给出下一个循环
1234561 // index in cycle
1246351 // vertex
有两对相邻的邻居((1,2) 和 (4,6))。第一个索引i 与v_i 不相邻v_{i+1} 是2。扫描第一个j > 3 使得v_j 与v_2 = 2 相邻并且v_{j+1} 与v_3 = 4 相邻。这给了j = 5。现在v_3和v_5(含)之间的部分,给出下一个循环
1234561 // index in cycle
1236451 // vertex
再一次,v_3 = 3 不与v_4 = 6 相邻,所以i = 3,j = 5,反转收益率
1234561 // index in cycle
1234651 // vertex
现在唯一的坏对是(v_6,v_1) = (5,1)。最小的j > 1 使得v_j 与v_6 = 5 和v_{j+1} 与v_1 = 1 相邻是j = 2。现在将部分从v_1 反转为v_2 产生
1234561 // index in cycle
2134652 // vertex
这是一个哈密顿循环。
¹我会马上修复它。