宽度优先搜索三个字母的单词,优化

时间:2011-02-25 14:58:47

标签: python graph breadth-first-search

我在Python中使用广度优先搜索算法来查找从三个字母单词到另一个单词的最短“路径”。我已经有了它的工作,但表现很糟糕,我怀疑我的单词生成功能。

基本上,对于我从队列中弹出的每个单词,我都会生成所有其他三个字母的单词,这些单词可以通过交换一个字母来形成。功能如下:

#Pseudo code
For each position (1-3)
    For each letter (a-z)
        create a new word by exchanging the letter at the position
        if this word is a valid word and is not used earlier
             add it to the return list

return the list

这通常需要大约0.03秒。 有更快的方法吗?

3 个答案:

答案 0 :(得分:4)

我假设您有一个有效单词列表,并且您实际上并不是在寻找单一路径(为什么要关注优化),而是考虑很多路径。使用networkX

可以非常轻松地完成此操作
from networkx import Graph
from networkx.algorithms.shortest_paths import shortest_path, all_pairs_shortest_path

from itertools import combinations

WORDS = {'cat', 'hat', 'sat', 'car', 'cad', 'had', 'pad', 'pat', 'can', 'man'}

def makeGraph(words):
    """ create a graph where nodes are words and two words are 
        connected iff they have one different letter """

    G = Graph()

    # all word combinations
    for a,b in combinations(WORDS,2):
        # number of different letters
        diff = sum(1 for x,y in zip(a,b) if x!=y)
        if diff == 1:
            G.add_edge(a,b)
    return G

g = makeGraph(WORDS)
# path between two words
print shortest_path(g, 'cat', 'pad')

# generating all shortest paths is way more efficient if you want many paths
paths = all_pairs_shortest_path(g)
print paths['cat']['pad']

感谢@Ducan的示例单词。

如果你真的想自己实现这些算法,你可以在wikipedia找到大量的描述。经典的单源最短路径算法为Dijkstra's,经典的所有对最短路径算法为Floyd-Warshall

答案 1 :(得分:2)

如果你想重新发明轮子,也许这会有所帮助(N.B.这已经设置了文字所以至少需要Python 2.7):

from collections import defaultdict

WORDS = {'cat', 'hat', 'sat', 'car', 'cad', 'had', 'pad', 'pat', 'can', 'man'}

D1 = defaultdict(set)
D2 = defaultdict(set)
D3 = defaultdict(set)

for w in WORDS:
    D1[w[:2]].add(w)
    D2[w[0]+w[2]].add(w)
    D3[w[1:]].add(w)

def follows(w):
    followers = set(D1.get(w[:2]).union(D2.get(w[0]+w[2]), D3.get(w[1:])))
    followers.discard(w)
    return followers

for w in WORDS:
    print(w, follows(w))

答案 2 :(得分:0)

不要以次优的方式重新发明轮子:使用现有的模块:

http://pypi.python.org/pypi/altgraph/0.8