import org.apache.commons.collections.CollectionUtils; import org.jgrapht.Graph; import com.google.common.base.Preconditions; import com.google.common.collect.Lists; import java.util.List; import java.util.stream.Collectors; /** * @ClassName: GraphXPUtils * @author kanpiaoxue * @version 1.0 * @CreateTime: 2019/09/03 15:50:36 * @Description: Graph工具类 */ public class GraphXPUtils { private static final int ZERO = 0; /** * */ private GraphXPUtils() { super(); } /** * 找到图中的叶子节点 * * @param* @param * @param graph * @return * @author kanpiaoxue * @CreateTime: 2019/09/03 15:53:08 * @Description: 图中的叶子节点:它们的出度为 0 */ public static List findLeaves(Graph graph) { Preconditions.checkNotNull(graph, "graph is null"); if (CollectionUtils.isEmpty(graph.vertexSet())) { return Lists.newArrayList(); } return graph.vertexSet().stream().filter(v -> { return graph.outDegreeOf(v) == ZERO; }).collect(Collectors.toList()); } /** * 找到图中的根节点 * * @param * @param * @param graph * @return * @author kanpiaoxue * @CreateTime: 2019/09/03 15:53:08 * @Description: 图中的根节点:它们的入度为 0 */ public static List findRoots(Graph graph) { Preconditions.checkNotNull(graph, "graph is null"); if (CollectionUtils.isEmpty(graph.vertexSet())) { return Lists.newArrayList(); } return graph.vertexSet().stream().filter(v -> { return graph.inDegreeOf(v) == ZERO; }).collect(Collectors.toList()); } }
全部路径的示例代码:
public static void test021() throws Exception { Graphg = new DirectedAcyclicGraph (DefaultEdge.class); IntStream.rangeClosed(1, 13).forEach(v -> { g.addVertex(v); }); /** * * * [示意图]:当前Graph是有向无环图(DAG),方向是:从上到下。 * -- predecessor:upstream * * 8 1 5 7 9 11 * | / | \ \ / | * 2 3 4 6 10 * | | * 12 | * \ | * 13 * * -- successor:downstream * **/ g.addEdge(8, 2); g.addEdge(1, 2); g.addEdge(1, 3); g.addEdge(1, 4); g.addEdge(5, 6); g.addEdge(7, 6); g.addEdge(9, 10); g.addEdge(2, 12); g.addEdge(3, 13); g.addEdge(12, 13); // 目标顶点 Integer targetVertex = 13; // 双连通性检查器 BiconnectivityInspectorin = new BiconnectivityInspector<>(g); System.out.println(StringUtils.repeat("=", 100)); // 根据目标顶点得到它的连通图。 Graph g2 = in.getConnectedComponent(targetVertex); System.out.println(String.format("targetVertex:%s, 连通图:%s", targetVertex, g2)); // 由于当前连通图 g2 是个无向图,需要将它转换为DAG有向图,采用子图的方式转换为g3的DAG Graph g3 = new AsSubgraph (g, g2.vertexSet()); System.out.println(String.format("targetVertex:%s, 连通DAG图:%s", targetVertex, g3)); /** * * * g2 ---> output * ([1, 2, 3, 4, 8, 12, 13], [{1,2}, {1,3}, {1,4}, {8,2}, {12,13}, {2,12}, {3,13}]) * g3 ---> output * ([1, 2, 3, 4, 8, 12, 13], [(8,2), (1,2), (1,3), (1,4), (2,12), (3,13), (12,13)]) * [注意] g2 和 g3 在边的打印上面的区别: * g2是无向图,边的关系使用花括号表示,如:{12,13} * g3是有向图,边的关系使用实括号表示,如:(12,13) * 有向图和无向图edge打印的区别可以查看下面的源代码: * org.jgrapht.graph.AbstractGraph.java#toString() **/ // 计算所有路径采用 AllDirectedPaths 来获得 AllDirectedPathsallPaths = new AllDirectedPaths (g); // 找到新的DAG图中的所有root顶点 List roots = GraphXPUtils.findRoots(g3); System.out.println(String.format("roots:%s", roots)); // 在新的DAG图中对所有root顶点进行遍历,查找它们到目标顶点的所有的路径 roots.forEach(root -> { System.out.println(StringUtils.repeat("=", 100)); List > paths = allPaths.getAllPaths(root, targetVertex, true, null); paths.forEach(p -> { System.out.println(String.format("root:%s,targetVertex:%s,path:%s", root, targetVertex, p)); }); }); }