DFS期间重新访问节点并控制无限循环
我通过以下方式在加权有向图上实现 DFS:
public class DFSonWeightedDirectedGraph {
private static final String START = "A";
private static final String END = "C";
private int pathLength = 0;
private int stops = 0;
public static void main(String[] args) {
//this is a directed weighted graph
WeightedDirectedGraph graph = new WeightedDirectedGraph();
graph.addEdge("A", "B", 5);
graph.addEdge("A", "D", 5);
graph.addEdge("A", "E", 7);
graph.addEdge("B", "C", 4);
graph.addEdge("C", "D", 8);
graph.addEdge("C", "E", 2);
graph.addEdge("D", "C", 8);
graph.addEdge("D", "E", 6);
graph.addEdge("E", "B", 3);
LinkedList<String> visited = new LinkedList<String>();
visited.add(START);
new DFSonWeightedDirectedGraph().depthFirst(graph, visited);
}
private void depthFirst(WeightedDirectedGraph graph, LinkedList<String> visited) {
Collection<Map.Entry<String, Integer>> nodes = graph.adjacentNodes(visited.getLast());
// examine adjacent nodes
for (Map.Entry<String, Integer> node : nodes) {
if (visited.contains(node.getKey())) {
continue;
}
if (node.getKey().equals(END)) {
visited.addLast(node.getKey());
pathLength += node.getValue();
stops += 1;
printPath(visited);
visited.removeLast();
pathLength -= node.getValue();
stops -= 1;
break;
}
}
// recursion
for (Map.Entry<String, Integer> node : nodes) {
if (visited.contains(node.getKey()) || node.getKey().equals(END)) {
continue;
}
visited.addLast(node.getKey());
pathLength += node.getValue();
stops += 1;
depthFirst(graph, visited);
visited.removeLast();
pathLength -= node.getValue();
stops -= 1;
}
}
private void printPath(LinkedList<String> visited) {
for (String node : visited) {
System.out.print(node);
System.out.print(" ");
}
System.out.println("[path length: "+pathLength +
" stops made: "+ stops+"]");
}
}
我需要修改上述内容以允许在搜索源节点和目标节点之间的所有路径期间出现循环。为了避免无限循环,可以根据“停止”次数或从源出发的最大允许距离设置条件来终止搜索。
例如,通过这种方式,我可以找到从 A 开始到 D 结束且恰好经过 5 站的行程数量: 一种解决方案可以是 ABCDCD。或者,我可以找到从 D 到 D 的距离小于 40 的不同路线的数量:一些解决方案是 DECD、DEBCD、DCDCD。
我的问题是,我不确定如何创建保持主算法搜索的逻辑,同时避免保证不会到达目标节点的无限搜索循环。
假设我想从 A 旅行到 D。一个可能的死循环可以是 ABCEBCEBCEB....(到无穷大)。我的基于停靠次数或总行驶距离的条件可以终止此循环,但也会结束整个搜索,否则可以找到正确的路径,例如 ABCDCCDCD,当满足任一预设条件时,该搜索将正确终止。
感谢您的任何想法。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我认为您需要动态设置截止点/距离。例如,对于“A 到 D 正好 5 次停止”的问题,将截止值设置为 5 次停止将在达到 6 次停止时终止所有循环。如果将截止距离设置为 40,这同样适用于问题“D 到 D 的距离小于 40”。
可以使用“可达性矩阵”(即满足 a(如果存在从 i 到 j 的路径,则 i, j) = 1,否则 a(i, j) = 0。您可以通过首先查找图形的强连接组件来构建这样的矩阵(使用类似这个)。
然后,如果无法从当前节点访问目标节点,即 a(current, target) = 0,则可以拒绝搜索循环。
I think you need to set your cutoff stops/distance dynamically. For example, for a problem "A to D in exactly 5 stops", setting a cutoff value of 5 stops will terminate all cycles when they reach 6 stops. The same holds for the problem "D to D with a distance of less than 40", if you set a cutoff distance of 40.
Some cycles can be cut off earlier, using an "accessibility matrix", i.e. a matrix such that a(i, j) = 1 if there is a path from i to j or a(i, j) = 0 otherwise. You can construct such a matrix by first finding the strongly connected components of your graph (using an algorithm like this).
Then you can reject a search cycle, if the target node is not accessible from the current node, i.e. a(current, target) = 0.