我开始使用具有N个状态的FSM(即状态图图上的N个顶点)。 其中一个状态是“开始”状态,一个状态是“结束”状态。
我想做的是 -
实现这一目标的最佳算法是什么? 此外,是否有任何Python模块可以用最少的工作量进行验证(比如只需一个函数调用)?
答案 0 :(得分:1)
您可以从开始状态使用任何遍历(DFS / BFS / ...)并将访问状态标记为可达。对于可达性问题,只需反转边缘并从结束开始。
答案 1 :(得分:1)
我发现这个Python模块Networkx对我有很大的帮助 This(networkx.shortest_path)具体是我使用的函数。
粘贴在对我有用的解决方案之下。
import networkx as nx
G = nx.DiGraph()
G.add_nodes_from(["Start", "a", "b", "c", "End"])
G.add_edges_from([("Start", "a"), ("Start", "c"), ("a", "b"), ("b", "a"), ("c", "End")])
total_num_nodes = G.number_of_nodes()
if len(nx.shortest_path(G, source="Start")) < total_num_nodes:
print "\nThis FSM has inaccessible states"
else:
print "\nAll nodes reachable from 'Start'"
H = G.reverse()
if len(nx.shortest_path(H, source="End")) < total_num_nodes:
print "\nThis FSM has dead-end states"
else:
print "\nAll nodes have a path to reach the 'End' state"
答案 2 :(得分:0)
如果您正在寻找一个简单的解决方案,您可以使用transitive closure计算FSM的转换函数的Floyd-Warshall algorithm。这将为您提供一个NxN
数组,告诉您任何两个州P
和Q
是否可以Q
访问P
。它需要O(N3)
,如果N
不是太大,这应该没问题。
该算法可以用五行精确编写。此处trans
是一个列表列表,如果从trans[s][t]
直接转换为True
,则s
为t
,否则为False
。 (s
和t
预计为整数)。它修改了这个数组;返回时,如果有trans[s][t]
到True
的路径,则s
为t
:
def warshall(trans):
for k in range(len(trans)):
for i in range(len(trans)):
for j in range(len(trans)):
trans[i][j] = trans[i][j] or trans[i][k] and trans[k][j]
(最后一行可能是用|=
写的,但我认为不太清楚。)
该算法还可用于计算所有最短路径&#34;数组,它通常被引用作为这个问题的解决方案。为此,我们从转换数组开始,其中trans[i][j]
是从i
转换为j
(infinity
,如果没有直接转换)的成本,并替换最后一行:
trans[i][j] = min(trans[i][j], trans[i][k] + trans[k][j])
对于FSM,您通常会将所有费用设置为1
或infinity
,然后您最终会得到s
的最短路径长度任何t
和s
的{{1}}。{/ p>
您将在整个互联网上(以及关于算法和图论的标准教科书)找到算法的正式证明,所以我只是做大纲:
为了简化输入,我将假装节点由t
范围内的整数表示。如果每个0…N-1
小于s→p0→…→pi→t
,我们会调用路径<k
和p0…pi
- 路径。因此,从k
到<0
的唯一可能s
- 路径是简单路径t
(如果它存在于图表中),以及从s→t
到s
的每条路径t
是<N
- 路径。
现在,如果有一个<k+1
- 从s
到t
的路径,则会有<k
- 从s
到{{}的路径1}},或者t
- 从<k
到s
的路径和另一个k
- 从<k
到k
的路径。 (这只是另一种说法,即每个非奇异路径都有一个最大内部节点,并且可以在该节点划分为两个最大值较小的路径。)
Warshall算法的每次迭代都以t
- 路径的转换数组开始,以<k
- 路径的转换数组结束,方法是通过节点{{1}添加所有路径组合}。所以最后,我们有<k+1
- 路径的数组,正如我们之前观察到的那样,它包含了所有可能的路径。