查找从源到目标的所有可能路径的集合,覆盖所有边缘

时间:2016-05-28 04:09:29

标签: java graph graph-algorithm path-finding edges

我有一张有向图。我想找到从源到目的地的所有可能路径,涵盖所有转换。这不同于"所有可能的路径覆盖所有顶点"。该图将具有恰好一个起始顶点并且可以具有多个末端顶点。如果节点没有传出转换,则节点是端节点。集合中的路径可能具有重复的过渡但不能具有重复的顶点。附有示例有向图。顶点 a (黑色)是起始顶点和顶点 e f 是结束节点(黄色)。 该图的解决方案如下。

a-f
a-b-f
a-b-c-e
a-b-c-d-e
a-b-c-d-b-f

您可以看到最后一条路径有两次 b 。这是有效的。即,路径可以具有多于一次的相同顶点。相应的过渡是

t18
t1-t7
t1-t2-t3
t1-t2-t4-t5
t1-t2-t4-t6-t7

您可以看到没有路径有重复的过渡。我需要一个java程序来做到这一点。 我写了一个程序来解决这个问题。但它给了我所有没有重复顶点的路径。因此,虽然它涵盖了所有节点,但我缺少一些边缘。我写的代码如下:

private Stack<Vertex> path = new Stack<Vertex>(); // the current path
private Set<Vertex> onPath = new HashSet<Vertex>(); // the set of vertices
public void AllPaths(Vertex s) {
    enumerate2(s);
}

private void enumerate(Vertex v) {
    // add node v to current path from source
    path.push(v);
    onPath.add(v);
    if (v.getOutgoings().size() == 0) {
        printPath(path);
        addToRawPaths(path);
    }

    // consider all neighbors that would continue path with repeating a node
    else {
        EList<Transition> ts = v.getOutgoings();
        for (Transition w : ts) {
            if (!onPath.contains(w.getTarget())) { // !onPath.contains(w.getTarget())
                enumerate(w.getTarget());
            }
        }
    }

    // done exploring from v, so remove from path
    path.pop();
    onPath.remove(v);
}

使用它,我正在

a-f
a-b-f
a-b-c-e
a-b-c-d-e

但我需要像上面描述的那样。您可以假设我在此代码中使用的这些API,或者您可以实现新的。即使是psudocode也没关系。我需要在基于模型的测试工具中应用该解决方案来生成测试用例。非常感谢你。

enter image description here

1 个答案:

答案 0 :(得分:0)

目前,当您发现Vertex已包含onPath时,您将停止枚举。在你的情况下,这不应该是规则。相比之下,你应该停止枚举当前路径中存在的currentVertex v,nextCandidateVertex w.getTarget()。

要实现这一点,我会使用HashSet<VertexPair>连续顶点而不是HashSet<Vertex>。我猜您的Transition个对象与VertexPair对应;如果是这样,您可以直接使用HashSet<Transition>

实际上,您可以使用path堆栈实现相同的功能,但查找现有对可能需要使用建议的HashSet<VertexPair>方法O(n)VS摊销的O(1)。 / p>