我知道这种类型的结构有模块,但我喜欢并且更愿意自己了解事情是如何运作的。 所以...我正在尝试从图形中扩展路径,例如:
g = dict(
s=['a','d','s'],
a=['s','d','b'],
d=['s','a','e'],
b=['a','e','c'],
e=['d','b','f'],
f=['e','g'],
c=['b'],
g=['f'])
到目前为止,我可以看到给定节点的邻居:
def vecinosDe(n = ''):
return g[n]
我希望每次调用一个给定一个参数的函数时,一个图形节点,返回一个与给定参数相连的其他节点的列表。
然后输入给定,创建的相同列表到同一个函数,以返回连接到给定列表图节点的节点,并连续返回到达'g'节点。
我也知道我需要检查连接到给定节点的节点是否有任何递归(循环)。
这是我到目前为止的代码:
def expandir(n = '', lista = []):
lista.append([n]) #or lista = lista + [n]?
for v in g[n]:
for i in range(len(lista)): #?
lista[i].append(v)
return lista
这就是发生的事情,我知道这不好,哈哈。
>>> expandir('s')
[['s', 'd', 'a', 's']]
>>> expandir('d')
[['S', 'D', 'A', 'S', 'S', 'A', 'E'], ['D', 'S', 'A', 'E']]
在第二个for循环中的代码的某些部分,我想我应该检查是否有一个节点等于我要扩展的节点,给定的节点。这就是我被卡住的地方 试试这个?
if n == v: #?
另外我认为这可能需要某种递归,对吧?但是我想要一些提示来继续拼图。 :P
我应该返回列表,列表列表吗?......怎么样? :S
有小费吗? :)
提前谢谢
答案 0 :(得分:4)
这是对@tangentstorm's answer的修改,避免使用生成器引发显式异常:
def pathiter(adjacent_vertexes, start, end, path=None):
if path is None: path = (start,)
for vertex in adjacent_vertexes[start]:
if vertex == end:
yield path + (vertex,)
elif vertex not in path:
for p in pathiter(adjacent_vertexes, vertex, end, path + (vertex,)):
yield p
示例:
end = 'g'
for v in g:
path = next(pathiter(g, v, end), None)
if path is not None:
print ' → '.join(path)
else:
print "no path between %s and %s" % (v, end)
a → s → d → e → f → g
c → b → a → s → d → e → f → g
b → a → s → d → e → f → g
e → f → g
d → s → a → b → e → f → g
g → f → g
f → g
s → a → d → e → f → g
您可以打印所有路径:
for v in graph:
print "%s ⇢ %s:" % (v, end)
path = None
for path in pathiter(graph, v, end):
print '\t'+' → '.join(path)
if path is None:
print "no path between %s and %s" % (v, end)
a ⇢ g:
a → s → d → e → f → g
a → d → e → f → g
a → b → e → f → g
c ⇢ g:
c → b → a → s → d → e → f → g
c → b → a → d → e → f → g
c → b → e → f → g
b ⇢ g:
b → a → s → d → e → f → g
b → a → d → e → f → g
b → e → f → g
e ⇢ g:
e → f → g
d ⇢ g:
d → s → a → b → e → f → g
d → a → b → e → f → g
d → e → f → g
g ⇢ g:
g → f → g
f ⇢ g:
f → g
s ⇢ g:
s → a → d → e → f → g
s → a → b → e → f → g
s → d → a → b → e → f → g
s → d → e → f → g
答案 1 :(得分:1)
这是我的看法:
graph = g # from your code
def findPath(graph, node, path=tuple(), end='g'):
for key in graph[node]:
next = path + (key,)
if key == end:
raise Exception("Found it! Path is: %s" % '.'.join(path))
elif key in path:
pass # avoid loops
else:
# print next # if you want to see what it's doing
findPath(graph, key, next, end)
else: # no break/raise at this level
if len(path) == 0: print "no path found."
findPath(graph, 's')
我认为你的主要问题[除了真正难以理解的变量名 :)]是你的路径(lista
)的默认参数为[] 。这很糟糕,因为default arguments are mutable
另外我认为这可能需要某种递归,对吧?但是我想要一些提示来继续拼图。 :P
是的,当你看到一棵树时,想想递归。 :)
答案 2 :(得分:1)
javascript中的一个非常好的示例可以在http://eloquentjavascript.net/chapter7.html中进行路径搜索。当然,它教你用javascript,逐步开发这个算法。这是一个很好的阅读,以了解它正在做什么。