【问题标题】:Number of simple mutations to change one string to another?将一个字符串更改为另一个字符串的简单突变数?
【发布时间】:2011-02-19 07:59:45
【问题描述】:

相信大家都听说过“文字游戏”,您可以尝试通过一次更改一个字母来将一个单词更改为另一个单词,并且只通过有效的英文单词。我正在尝试实现 A* 算法来解决它(只是为了充实我对 A* 的理解),其中需要的一件事是最小距离启发式。

也就是说,这三个突变中的一个可以将任意字符串 a 变成另一个字符串 b 的最小数目: 1) 将一个字母换成另一个字母 2)在任何字母之前或之后添加一个字母 3) 删除任何字母

例子

aabca => abaca:
aabca
abca
abaca
= 2

abcdebf => bgabf:
abcdebf
bcdebf
bcdbf
bgdbf
bgabf
= 4

我尝试了很多算法;我似乎无法找到一个每次都能给出实际答案的人。事实上,有时我甚至不确定我的人类推理是否能找到最佳答案。

有没有人知道任何用于此目的的算法?或者可以帮我找一个吗?

(澄清一下,我要求一种算法,可以将任意字符串转换为任何其他字符串,而不管它们的英语有效性。)

【问题讨论】:

  • 如果您实际上并不关心中间步骤是实际的英文单词,您似乎没有根据您在下面留下的评论来判断,您应该在您的问题中提及这一点,因为您重新描述原始文字游戏似乎表明您很在意。
  • 对不起;当我说“任意字符串”时,我以为我正在改变我的问题的术语,然后给出了不是单词的字符串示例。但我认为上下文有点误导,所以我会更清楚地说明。谢谢=)
  • 问题的第一段完全是误导!这必须是个骗子。

标签: algorithm string heuristics path-finding


【解决方案1】:

你想要minimum edit distance (or Levenshtein distance):

两个字符串之间的 Levenshtein 距离定义为将一个字符串转换为另一个字符串所需的最小编辑次数,允许的编辑操作是插入、删除或替换单个字符。它以 Vladimir Levenshtein 的名字命名,他在 1965 年考虑到了这个距离。

确定编辑顺序的一种算法在同一页面上here

【讨论】:

  • 这可能不适用,因为他使用的是纯英文单词。
  • 其实,这正是我要找的;我正在寻找一种不会打扰字典的最短距离启发式算法。谢谢=)
  • 请记住,如果您试图通过有效词找到最短路径,则列文斯坦距离仅提供下限。莱文斯坦距离最短的选项实际上可能比距离较远的选项离目的地更远。
  • 我正在尝试实现一个 A* 寻路算法来找到最短路径;该实现需要一个下限启发式来帮助计算。
【解决方案2】:

S. Dasgupta、C. H. Papadimitriou 和 U. V. Vazirani 编写的算法教科书第 6.3 节是关于“编辑距离”的一个极好的参考资料,其草稿可免费获得 here

【讨论】:

  • 感谢教科书的链接;它会派上用场 =)
【解决方案3】:

如果您有一个合理大小(小)的字典,那么广度优先树搜索可能会起作用。

所以从你的单词可以变异成的所有单词开始,然后所有可以变异成的单词(除了原来的),然后进入第三层……直到找到你要找的单词。

您可以消除发散词(离目标较远的词),但这样做可能会导致您在必须通过某些发散状态才能到达最短路径的情况下失败。

【讨论】:

  • 好吧,我已经实现了我的搜索算法 (A*),它很好地解释了不同的单词(就像它可以通过先离开山然后找到绕山的最佳路径一样)四处走动,而不是总是选择最近的点);它有一个简洁的优先系统,但所有这些都依赖于可靠的最小距离启发式;在寻路中,这是一条直线,忽略所有障碍。这将是语言等价物。
  • 那么,除了尝试每条路径并找到最短路径之外,我不知道任何方法。给定这两个词并迈出第一步(包括您的算法),您预计需要检查多少个词来分支第一个词?如果它只有 10 个左右,您可能只需对整个树进行广度优先搜索。如果它更多,您可能必须先进行深度优先,直到达到 3 左右的深度,然后再对该节点进行广度优先,以保持在内存限制内。对于国际象棋程序,我认为它们可以做到这一点,但擅长扔掉不好的路径。
猜你喜欢
  • 2023-04-05
  • 1970-01-01
  • 1970-01-01
  • 2015-02-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-10
相关资源
最近更新 更多