我想找到一种有效的方法来检查通过图表进行的给定“步行”是否有效。
这样的函数应该接受一个Graph(节点,边)和一串节点名,如果可以根据图形按给定的顺序访问节点,则输出True,否则输出false。
最好使用NetworkX库,因为我已经使用它来存储和表示图形了。
类似以下内容:
""" G:
Q1 -> Q1
Q1 -> Q2
Q2 -> Q2
"""
accepts(G, ["Q1", "Q1", "Q2"])
>> True
accepts(G, ["Q2", "Q2", "Q2"])
>> True
accepts(G, ["Q2", "Q2", "Q1"])
>> False
accepts(G, ["Q1", "Q2", "Q1"])
>> False
accepts(G, ["Q1", "Q1", "Q2", "Q1"])
>> False
这将用于自动机类。基本检查给定图形表示的语言的字符串的成员资格。
答案 0 :(得分:2)
您只需要检查路径的所有边缘是否有效。
def accepts(g, path):
return all([(path[i],path[i+1]) in g.edges() for i in range(len(path)-1)])
示例:
g=nx.DiGraph()
g.add_edge("Q1","Q1")
g.add_edge("Q1","Q2")
g.add_edge("Q2","Q2")
print(accepts(g, ["Q1", "Q1", "Q2"]))
print(accepts(g, ["Q2", "Q2", "Q2"]))
print(accepts(g, ["Q2", "Q2", "Q1"]))
print(accepts(g, ["Q1", "Q2", "Q1"]))
print(accepts(g, ["Q1", "Q1", "Q2", "Q1"]))
答案 1 :(得分:1)
@newbie的观点是“您只需要检查路径的所有边缘是否有效”,这是正确的,但是他给出的实现远非高效。 graph.edges()
会从头开始为路径中的每个边缘重新生成所有图形边缘的列表。您应该始终使用(u, v) in g.edges()
而不是g.has_edge(u, v)
,这是一个恒定时间的操作。尽管目前您似乎正在使用DiGraph
,但后一种方法还具有同时为Graph
和DiGraph
工作的优点,而较早的方法仅适用于{{ 1}}。 (这是因为DiGraph
的{{1}}方法仅返回一个(随机)方向上的边缘,因此仅检查一个方向上的边缘是不够的; Graph
会正确执行edges()
和g.has_edge()
都在这里出现
长话短说,使用:
Graph
或者,更简洁一些:
DiGraph