gt-graph有向图是geotools中的图模块,是一个图形框架,该框架对寻找最短路径的dijkstra算法和A*算法都提供了实现。
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-graph</artifactId>
<version>18.0</version>
</dependency>
利用gt_graph进行手动有向图建模的时候(还可以使用路网数据导入建模),在计算最短路径取值时,经常会出现方向搞混的情况,非常的头疼。
建模时,图中的主要对象:
图Graph是由一堆的Node(点)和Edge(边)构成的
Edge边是由两个Node(点)构成的,可以理解为有向线段
边和其方向的指向
构建有向边时,是用框架提供的构建器进行构建
Edge edge = graphGenerator.getGraphBuilder().buildEdge(nodeA, nodeB);
此时我们会默认认为,这条边的方向应该是nodeA -----> nodeB。实际也是这个方向,从源码中我们会发现 nodeA对应的是Edge中的m_in字段,nodeB对应的m_out字段
当把上面构建的nodeA–>nodeB这条边加入图中时,会触发一个动作
graphGenerator.getGraphBuilder().addEdge(edge);
容易混淆的地方就出现了,在有向Node中会维护两个和自己有关的边列表。此时,当这条边加入图中时,会把上面构建的边加入到nodeA的m_out列表和nodeB的m_in列表中
就像如下的结构
容易造成我们错误使用的地方
Edge edge = nodeA.getEdge(nodeB);
这条边我们可能会默认认为我们拿到的是nodeA–>nodeB的边,但从源码来看其实是nodeB–>nodeA
先拿的是getInEdge(nodeB),为空了之后,才是拿的getOutEdge(nodeB)。意思是没有B–>A这条边的情况下,我们才会拿到A—>B这条边
在看看源码 getInEdge(nodeB)源码,会发现这个方法里面,nodeB是Edge对象的m_in,但是我们在最开始buildEdge的时候,nodeA才是Edge的m_in,所以这里就刚好反了。
方向边的正确取法
要取nodeA–>nodeB
Edge edge = nodeA.getOutEdge(nodeB);
可以理解为Edge = build(nodeA,nodeB)的边方向和nodeA.getOutEdge(nodeB)的边方向是一致的
和nodeA.getInEdge(nodeB)方向是相反的