验证FSM中每个状态从“开始”状态到“结束”状态的可达性

时间:2014-06-30 08:47:01

标签: python algorithm graph graph-theory graph-algorithm

我开始使用具有N个状态的FSM(即状态图图上的N个顶点)。 其中一个状态是“开始”状态,一个状态是“结束”状态。

我想做的是 -

  1. 检查是否可以从“开始”状态到达其他每个N-2状态
  2. 检查是否可以从每个N-2状态到达'结束'状态
  3. 实现这一目标的最佳算法是什么? 此外,是否有任何Python模块可以用最少的工作量进行验证(比如只需一个函数调用)?

3 个答案:

答案 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数组,告诉您任何两个州PQ是否可以Q访问P。它需要O(N3),如果N不是太大,这应该没问题。

该算法可以用五行精确编写。此处trans是一个列表列表,如果从trans[s][t]直接转换为True,则st,否则为False 。 (st预计为整数)。它修改了这个数组;返回时,如果有trans[s][t]True的路径,则st

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转换为jinfinity,如果没有直接转换)的成本,并替换最后一行:

        trans[i][j] = min(trans[i][j], trans[i][k] + trans[k][j])

对于FSM,您通常会将所有费用设置为1infinity,然后您最终会得到s的最短路径长度任何ts的{​​{1}}。{/ p>

您将在整个互联网上(以及关于算法和图论的标准教科书)找到算法的正式证明,所以我只是做大纲:

为了简化输入,我将假装节点由t范围内的整数表示。如果每个0…N-1小于s→p0→…→pi→t,我们会调用路径<kp0…pi - 路径。因此,从k<0的唯一可能s - 路径是简单路径t(如果它存在于图表中),以及从s→ts的每条路径t<N - 路径。

现在,如果有一个<k+1 - 从st的路径,则会有<k - 从s到{{}的路径1}},或者t - 从<ks的路径和另一个k - 从<kk的路径。 (这只是另一种说法,即每个非奇异路径都有一个最大内部节点,并且可以在该节点划分为两个最大值较小的路径。)

Warshall算法的每次迭代都以t - 路径的转换数组开始,以<k - 路径的转换数组结束,方法是通过节点{{1}添加所有路径组合}。所以最后,我们有<k+1 - 路径的数组,正如我们之前观察到的那样,它包含了所有可能的路径。