我正在通过以下方式在加权有向图上实现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 ....(到无限远)。我基于停靠次数或总行进距离的条件可以终止此循环,但也将结束整个搜索,否则可能找到正确的ABCDCDCDCD路径,当满足任一预设条件时,该路径将正确终止。
感谢任何想法。
答案 0 :(得分:1)
我认为您需要动态设置截止停止/距离。例如,对于“正好5档中的A到D”的问题,设置5档的截止值将在它们达到6档时终止所有循环。如果将截止距离设置为40,则问题“D到D的距离小于40”也是如此。
使用“可访问性矩阵”可以更早地切断某些周期,即如果存在从i到j或a(i,j)= 0的路径,则a(i,j)= 1的矩阵。您可以通过首先找到图表中的强连接组件来构建此类矩阵(使用this之类的算法)。
如果目标节点无法从当前节点访问,即(当前,目标)= 0,则可以拒绝搜索周期。