遍历图中所有边的算法

时间:2012-04-06 11:49:30

标签: python graph-theory traversal model-based-testing

作为个人复活节项目,我正在尝试在工作中实施一些基于模型的测试。我有一个在python中实现的图形,我需要遍历所有边缘/完成图形的所有转换,至少一次。遍历边缘两次或更多并不重要,但我需要在同一节点中开始和结束并获得一系列边缘/过渡。

更简单的算法>最短的序列。

我环顾四周,发现了很多算法,但我找不到一个适用于我的组合/组合。如果有人能指出我正确的方向或给我一些如何做到这一点的提示,那将是很棒的。

我的图表实现如下所示:

graph = {
    A : {'IDLE': 't8', 'B': 't2', 'C': 't4'},
    B : {'A': 't3', 'C': 't4', 'IDLE': 't6'},
    C : {'A': 't5', 'IDLE': 't7', 'B': 't2'},
    IDLE : {'A': 't1'}
}

graph

4 个答案:

答案 0 :(得分:4)

方法1

您可以将图形G更改为新图形G',其中G中的每条边都成为G'中的节点。如果“A - > t1 - > B>> t2 - > C”可以在G中为某些A,B和C设置从t1到t2的边缘。

然后你需要在G'中找到path cover

方法2

  • 您的位置P最初是某个节点P0(例如空闲)。
  • 对于每个边缘T(从A到B),找到从P到A的任何路线,然后使用T转到B.将P更新为B。
  • 最后找到从P回到P0的任何路线。

答案 1 :(得分:1)

此问题与旅行商问题不同。相反,它被称为中国邮递员问题。最大的区别是TSP想要访问CPP想要访问所有边缘(街道)的所有节点(城市)。

这里有一个完美的教程:https://www.datacamp.com/community/tutorials/networkx-python-graph-tutorial

答案 2 :(得分:0)

我不确定您是否需要算法,或者您想知道如何完成工作。 如果是后者,可以使用networkx

下载并安装networkx后,您可以尝试以下

>>> import networkx as nx
>>> DG=nx.DiGraph()
>>> def CycleFrom(G,node):
    return sorted((c for c in nx.simple_cycles(DG) if node in c), key=len)[0]

>>> for (stnode, edges) in graph.items():
    for (ennode,edge) in edges.items():
        DG.add_edge(stnode,ennode,name=edge)


>>> for node in DG.nodes():
    print "Cycles from {0} is {1}".format(node,CycleFrom(DG,node))


Cycles from A is ['A', 'IDLE', 'A']
Cycles from IDLE is ['A', 'IDLE', 'A']
Cycles from B is ['A', 'B', 'A']
Cycles from C is ['A', 'C', 'A']
>>> 

答案 3 :(得分:0)

对于每个P1,图中的P2点找到所有R道路,其中R看起来像这样:

R =(P1,Pf1,...,Pfn,P2)

对于从P1到P2的每条R1,R2道路,如果交叉口(R1,R2)有超过0个点(当然除了P1和P2),确定哪个更短。如果R1的长度小于R2的长度,则忘记R2,否则忘记R1。

在迭代中,您会发现从P1到P2的最短的完全独立的道路。如果你想要遍历道路,你有点(P1,...,Pk)如果我们选择Pi,其中1< = i< = k,我们知道第一点将是Pi和最后一点也将是Pi。

假设订单无关紧要。每当您遍历一个点时,将其标记为已遍历。如果某个点标记为已遍历,则您不希望再次返回给定点,但如果需要,您不会介意再次遍历该点。因此,计划的道路将是:Pf1,...,Pfk,Pf1。

每个Pfj,Pfm:

我们现在在Pfj。如果遍历Pfm,那么我们不想再次去Pfm,所以我们进入下一次迭代

如果没有经过Pfm,我们有从Pfj到Pfm的R1,...,Rq道路。选择具有最大未遍历点数和最小已经遍历道路数的道路。你需要通过一个聪明的想法来衡量道路中未被移动的点的重要性和一个被遍历的点(希望你的重量将最小化从Pf1到Pf1的道路总长度)。

请注意,Pf1不应标记为已遍历,因为您希望在算法结束时到达那里。