Java JGraphT:如何尽可能高效地表示顶点和边集

Java JGraphT:如何尽可能高效地表示顶点和边集,java,graph-theory,dot,jgrapht,logistics,Java,Graph Theory,Dot,Jgrapht,Logistics,除了这个JGraphT(Java)库之外,我还不熟悉图论,我正在使用它来实现一个我试图解决的物流问题的解决方案。因此,我对解决这个问题的最佳方法有点迷茫,因为给定传入数据,我必须表示从a点到C点的装运路径 给定一个传输段或有序对的列表,如何用最少的边以编程方式表示它 送货1从亚特兰大到孟买 送货2从亚特兰大到伦敦 Delivery 3从伦敦到孟买 在我的可视化图形表示中,我想删除显式的Atlanta to Mumbai边,并简单地从其他边推断,并简单地表示为: 亚特兰大->伦敦->孟买 我觉得可

除了这个JGraphT(Java)库之外,我还不熟悉图论,我正在使用它来实现一个我试图解决的物流问题的解决方案。因此,我对解决这个问题的最佳方法有点迷茫,因为给定传入数据,我必须表示从a点到C点的装运路径

给定一个传输段或有序对的列表,如何用最少的边以编程方式表示它

送货1
从亚特兰大到孟买

送货2
从亚特兰大到伦敦

Delivery 3
从伦敦到孟买

在我的可视化图形表示中,我想删除显式的
Atlanta to Mumbai
边,并简单地从其他边推断,并简单地表示为:

亚特兰大->伦敦->孟买

我觉得可能有一种现有的路径算法可以应用于解决这个相当简单的用例,但考虑到我对主题的相对新颖性,我正在努力找出哪种算法。如果我的要求是删除过多的顶点而不是边,那么这里似乎可以使用
ShortestPathAlgorithm

我可以确定给定对的最终
接收器
(即亚特兰大是源,孟买是接收器),但如果可能的话,我不想走手动移除边缘的道路

当前表示法:

所需表示:

我创建了一个类来帮助我实现下面提到的替代深度优先解决方案@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);
    }
  }
}
公共最终课程演示{
公共静态void main(字符串[]args)引发异常{
//创建图形对象
Graph Graph=新的DefaultDirectedGraph(DefaultEdge.class);
字符串亚特兰大=“亚特兰大”;
String london=“伦敦”;
字符串mumbai=“mumbai”;
graph.addVertex(亚特兰大);
图.addVertex(伦敦);
图.addVertex(孟买);
图.附录(亚特兰大,伦敦);
图.附录(伦敦、孟买);
附录(亚特兰大、孟买);
ComponentNameProvider vertexIdProvider=名称->名称;
ComponentNameProvider vertexLabelProvider=名称->名称;
字符串start=graph.vertexSet().stream().filter(r->r.equals(“亚特兰大”)).findAny().get();
System.out.println(“--traverseGraph output”);
遍历图形(图形,开始);
GraphExporter exporter=新点导出器(vertexIdProvider,vertexLabelProvider,null);
Writer-Writer=新的StringWriter();
exporter.exportGraph(图形、书写器);
System.out.println(writer.toString());
}
私有静态void遍历图(图形、字符串开始){
迭代器迭代器=新的DepthFirstIterator(图,开始);
while(iterator.hasNext()){
String字符串=迭代器.next();
System.out.println(字符串);
}
}
}

目前,该问题的表述不够精确,无法给出准确答案。不过,您似乎可以通过以下步骤解决问题:

  • 构造包含所有弧的有向图。将一个额外的节点“s”添加到图形中,该图形具有所有其他节点的传出弧
  • 从节点“s”开始执行(BFS)
  • 最后,删除节点以及所有不属于BFS树的边。 您还可以使用代替BFS,并删除所有后边缘、前边缘和交叉边缘

  • 所有这些在JGraphT中都很容易完成,但这是一个单独的问题。

    这个问题与JGraphT无关。首先,您需要了解一些概念性问题,然后您可以考虑实施。您删除arc(亚特兰大,孟买)而不是arc(伦敦,孟买)的具体原因是什么?我们试图表示一条逻辑线,一辆卡车在给定一组起点(源)和目的地(汇)的情况下,在交付货物时会采用这种逻辑线对。很抱歉,在找到概念解决方案之前就引用了实现工具。我对理论和所选择的实现都很陌生。谢谢你的建议。我尝试使用深度优先迭代器来了解更多关于该算法的信息,但不理解为什么孟买在这种情况下比伦敦来得早(或者为什么它不会)。请参阅下面的代码示例。您应该在链接的Wikipedia页面上查看DFS算法的伪代码。DFS无法区分解决方案{(亚特兰大->伦敦)、(亚特兰大->孟买)和{(亚特兰大->伦敦)、(伦敦->孟买)}。根据您的问题,这两种解决方案都以“尽可能少的边”表示您的问题。