除了我正在使用的这个 JGraphT (Java) 库之外,我还是图论的新手,以便为我试图解决的物流问题实施解决方案。因此,我对解决这个问题的最佳方法有点迷茫,我必须在给定传入数据的情况下表示货物从 A 点到 C 点的路径。
给定一个传送段或有序对的列表,我如何以尽可能少的边以编程方式表示它?
Delivery 1
从亚特兰大到孟买。
Delivery 2
从亚特兰大到伦敦。
Delivery 3
从伦敦到孟买。
在我的可视化图形表示中,我想删除显式Atlanta to Mumbai
边缘并简单地从其他边缘推断出来,并将其简单地表示为:
Atlanta -> London -> Mumbai
我觉得可能有一个现有的路径算法可以用来解决这个相当简单的用例,但鉴于我对主题的相对较新,我正在努力找出哪一个。如果我的要求是删除过多的顶点而不是边,那么这里似乎ShortestPathAlgorithm
很有用。
我可能会确定我给定的对的最终source
和sink
(即亚特兰大是源,孟买是接收器),但如果可能的话,我不想走手动移除边缘的路径。
当前代表:
期望的代表:
我创建了一个类来让我接近实现替代深度优先解决方案@JorisKinable 下面提到,但仍然不明白为什么“亚特兰大、孟买和伦敦”按此顺序列出。如果没有对边缘施加权重,是什么导致孟买在这种情况下排在伦敦之前?
public final class Demo {
public static void main(String[] args) throws Exception {
// Create the graph object
Graph<String, DefaultEdge> graph = new DefaultDirectedGraph<>(DefaultEdge.class);
String atlanta = "Atlanta";
String london = "London";
String mumbai = "Mumbai";
graph.addVertex(atlanta);
graph.addVertex(london);
graph.addVertex(mumbai);
graph.addEdge(atlanta, london);
graph.addEdge(london, mumbai);
graph.addEdge(atlanta, mumbai);
ComponentNameProvider<String> vertexIdProvider = name -> name;
ComponentNameProvider<String> vertexLabelProvider = name -> name;
String start = graph.vertexSet().stream().filter(r -> r.equals("Atlanta")).findAny().get();
System.out.println("-- traverseGraph output");
traverseGraph(graph, start);
GraphExporter<String, DefaultEdge> exporter = new DOTExporter<>(vertexIdProvider, vertexLabelProvider, null);
Writer writer = new StringWriter();
exporter.exportGraph(graph, writer);
System.out.println(writer.toString());
}
private static void traverseGraph(Graph<String, DefaultEdge> graph, String start) {
Iterator<String> iterator = new DepthFirstIterator<>(graph, start);
while (iterator.hasNext()) {
String string = iterator.next();
System.out.println(string);
}
}
}