【问题标题】:Algorithm to traverse all edges in a graph遍历图中所有边的算法
【发布时间】:2012-04-06 11:49:29
【问题描述】:

作为一个个人复活节项目,我正在尝试在工作中实施一些基于模型的测试。我有一个用 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'}
}

【问题讨论】:

  • 您的图表看起来是有方向的。是否只允许沿着箭头移动?
  • 嗯,这就是旅行商问题,不是吗。如果您找到解决方案,请让全世界知道。
  • 我们可以假设您的图表是strongly connected吗?
  • @DanielRoseman:实际上是欧拉循环。 TSP 处理访问所有节点,而不是所有边。
  • @Avaris:实际上这不是欧拉循环,因为您可以多次访问边缘。 OP 要求每条边至少访问一次。

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


【解决方案1】:

方法 1

您可以将图 G 更改为新图 G',其中 G 中的每条边都成为 G' 中的节点。如果对于某些 A、B 和 C 在 G 中“A -> t1 -> B -> t2 -> C”是可能的,则在 G' 中创建从 t1 到 t2 的边。

那么你需要在G'中找到一个path cover

方法 2

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

【讨论】:

  • 谢谢,我会调查的。 G' 解决方案听起来很有趣。
【解决方案2】:

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

可以在这里找到一个完美的教程:https://www.datacamp.com/community/tutorials/networkx-python-graph-tutorial

【讨论】:

    【解决方案3】:

    对于图中的每个 P1、P2 点,找到所有 R 条道路,其中 R 如下所示:

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

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

    在一次迭代中,您会发现从 P1 到 P2 的最短的完全独立的道路。如果你想穿越一条道路,你有点 (P1, ..., Pk) 如果我们选择 Pi,其中 1

    假设顺序无关紧要。每当您遍历一个点时,将其标记为已遍历。如果一个点被标记为已遍历,您将不想再次前往给定点,但您不会介意在必要时再次遍历该点。因此,规划道路为:Pf1, ..., Pfk, Pf1。

    对于每个 Pfj,Pfm:

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

    如果不遍历 Pfm,我们有从 Pfj 到 Pfm 的 R1,...,Rq 路。选择未经过点数最多且已经过道路数最少的道路。您需要通过一个聪明的想法来衡量道路中未经过点和经过点的重要性(希望您的权重可以最小化从 Pf1 到 Pf1 的道路总长度)。

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

    【讨论】:

      【解决方案4】:

      我不确定您是想要算法还是想知道如何完成工作。 如果是后者,您可以使用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']
      >>> 
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-12-22
        • 1970-01-01
        相关资源
        最近更新 更多