我有一张有向图。我想找到从源到目的地的所有可能路径,涵盖所有转换。这不同于"所有可能的路径覆盖所有顶点"。该图将具有恰好一个起始顶点并且可以具有多个末端顶点。如果节点没有传出转换,则节点是端节点。集合中的路径可能具有重复的过渡但不能具有重复的顶点。附有示例有向图。顶点 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也没关系。我需要在基于模型的测试工具中应用该解决方案来生成测试用例。非常感谢你。
答案 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>