gpt4 book ai didi

algorithm - 寻找两个任意顶点之间所有连接的图算法

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:11:29 28 4
gpt4 key购买 nike

我正在尝试确定最省时的算法来完成下面描述的任务。

我有一组记录。对于这组记录,我有连接数据,它指示这组记录对如何相互连接。这基本上表示一个无向图,记录是顶点,连接数据是边。

集合中的所有记录都有连接信息(即不存在孤立记录;集合中的每条记录都连接到集合中的一个或多个其他记录)。

我想从集合中选择任意两条记录,并能够显示所选记录之间的所有简单路径。 “简单路径”是指路径中没有重复记录的路径(即只有有限路径)。

注意:两个选择的记录将始终不同(即开始和结束顶点永远不会相同;没有循环)。

例如:

    If I have the following records:        A, B, C, D, E    and the following represents the connections:         (A,B),(A,C),(B,A),(B,D),(B,E),(B,F),(C,A),(C,E),        (C,F),(D,B),(E,C),(E,F),(F,B),(F,C),(F,E)        [where (A,B) means record A connects to record B]

如果我选择 B 作为我的开始记录,E 作为我的结束记录,我想找到所有通过记录连接的简单路径,将记录 B 连接到记录 E。

   All paths connecting B to E:      B->E      B->F->E      B->F->C->E      B->A->C->E      B->A->C->F->E

这是一个例子,在实践中我可能有包含数十万条记录的集合。

最佳答案

这似乎可以通过对图进行深度优先搜索来完成。 深度优先搜索将找到两个节点之间的所有非循环路径。这个算法应该非常快并且可以扩展到大图(图数据结构是稀疏的,所以它只使用与它一样多的内存需要)。

我注意到您在上面指定的图形只有一条方向边 (B,E)。这是打字错误还是真的是有向图?该解决方案无论如何都有效。抱歉,我无法在 C 中做到这一点,我在那个领域有点弱。不过,我希望您能够毫不费力地翻译这段 Java 代码。

Graph.java:

import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.Map;
import java.util.Set;

public class Graph {
private Map<String, LinkedHashSet<String>> map = new HashMap();

public void addEdge(String node1, String node2) {
LinkedHashSet<String> adjacent = map.get(node1);
if(adjacent==null) {
adjacent = new LinkedHashSet();
map.put(node1, adjacent);
}
adjacent.add(node2);
}

public void addTwoWayVertex(String node1, String node2) {
addEdge(node1, node2);
addEdge(node2, node1);
}

public boolean isConnected(String node1, String node2) {
Set adjacent = map.get(node1);
if(adjacent==null) {
return false;
}
return adjacent.contains(node2);
}

public LinkedList<String> adjacentNodes(String last) {
LinkedHashSet<String> adjacent = map.get(last);
if(adjacent==null) {
return new LinkedList();
}
return new LinkedList<String>(adjacent);
}
}

搜索.java:

import java.util.LinkedList;

public class Search {

private static final String START = "B";
private static final String END = "E";

public static void main(String[] args) {
// this graph is directional
Graph graph = new Graph();
graph.addEdge("A", "B");
graph.addEdge("A", "C");
graph.addEdge("B", "A");
graph.addEdge("B", "D");
graph.addEdge("B", "E"); // this is the only one-way connection
graph.addEdge("B", "F");
graph.addEdge("C", "A");
graph.addEdge("C", "E");
graph.addEdge("C", "F");
graph.addEdge("D", "B");
graph.addEdge("E", "C");
graph.addEdge("E", "F");
graph.addEdge("F", "B");
graph.addEdge("F", "C");
graph.addEdge("F", "E");
LinkedList<String> visited = new LinkedList();
visited.add(START);
new Search().depthFirst(graph, visited);
}

private void depthFirst(Graph graph, LinkedList<String> visited) {
LinkedList<String> nodes = graph.adjacentNodes(visited.getLast());
// examine adjacent nodes
for (String node : nodes) {
if (visited.contains(node)) {
continue;
}
if (node.equals(END)) {
visited.add(node);
printPath(visited);
visited.removeLast();
break;
}
}
for (String node : nodes) {
if (visited.contains(node) || node.equals(END)) {
continue;
}
visited.addLast(node);
depthFirst(graph, visited);
visited.removeLast();
}
}

private void printPath(LinkedList<String> visited) {
for (String node : visited) {
System.out.print(node);
System.out.print(" ");
}
System.out.println();
}
}

程序输出:

B E 
B A C E
B A C F E
B F E
B F C E

关于algorithm - 寻找两个任意顶点之间所有连接的图算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58306/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com