/** Creates a mutable copy of {@code network} with the same nodes and edges. */ public static <N, E> MutableNetwork<N, E> copyOf(Network<N, E> network) { MutableNetwork<N, E> copy = NetworkBuilder.from(network) .expectedNodeCount(network.nodes().size()) .expectedEdgeCount(network.edges().size()) .build(); for (N node : network.nodes()) { copy.addNode(node); } for (E edge : network.edges()) { EndpointPair<N> endpointPair = network.incidentNodes(edge); copy.addEdge(endpointPair.nodeU(), endpointPair.nodeV(), edge); } return copy; }
private static <N, E> NetworkConnections<N, E> connectionsOf(Network<N, E> network, N node) { if (network.isDirected()) { Map<E, N> inEdgeMap = Maps.asMap(network.inEdges(node), sourceNodeFn(network)); Map<E, N> outEdgeMap = Maps.asMap(network.outEdges(node), targetNodeFn(network)); int selfLoopCount = network.edgesConnecting(node, node).size(); return network.allowsParallelEdges() ? DirectedMultiNetworkConnections.ofImmutable(inEdgeMap, outEdgeMap, selfLoopCount) : DirectedNetworkConnections.ofImmutable(inEdgeMap, outEdgeMap, selfLoopCount); } else { Map<E, N> incidentEdgeMap = Maps.asMap(network.incidentEdges(node), adjacentNodeFn(network, node)); return network.allowsParallelEdges() ? UndirectedMultiNetworkConnections.ofImmutable(incidentEdgeMap) : UndirectedNetworkConnections.ofImmutable(incidentEdgeMap); } }
/** * Returns true if {@code network} has at least one cycle. A cycle is defined as a non-empty * subset of edges in a graph arranged to form a path (a sequence of adjacent outgoing edges) * starting and ending with the same node. * * <p>This method will detect any non-empty cycle, including self-loops (a cycle of length 1). */ public static boolean hasCycle(Network<?, ?> network) { // In a directed graph, parallel edges cannot introduce a cycle in an acyclic graph. // However, in an undirected graph, any parallel edge induces a cycle in the graph. if (!network.isDirected() && network.allowsParallelEdges() && network.edges().size() > network.asGraph().edges().size()) { return true; } return hasCycle(network.asGraph()); }
private static <N, E> Map<E, N> getEdgeToReferenceNode(Network<N, E> network) { // ImmutableMap.Builder maintains the order of the elements as inserted, so the map will have // whatever ordering the network's edges do, so ImmutableSortedMap is unnecessary even if the // input edges are sorted. ImmutableMap.Builder<E, N> edgeToReferenceNode = ImmutableMap.builder(); for (E edge : network.edges()) { edgeToReferenceNode.put(edge, network.incidentNodes(edge).nodeU()); } return edgeToReferenceNode.build(); }
/** * Returns a {@link NetworkBuilder} initialized with all properties queryable from {@code * network}. * * <p>The "queryable" properties are those that are exposed through the {@link Network} interface, * such as {@link Network#isDirected()}. Other properties, such as {@link * #expectedNodeCount(int)}, are not set in the new builder. */ public static <N, E> NetworkBuilder<N, E> from(Network<N, E> network) { return new NetworkBuilder<N, E>(network.isDirected()) .allowsParallelEdges(network.allowsParallelEdges()) .allowsSelfLoops(network.allowsSelfLoops()) .nodeOrder(network.nodeOrder()) .edgeOrder(network.edgeOrder()); }
assertThat(networkString).contains("isDirected: " + network.isDirected()); assertThat(networkString).contains("allowsParallelEdges: " + network.allowsParallelEdges()); assertThat(networkString).contains("allowsSelfLoops: " + network.allowsSelfLoops()); Graph<N> asGraph = network.asGraph(); AbstractGraphTest.validateGraph(asGraph); assertThat(network.nodes()).isEqualTo(asGraph.nodes()); assertThat(network.edges().size()).isAtLeast(asGraph.edges().size()); assertThat(network.nodeOrder()).isEqualTo(asGraph.nodeOrder()); assertThat(network.isDirected()).isEqualTo(asGraph.isDirected()); assertThat(network.allowsSelfLoops()).isEqualTo(asGraph.allowsSelfLoops()); for (E edge : sanityCheckSet(network.edges())) { EndpointPair<N> endpointPair = network.incidentNodes(edge); N nodeU = endpointPair.nodeU(); N nodeV = endpointPair.nodeV(); assertThat(asGraph.edges()).contains(EndpointPair.of(network, nodeU, nodeV)); assertThat(network.edgesConnecting(nodeU, nodeV)).contains(edge); assertThat(network.successors(nodeU)).contains(nodeV); assertThat(network.adjacentNodes(nodeU)).contains(nodeV); assertThat(network.outEdges(nodeU)).contains(edge); assertThat(network.incidentEdges(nodeU)).contains(edge); assertThat(network.predecessors(nodeV)).contains(nodeU); assertThat(network.adjacentNodes(nodeV)).contains(nodeU); assertThat(network.inEdges(nodeV)).contains(edge); assertThat(network.incidentEdges(nodeV)).contains(edge); for (N incidentNode : network.incidentNodes(edge)) {
@Override public final boolean equals(@Nullable Object obj) { if (obj == this) { return true; } if (!(obj instanceof Network)) { return false; } Network<?, ?> other = (Network<?, ?>) obj; return isDirected() == other.isDirected() && nodes().equals(other.nodes()) && edgeIncidentNodesMap(this).equals(edgeIncidentNodesMap(other)); }
AbstractNetworkTest.validateNetwork(transpose); assertThat(transpose.edgesConnecting(N1, N2)).isEmpty(); assertThat(transpose.edgeConnecting(N1, N2).isPresent()).isFalse(); assertThat(transpose.edgeConnectingOrNull(N1, N2)).isNull(); assertThat(directedGraph.inDegree(node)).isSameAs(transpose.outDegree(node)); assertThat(directedGraph.outDegree(node)).isSameAs(transpose.inDegree(node)); assertThat(transpose.edgesConnecting(N1, N2)).containsExactly(E21); assertThat(transpose.edgeConnecting(N1, N2).get()).isEqualTo(E21); assertThat(transpose.edgeConnectingOrNull(N1, N2)).isEqualTo(E21); AbstractNetworkTest.validateNetwork(transpose);
public Double apply(VEPair<N, E> ve_pair) { E e = ve_pair.getE(); N v = ve_pair.getV(); return graph.isDirected() ? 1.0 / graph.outDegree(graph.incidentNodes(e).source()) : 1.0 / graph.degree(v); } }
private static <N, E> Map<N, NetworkConnections<N, E>> getNodeConnections(Network<N, E> network) { // ImmutableMap.Builder maintains the order of the elements as inserted, so the map will have // whatever ordering the network's nodes do, so ImmutableSortedMap is unnecessary even if the // input nodes are sorted. ImmutableMap.Builder<N, NetworkConnections<N, E>> nodeConnections = ImmutableMap.builder(); for (N node : network.nodes()) { nodeConnections.put(node, connectionsOf(network, node)); } return nodeConnections.build(); }
@Override public EndpointPair<N> apply(E edge) { return network.incidentNodes(edge); } };
public void setNetwork(Network<N, E> network, boolean forceUpdate) { log.trace("setNetwork to n:{} e:{}", network.nodes(), network.edges()); this.network = network; this.layoutModel.setGraph(network.asGraph()); if (forceUpdate && this.layoutAlgorithm != null) { log.trace("will accept {}", layoutAlgorithm); layoutModel.accept(this.layoutAlgorithm); log.trace("will fire stateChanged"); changeSupport.fireStateChanged(); log.trace("fired stateChanged"); } }
@Override public void layoutChanged(LayoutEvent<N> evt) { // need to take care of edge changes N node = evt.getNode(); Point p = evt.getLocation(); if (visualizationModel.getNetwork().nodes().contains(node)) { Set<E> edges = visualizationModel.getNetwork().incidentEdges(node); for (E edge : edges) { update(edge, p); } } }
@Override public Set<E> edgesConnecting(N nodeU, N nodeV) { return delegate().edgesConnecting(nodeU, nodeV); }
@Override public boolean isDirected() { return delegate().isDirected(); }
@Override public int degree(N node) { return delegate().degree(node); }
@Override public int inDegree(N node) { return delegate().inDegree(node); }
private static <N, E> Map<E, EndpointPair<N>> edgeIncidentNodesMap(final Network<N, E> network) { Function<E, EndpointPair<N>> edgeToIncidentNodesFn = new Function<E, EndpointPair<N>>() { @Override public EndpointPair<N> apply(E edge) { return network.incidentNodes(edge); } }; return Maps.asMap(network.edges(), edgeToIncidentNodesFn); } }
/** * Initialize incoming EIGRP message queues for each adjacency * * @param eigrpTopology The topology representing EIGRP adjacencies */ void initQueues(Network<EigrpInterface, EigrpEdge> eigrpTopology) { _incomingRoutes = _interfaces.stream() .filter(eigrpTopology.nodes()::contains) .flatMap(n -> eigrpTopology.inEdges(n).stream()) .collect(toImmutableSortedMap(Function.identity(), e -> new ConcurrentLinkedQueue<>())); }