这是我早期问题的一个更具体,易于表达的形式。
从字典中获取具有共同字母长度的单词列表 如何重新排序此列表t以保持相邻单词之间共同的尽可能多的字母?
示例1:
AGNI, CIVA, DEVA, DEWA, KAMA, RAMA, SIVA, VAYU
reorders to:
AGNI, CIVA, SIVA, DEVA, DEWA, KAMA, RAMA, VAYU
示例2:
DEVI, KALI, SHRI, VACH
reorders to:
DEVI, SHRI, KALI, VACH
最简单的算法似乎是:选择任何东西,然后搜索最短距离?
但是,DEVI-> KALI(1普通)相当于DEVI-> SHRI(1普通)
选择第一个匹配将导致整个列表中较少的公共对(4对5)。
这似乎应该比完整的TSP更简单?
答案 0 :(得分:3)
你要做的是,在一个完整的加权图中计算最短的哈密顿路径,其中每个单词都是一个顶点,每个边的权重是这两个单词之间不同的字母数。 / p>
对于您的示例,图表的边缘加权如下:
DEVI KALI SHRI VACH DEVI X 3 3 4 KALI 3 X 3 3 SHRI 3 3 X 4 VACH 4 3 4 X
然后,选择你最喜欢的TSP solving algorithm只是一个简单的事情,你很高兴。
答案 1 :(得分:1)
我的伪代码:
这个问题可能是NP完成的,这意味着随着字典的增长,算法的运行时将变得无法忍受。现在,我只看到一种方法来优化它:将图形切割成几个较小的图形,在每个图形上运行代码然后加入列表。结果不会像你尝试每个排列时那样完美,但运行时会好得多,最终结果可能“足够好”。
[编辑]由于此算法没有尝试所有可能的组合,因此很可能错过完美的结果。甚至有可能陷入局部最大限度。比如说,你有一对值为7但如果你选择了这对,所有其他值都会降到1;如果你不接受这一对,大多数其他值将是2,从而给出更好的总体最终结果。
该算法以完美的速度进行交易。当尝试每种可能的组合需要数年时间,即使使用世界上最快的计算机,您也必须找到一些方法来限制运行时。
如果字典很小,您只需创建每个排列,然后选择最佳结果。如果他们超过某个界限,你就注定了。
另一个解决方案是混合两者。使用贪婪算法找到可能相当不错的“孤岛”,然后使用“完整搜索”对小岛进行排序。
答案 2 :(得分:0)
这可以通过递归方法完成。伪代码:
Start with one of the words, call it w
FindNext(w, l) // l = list of words without w
Get a list l of the words near to w
If only one word in list
Return that word
Else
For every word w' in l do FindNext(w', l') //l' = l without w'
您可以添加一些分数来计算公共对,并选择“更好”的列表。
答案 3 :(得分:0)
您可能需要查看BK-Trees,这样可以有效地找到彼此给定距离的单词。不是一个完整的解决方案,但可能是一个组件。
答案 4 :(得分:0)
此问题有一个名称:n-ary Gray代码。由于您使用的是英文字母,因此n = 26. Wikipedia article on Gray code描述了问题,并包含一些示例代码。