我目前正在尝试在从源到接收器的图表中找到单个路径。我正在尝试使用dfs实现一个方法来实现这一点。但是,我似乎无法弄清楚如何使方法停止递归。例如,我有这个图(矩阵形式)
0 1 1 0
0 0 0 1
0 0 0 1
0 0 0 0
所以我有一个从节点0(源)到节点1和2的边缘,然后从1到2的边缘到3(接收器)。我想要的路径是0> 1> 3,而是我得到0> 1> 3> 2> 3。一旦找到了接收器的路径,我怎样才能使递归停止?
以下是该方法的代码:
public void dfsPath(int i) {
boolean[] visited = new boolean[this.edgeCapacities.length];
visited[i] = true;
this.path.add(i); //Integer ArrayList containing the nodes in the path
//loop through all of the nodes in the matrix to find adjacency
for (int j = 0; j < this.edgeCapacities.length; j++) {
//check if edge exists and node has not been visited
if (this.edgeCapacities[i][j] != 0 && !visited[j]) {
//here is the problem, i want the recursion to stop once the sink is found
//it does not work however.
if(j == this.sink) {
visited[j] = true;
this.path.add(j);
return;
} else {
//recursion
dfsPath(j);
}
}
}
非常感谢任何帮助。提前谢谢。
答案 0 :(得分:1)
您的DFS算法似乎存在一些问题:
visited
列表,它始终只包含当前节点this.path
添加节点,但从未删除未达到目标的节点要解决此问题,您应该在方法结束时从this.path
删除当前节点,即如果没有找到路径。此外,您可以删除visited
数组,只检查下一个节点是否已在路径中。这不是那么快,但应该足以满足您的需求,并使代码不那么复杂。此外,该方法应返回true
或false
,具体取决于是否找到路径。
尝试此操作(未经过测试,但应该工作)。
public boolean dfsPath(int i) {
this.path.add(i); // add current node to path
if (i == this.sink) {
return true; // if current node is sink, return true
// this.path contains nodes from source to sink
}
for (int j = 0; j < this.edgeCapacities.length; j++) {
if (this.edgeCapacities[i][j] != 0 && ! this.path.contains(j)) {
if (dfsPath(j)) {
return true; // found a path -> search no further
}
}
}
this.path.remove(this.path.size() - 1); // pop last node
return false; // no path found
}
请注意,我还移动了sink
- 检查了循环。这纯粹是一种品味问题,但它使代码更简单,因为您不必将sink
节点分别添加到路径中。