在guava比较新的版本中提供了Graph类,顾名思义,都是跟图论相关的。
它提供了Graph、ValueGraph、Network几个类。它们的功能层层递进,差别都在边Edge的定义上。
如果边的定义很模糊,只是两个点的连接,没有其他的属性,那就可以用Graph。
如果边有名字或者权重,那就选择ValueGraph。
如果边是一级对象,每条边在图中都是唯一的,那就用Network.
一、构造图
// Creating mutable graphs MutableGraph<Integer> graph = GraphBuilder.undirected().build(); MutableValueGraph<City, Distance> roads = ValueGraphBuilder.directed() .incidentEdgeOrder(ElementOrder.stable()) .build(); MutableNetwork<Webpage, Link> webSnapshot = NetworkBuilder.directed() .allowsParallelEdges(true) .nodeOrder(ElementOrder.natural()) .expectedNodeCount(100000) .expectedEdgeCount(1000000) .build(); // Creating an immutable graph ImmutableGraph<Country> countryAdjacencyGraph = GraphBuilder.undirected() .<Country>immutable() .putEdge(FRANCE, GERMANY) .putEdge(FRANCE, BELGIUM) .putEdge(GERMANY, BELGIUM) .addNode(ICELAND) .build();
ImmutableGraph<Integer> graph = GraphBuilder.directed() .<Integer>immutable() .addNode(1) .putEdge(2, 3) // also adds nodes 2 and 3 if not already present .putEdge(2, 3) // no effect; Graph does not support parallel edges .build(); Set<Integer> successorsOfTwo = graph.successors(2); // returns {3} MutableValueGraph<Integer, Double> weightedGraph = ValueGraphBuilder.directed().build(); weightedGraph.addNode(1); weightedGraph.putEdgeValue(2, 3, 1.5); // also adds nodes 2 and 3 if not already present weightedGraph.putEdgeValue(3, 5, 1.5); // edge values (like Map values) need not be unique ... weightedGraph.putEdgeValue(2, 3, 2.0); // updates the value for (2,3) to 2.0 MutableNetwork<Integer, String> network = NetworkBuilder.directed().build(); network.addNode(1); network.addEdge("2->3", 2, 3); // also adds nodes 2 and 3 if not already present Set<Integer> successorsOfTwo = network.successors(2); // returns {3} Set<String> outEdgesOfTwo = network.outEdges(2); // returns {"2->3"} network.addEdge("2->3 too", 2, 3); // throws; Network disallows parallel edges // by default network.addEdge("2->3", 2, 3); // no effect; this edge is already present // and connecting these nodes in this order Set<String> inEdgesOfFour = network.inEdges(4); // throws; node not in graph
二、图的常用方法
graph.nodes().contains(node); // This is the preferred syntax since 23.0 for all graph types. graphs.hasEdgeConnecting(u, v); // These are equivalent (to each other and to the above expression). graph.successors(u).contains(v); graph.predecessors(v).contains(u); // This is equivalent to the expressions above if the graph is undirected. graph.adjacentNodes(u).contains(v); // This works only for Networks. !network.edgesConnecting(u, v).isEmpty(); // This works only if "network" has at most a single edge connecting u to v. network.edgeConnecting(u, v).isPresent(); // Java 8 only network.edgeConnectingOrNull(u, v) != null; // These work only for ValueGraphs. valueGraph.edgeValue(u, v).isPresent(); // Java 8 only valueGraph.edgeValueOrDefault(u, v, null) != null;