除了我正在使用的这个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);
}
}
}