确实,维基百科对算法的描述是¹错了。帕尔默自己的描述是
步骤 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})
,并且可能破坏了在图中相邻的一对循环邻居,(v_j, v_{j+1})
。图中相邻的循环邻居对的数量每一步增加 1 或 2,因此算法终止。
由于维基百科的错误索引,移动v_j
nextv_i
和v_{i+1}
nextv_{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
是。现在反转循环中的部分(在这种情况下,在 4 和 2 之间没有顶点),给出下一个循环v_j
v_1
v_{j+1}
v_2
j = 3
4...2
1234561 // index in cycle
1246351 // vertex
有两对相邻的邻居 ((1,2)
和(4,6)
)。不相邻的第一个索引是 2。扫描第一个与i
相邻和相邻的索引。这给了. 现在和(含)之间的部分,给出下一个循环v_i
v_{i+1}
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)
. 与和to相邻的最小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
这是一个哈密顿循环。
¹我会马上修复它。