/** * This test checks an implementation dependent feature. It tests that the method {@code addEdge} * will silently add the missing nodes to the graph, then add the edge connecting them. We are not * using the proxy methods here as we want to test {@code addEdge} when the end-points are not * elements of the graph. */ @Test public void addEdge_nodesNotInGraph() { network.addNode(N1); assertTrue(network.addEdge(N1, N5, E15)); assertTrue(network.addEdge(N4, N1, E41)); assertTrue(network.addEdge(N2, N3, E23)); assertThat(network.nodes()).containsExactly(N1, N5, N4, N2, N3).inOrder(); assertThat(network.edges()).containsExactly(E15, E41, E23).inOrder(); assertThat(network.edgesConnecting(N1, N5)).containsExactly(E15); assertThat(network.edgesConnecting(N4, N1)).containsExactly(E41); assertThat(network.edgesConnecting(N2, N3)).containsExactly(E23); assertThat(network.edgesConnecting(N3, N2)).containsExactly(E23); } }
@Test public void endpointPair_undirectedNetwork() { MutableNetwork<Integer, String> undirectedNetwork = NetworkBuilder.undirected().allowsParallelEdges(true).allowsSelfLoops(true).build(); undirectedNetwork.addNode(N0); undirectedNetwork.addEdge(N1, N2, E12); undirectedNetwork.addEdge(N2, N1, E12_A); // adds parallel edge, won't be in Graph edges undirectedNetwork.addEdge(N1, N3, E13); undirectedNetwork.addEdge(N4, N4, E44); containsExactlySanityCheck( undirectedNetwork.asGraph().edges(), EndpointPair.unordered(N1, N2), EndpointPair.unordered(N1, N3), EndpointPair.unordered(N4, N4)); }
@Test public void removeEdge_existingEdge() { addEdge(N1, N2, E12); assertTrue(network.removeEdge(E12)); assertFalse(network.removeEdge(E12)); assertThat(network.edges()).doesNotContain(E12); assertThat(network.edgesConnecting(N1, N2)).isEmpty(); }
/** * Returns the subgraph of {@code network} induced by {@code nodes}. This subgraph is a new graph * that contains all of the nodes in {@code nodes}, and all of the {@link Network#edges() edges} * from {@code network} for which the {@link Network#incidentNodes(Object) incident nodes} are * both contained by {@code nodes}. * * @throws IllegalArgumentException if any element in {@code nodes} is not a node in the graph */ public static <N, E> MutableNetwork<N, E> inducedSubgraph( Network<N, E> network, Iterable<? extends N> nodes) { MutableNetwork<N, E> subgraph = (nodes instanceof Collection) ? NetworkBuilder.from(network).expectedNodeCount(((Collection) nodes).size()).build() : NetworkBuilder.from(network).build(); for (N node : nodes) { subgraph.addNode(node); } for (N node : subgraph.nodes()) { for (E edge : network.outEdges(node)) { N successorNode = network.incidentNodes(edge).adjacentNode(node); if (subgraph.nodes().contains(successorNode)) { subgraph.addEdge(node, successorNode, edge); } } } return subgraph; }
@Test public void edgesConnecting_checkReturnedSetMutability() { network.addNode(N1); network.addNode(N2); Set<String> edgesConnecting = network.edgesConnecting(N1, N2); try { edgesConnecting.add(E23); fail(ERROR_MODIFIABLE_COLLECTION); } catch (UnsupportedOperationException e) { network.addEdge(N1, N2, E12); assertThat(networkForTest.edgesConnecting(N1, N2)).containsExactlyElementsIn(edgesConnecting); } }
assertThat(network.nodes()).isEmpty(); assertThat(network.edges()).isEmpty(); AbstractNetworkTest.validateNetwork(network); while (network.nodes().size() < NUM_NODES) { network.addNode(gen.nextInt(NODE_POOL_SIZE)); ArrayList<Integer> nodeList = new ArrayList<>(network.nodes()); for (int i = 0; i < NUM_EDGES; ++i) { network.addEdge( getRandomElement(nodeList, gen), getRandomElement(nodeList, gen), new Object())) .isTrue(); ArrayList<Object> edgeList = new ArrayList<>(network.edges()); assertThat(network.nodes()).hasSize(NUM_NODES); assertThat(network.edges()).hasSize(NUM_EDGES); AbstractNetworkTest.validateNetwork(network); for (int i = 0; i < numEdgesToRemove; ++i) { Object edge = edgeList.get(i); assertThat(network.removeEdge(edge)).isTrue(); assertThat(network.nodes()).hasSize(NUM_NODES); assertThat(network.edges()).hasSize(NUM_EDGES - numEdgesToRemove); AbstractNetworkTest.validateNetwork(network); int numNodesToRemove = gen.nextInt(NUM_NODES);
@Test public void removeNode_existingNode() { addEdge(N1, N2, E12); addEdge(N4, N1, E41); assertTrue(network.removeNode(N1)); assertFalse(network.removeNode(N1)); assertThat(network.nodes()).containsExactly(N2, N4); assertThat(network.edges()).doesNotContain(E12); assertThat(network.edges()).doesNotContain(E41); }
@After public void validateUndirectedEdges() { for (Integer node : network.nodes()) { new EqualsTester() .addEqualityGroup( network.inEdges(node), network.outEdges(node), network.incidentEdges(node)) .testEquals(); new EqualsTester() .addEqualityGroup( network.predecessors(node), network.successors(node), network.adjacentNodes(node)) .testEquals(); for (Integer adjacentNode : network.adjacentNodes(node)) { assertThat(network.edgesConnecting(node, adjacentNode)) .containsExactlyElementsIn(network.edgesConnecting(adjacentNode, node)); } } }
@Test public void createDirected_multigraph() { MutableNetwork<Integer, String> directedMultigraph = NetworkBuilder.directed().allowsParallelEdges(true).build(); assertThat(directedMultigraph.addEdge(N1, N2, E12)).isTrue(); assertThat(directedMultigraph.addEdge(N1, N2, E12_A)).isTrue(); assertThat(directedMultigraph.edgesConnecting(N1, N2)).isEqualTo(ImmutableSet.of(E12, E12_A)); assertThat(directedMultigraph.edgesConnecting(N2, N1)).isEmpty(); }
/** * A proxy method that adds the node {@code n} to the graph being tested. In case of Immutable * graph implementations, this method should add {@code n} to the graph builder and build a new * graph with the current builder state. * * @return {@code true} iff the graph was modified as a result of this call */ @CanIgnoreReturnValue protected boolean addNode(Integer n) { return network.addNode(n); }
@After public void validateSourceAndTarget() { for (Integer node : network.nodes()) { for (String inEdge : network.inEdges(node)) { EndpointPair<Integer> endpointPair = network.incidentNodes(inEdge); assertThat(endpointPair.source()).isEqualTo(endpointPair.adjacentNode(node)); assertThat(endpointPair.target()).isEqualTo(node); } for (String outEdge : network.outEdges(node)) { EndpointPair<Integer> endpointPair = network.incidentNodes(outEdge); assertThat(endpointPair.source()).isEqualTo(node); assertThat(endpointPair.target()).isEqualTo(endpointPair.adjacentNode(node)); } for (Integer adjacentNode : network.adjacentNodes(node)) { Set<String> edges = network.edgesConnecting(node, adjacentNode); Set<String> antiParallelEdges = network.edgesConnecting(adjacentNode, node); assertThat(node.equals(adjacentNode) || Collections.disjoint(edges, antiParallelEdges)) .isTrue(); } } }
public void addSmallWorldConnections( MutableNetwork<N, E> graph, Distance<N> distance, Supplier<E> edgeFactory) { // verify that it's actually possible to give each node 'connectionCount' new incident edges // without creating parallel edges or self-loops (both are disallowed) Preconditions.checkArgument(graph.nodes().size() - 5 >= connectionCount); // TODO: For toroidal graphs, we can make this more clever by pre-creating the WeightedChoice object // and using the output as an offset to the current node location. for (N node : graph.nodes()) { // TODO: come up with a better random selection mechanism. // in this case we want selection without replacement, which is not what WeightedChoice does; // otherwise we can keep selecting the same target over and over again, which is inefficient. WeightedChoice<N> weightedChoice = getWeightedChoiceForDistance(node, graph.asGraph(), distance); Set<N> targets = new HashSet<>(); while (targets.size() < connectionCount) { // the item returned is guaranteed by getWeightedChoiceForDistance() to not be equal to node // or any of its successors; we may try to add the same node to targets more than once // (see the note above re: selection w/o replacement) but the Set semantics disallows duplicates targets.add(weightedChoice.nextItem()); } for (N target : targets) { graph.addEdge(node, target, edgeFactory.get()); } } }
@Test public void equivalent_propertiesDiffer() { network.addEdge(N1, N2, E12); MutableNetwork<Integer, String> g2 = NetworkBuilder.from(network) .allowsParallelEdges(!network.allowsParallelEdges()) .allowsSelfLoops(!network.allowsSelfLoops()) .build(); g2.addEdge(N1, N2, E12); assertThat(network).isEqualTo(g2); }
@Test public void nodeOrderUnorderedandEdgesSorted() { MutableNetwork<Integer, String> network = NetworkBuilder.directed() .nodeOrder(unordered()) .edgeOrder(ElementOrder.sorted(Ordering.<String>natural().reverse())) .build(); addEdges(network); assertThat(network.edgeOrder()) .isEqualTo(ElementOrder.sorted(Ordering.<String>natural().reverse())); assertThat(network.edges()).containsExactly("p", "i", "e").inOrder(); assertThat(network.nodeOrder()).isEqualTo(unordered()); assertThat(network.nodes()).containsExactly(4, 1, 3); }
@Test public void removeNode_nodeNotPresent() { addNode(N1); ImmutableSet<Integer> nodes = ImmutableSet.copyOf(network.nodes()); assertFalse(network.removeNode(NODE_NOT_IN_GRAPH)); assertThat(network.nodes()).containsExactlyElementsIn(nodes); }
@Test public void removeEdge_edgeNotPresent() { addEdge(N1, N2, E12); ImmutableSet<String> edges = ImmutableSet.copyOf(network.edges()); assertFalse(network.removeEdge(EDGE_NOT_IN_GRAPH)); assertThat(network.edges()).containsExactlyElementsIn(edges); }
private void groupCluster(AggregateLayoutModel<Number> layoutModel, Set<Number> nodes) { if (nodes.size() < vv.getModel().getNetwork().nodes().size()) { Point center = layoutModel.apply(nodes.iterator().next()); MutableNetwork<Number, Number> subGraph = NetworkBuilder.undirected().build(); for (Number v : nodes) { subGraph.addNode(v); } LayoutAlgorithm<Number> subLayoutAlgorithm = new CircleLayoutAlgorithm<>(); LayoutModel<Number> subModel = LoadingCacheLayoutModel.<Number>builder() .setGraph(subGraph.asGraph()) .setSize(40, 40) .build(); layoutModel.put(subModel, center); subModel.accept(subLayoutAlgorithm); vv.repaint(); } } }