使用 JGraphT 库的 EdgeProvider class
Using the JGraphT library's EdgeProvider class
我四处寻找解决方案,但由于我对 Java 的通用编程风格没有太多经验,我什至对使用什么词进行搜索有点困惑这个。我正在尝试使用 DOTImporter (http://jgrapht.org/javadoc/org/jgrapht/ext/DOTImporter.html) from the JGraphT library, which in turn requires me to use the EdgeProvider interface (http://jgrapht.org/javadoc/org/jgrapht/ext/EdgeProvider.html). I have tried myriad ways of implementing this, but the fact that buildEdge uses a generic return type has me quite confused. I'm trying to use their DefaultEdge as well (http://jgrapht.org/javadoc/org/jgrapht/graph/DefaultEdge.html),这并没有好多少,因为他们的 API 指定了两种获取几个字段(源和目标)的方法,但没有办法设置这些字段,并且由于它们不是 public,并且构造函数没有参数,所以我不太确定应该如何设置它们。
为了将其置于上下文中,我正在尝试加载一个 .dot 文件,而我真正关心的只是标签,因此我的图形实际上将由字符串顶点组成,因此边将是(字符串, String) 结构也是如此。这真的很简单,因此我不介意实现我自己的图形结构来使用它,但我真的很想利用 DOTImporter。
如果有人能为我提供一些关于如何为 EdgeProvider 正确实施具体 class 以及如何使用 DefaultEdge class 的帮助,我将不胜感激。
简短回答:这是 DOTImporter 的完整示例(非常简单...):
1 之前 JGraphT 版本的示例代码。4.x:
public class DOTTest {
public static void main(String[] args) throws ImportException {
//Example graph
String input =
"digraph graphname {\r\n" + " a -> b -> c;\r\n" + " b -> d;\r\n" + " }";
GraphImporter<String, DefaultEdge> importer = new DOTImporter<>(
(label, attributes) -> label,
(from, to, label, attributes) -> new DefaultEdge()
);
Graph<String, DefaultEdge> result = new SimpleDirectedGraph<>(DefaultEdge.class);
importer.importGraph(result, new StringReader(input));
System.out.println(result);
}
}
JGraphT 1.5.0 及更高版本的新示例代码:
public class DOTTest {
public static void main(String[] args) throws ImportException {
//Example graph
String input =
"digraph graphname {\r\n" + " a -> b -> c;\r\n" + " b -> d;\r\n" + " }";
Graph<String, DefaultEdge> result = new SimpleDirectedGraph<>(DefaultEdge.class);
DOTImporter<String, DefaultEdge> dotImporter = new DOTImporter<>();
dotImporter.setVertexFactory(label -> label);
dotImporter.importGraph(result, new StringReader(input);
System.out.println(result);
}
}
请注意,在 JGraphT 中,每个 class 都带有相应的测试 class,其中包含许多示例。
更长的答案:
在 JGraphT 中,每个顶点和每条边都是一个对象。这允许非常灵活的图形。缺点是需要提供工厂方法。例如,如果您调用 graph.addEdge(u,v)
,则必须创建一个新对象来表示 u 和 v 之间的边。为此,需要一个边工厂。在许多实际情况下,用户不需要自定义边缘对象。对于这些情况,JGraphT 提供了 DefaultEdge class。一个您希望拥有自定义边的实际示例,例如,当您构建表示道路网络的图形时。一个顶点就是一个交叉点,一条边就是一条街道。例如,街道对象将存储车道数、行驶速度、行驶方向等。
那么 IntrusiveEdge
的目的是什么?除非您打算为 JGraphT 贡献代码,否则这并不重要。你不应该直接使用 IntrusiveEdge。 IntrusiveEdge 是大多数边缘的基本类型。在引擎盖下,它存储边的源、目标和权重。但是,这些字段是隐藏的,即不能直接访问它们!相反,图 class 提供了访问这些字段的方法,例如graph.getEdgeSource(myEdge).
我四处寻找解决方案,但由于我对 Java 的通用编程风格没有太多经验,我什至对使用什么词进行搜索有点困惑这个。我正在尝试使用 DOTImporter (http://jgrapht.org/javadoc/org/jgrapht/ext/DOTImporter.html) from the JGraphT library, which in turn requires me to use the EdgeProvider interface (http://jgrapht.org/javadoc/org/jgrapht/ext/EdgeProvider.html). I have tried myriad ways of implementing this, but the fact that buildEdge uses a generic return type has me quite confused. I'm trying to use their DefaultEdge as well (http://jgrapht.org/javadoc/org/jgrapht/graph/DefaultEdge.html),这并没有好多少,因为他们的 API 指定了两种获取几个字段(源和目标)的方法,但没有办法设置这些字段,并且由于它们不是 public,并且构造函数没有参数,所以我不太确定应该如何设置它们。
为了将其置于上下文中,我正在尝试加载一个 .dot 文件,而我真正关心的只是标签,因此我的图形实际上将由字符串顶点组成,因此边将是(字符串, String) 结构也是如此。这真的很简单,因此我不介意实现我自己的图形结构来使用它,但我真的很想利用 DOTImporter。
如果有人能为我提供一些关于如何为 EdgeProvider 正确实施具体 class 以及如何使用 DefaultEdge class 的帮助,我将不胜感激。
简短回答:这是 DOTImporter 的完整示例(非常简单...):
1 之前 JGraphT 版本的示例代码。4.x:
public class DOTTest {
public static void main(String[] args) throws ImportException {
//Example graph
String input =
"digraph graphname {\r\n" + " a -> b -> c;\r\n" + " b -> d;\r\n" + " }";
GraphImporter<String, DefaultEdge> importer = new DOTImporter<>(
(label, attributes) -> label,
(from, to, label, attributes) -> new DefaultEdge()
);
Graph<String, DefaultEdge> result = new SimpleDirectedGraph<>(DefaultEdge.class);
importer.importGraph(result, new StringReader(input));
System.out.println(result);
}
}
JGraphT 1.5.0 及更高版本的新示例代码:
public class DOTTest {
public static void main(String[] args) throws ImportException {
//Example graph
String input =
"digraph graphname {\r\n" + " a -> b -> c;\r\n" + " b -> d;\r\n" + " }";
Graph<String, DefaultEdge> result = new SimpleDirectedGraph<>(DefaultEdge.class);
DOTImporter<String, DefaultEdge> dotImporter = new DOTImporter<>();
dotImporter.setVertexFactory(label -> label);
dotImporter.importGraph(result, new StringReader(input);
System.out.println(result);
}
}
请注意,在 JGraphT 中,每个 class 都带有相应的测试 class,其中包含许多示例。
更长的答案:
在 JGraphT 中,每个顶点和每条边都是一个对象。这允许非常灵活的图形。缺点是需要提供工厂方法。例如,如果您调用 graph.addEdge(u,v)
,则必须创建一个新对象来表示 u 和 v 之间的边。为此,需要一个边工厂。在许多实际情况下,用户不需要自定义边缘对象。对于这些情况,JGraphT 提供了 DefaultEdge class。一个您希望拥有自定义边的实际示例,例如,当您构建表示道路网络的图形时。一个顶点就是一个交叉点,一条边就是一条街道。例如,街道对象将存储车道数、行驶速度、行驶方向等。
那么 IntrusiveEdge
的目的是什么?除非您打算为 JGraphT 贡献代码,否则这并不重要。你不应该直接使用 IntrusiveEdge。 IntrusiveEdge 是大多数边缘的基本类型。在引擎盖下,它存储边的源、目标和权重。但是,这些字段是隐藏的,即不能直接访问它们!相反,图 class 提供了访问这些字段的方法,例如graph.getEdgeSource(myEdge).