/* * The subroutine of DFS. NOTE: the set is used to distinguish between 1st * and 2nd round of DFS. set == null: finished vertices are stored (1st * round). set != null: all vertices found will be saved in the set (2nd * round) */ private void dfsVisit( DirectedGraph<V, E> visitedGraph, VertexData<V> vertexData, Set<V> vertices) { Deque<VertexData<V>> stack = new ArrayDeque<VertexData<V>>(); stack.add(vertexData); while (!stack.isEmpty()) { VertexData<V> data = stack.removeLast(); if (!data.isDiscovered()) { data.setDiscovered(true); if (vertices != null) { vertices.add(data.getVertex()); } stack.add(new VertexData1<V>(data, true, true)); // follow all edges for (E edge : visitedGraph.outgoingEdgesOf(data.getVertex())) { VertexData<V> targetData = vertexToVertexData.get(visitedGraph.getEdgeTarget(edge)); if (!targetData.isDiscovered()) { // the "recursion" stack.add(targetData); } } } else if (data.isFinished()) { if (vertices == null) { orderedVertices.addFirst(data.getFinishedData()); } } } }
/* * Creates a VertexData object for every vertex in the graph and stores * them * in a HashMap. */ private void createVertexData() { vertexToVertexData = new HashMap<V, VertexData<V>>(graph.vertexSet().size()); for (V vertex : graph.vertexSet()) { vertexToVertexData.put(vertex, new VertexData2<V>(vertex, false, false)); } }
private void replaceVertex(JavaClass newClass) { List<JavaClass> incomingEdges = getParents(newClass); graph.removeVertex(newClass); graph.addVertex(newClass); for (JavaClass each : incomingEdges) { graph.addEdge(each, newClass); } }
private void updateParentReferences(JavaClass parentClass) { for (String child : parentClass.getImports()) { JavaClass childClass = findJavaClass(child); if ((childClass != null) && !childClass.equals(parentClass)) { if (graph.containsVertex(childClass)) { graph.addEdge(parentClass, childClass); } } } }
/** @see GraphListener#edgeRemoved(GraphEdgeChangeEvent) */ public void edgeRemoved(GraphEdgeChangeEvent<V, E> e) { E edge = e.getEdge(); V source = graph.getEdgeSource(edge); V target = graph.getEdgeTarget(edge); if (successorMap.containsKey(source)) { successorMap.get(source).removeNeighbor(target); } if (predecessorMap.containsKey(target)) { predecessorMap.get(target).removeNeighbor(source); } }
/** . */ public void testStronglyConnected2() { DirectedGraph<String, DefaultEdge> g = new DefaultDirectedGraph<String, DefaultEdge>(DefaultEdge.class); g.addVertex(V1); g.addVertex(V2); g.addVertex(V3); g.addVertex(V4); g.addEdge(V1, V2); g.addEdge(V2, V1); // strongly connected g.addEdge(V4, V3); // only weakly connected g.addEdge(V3, V2); // only weakly connected StrongConnectivityInspector<String, DefaultEdge> inspector = new StrongConnectivityInspector<String, DefaultEdge>(g); // convert from List to Set because we need to ignore order // during comparison Set<Set<String>> actualSets = new HashSet<Set<String>>(inspector.stronglyConnectedSets()); // construct the expected answer Set<Set<String>> expectedSets = new HashSet<Set<String>>(); Set<String> set = new HashSet<String>(); set.add(V1); set.add(V2); expectedSets.add(set); set = new HashSet<String>(); set.add(V3); expectedSets.add(set); set = new HashSet<String>(); set.add(V4); expectedSets.add(set); assertEquals(expectedSets, actualSets); actualSets.clear(); List<DirectedSubgraph<String, DefaultEdge>> subgraphs = inspector.stronglyConnectedSubgraphs(); for (DirectedSubgraph<String, DefaultEdge> sg : subgraphs) { actualSets.add(sg.vertexSet()); StrongConnectivityInspector<String, DefaultEdge> ci = new StrongConnectivityInspector<String, DefaultEdge>(sg); assertTrue(ci.isStronglyConnected()); } assertEquals(expectedSets, actualSets); }
/** * Finds the vertex set for the subgraph of all cycles. * * @return set of all vertices which participate in at least one cycle in this graph */ public Set<V> findCycles() { // ProbeIterator can't be used to handle this case, // so use StrongConnectivityInspector instead. StrongConnectivityInspector<V, E> inspector = new StrongConnectivityInspector<V, E>(graph); List<Set<V>> components = inspector.stronglyConnectedSets(); // A vertex participates in a cycle if either of the following is // true: (a) it is in a component whose size is greater than 1 // or (b) it is a self-loop Set<V> set = new HashSet<V>(); for (Set<V> component : components) { if (component.size() > 1) { // cycle set.addAll(component); } else { V v = component.iterator().next(); if (graph.containsEdge(v, v)) { // self-loop set.add(v); } } } return set; }
public Set<String> getIndexedClasses() { Set<String> classes = newHashSet(); Set<JavaClass> vertexSet = graph.vertexSet(); for (JavaClass each : vertexSet) { classes.add(each.getName()); } return classes; }
private JavaClass findClass(String classname) { for (JavaClass jClass : graph.vertexSet()) { if (jClass.getName().equals(classname)) { return jClass; } } return null; }
// experimental // ==================================================================== // ==================================================================== // ==================================================================== private void readAndDrawBIGGraph(String file) { // behövs inte än // @TODO // hur rita flera linjer mellan 2 noder? (för flera linjer) // reading of the graph should be done in the graph itself // it should be possible to get an iterator over nodes and one over edges // read in all the stops and lines and draw the lmap Scanner indata = null; // insert into p-queue to get them sorted names = new PriorityQueue<String>(); try { // Read stops and put them in the node-table // in order to give the user a list of possible stops // assume input file is correct indata = new Scanner(new File(file + "-stops.txt"), "ISO-8859"); // while (indata.hasNext()) { String hpl = indata.next().trim(); int xco = indata.nextInt(); int yco = indata.nextInt(); noderna.add(new BusStop(hpl, xco, yco)); names.add(hpl); // Draw // this is a fix: fixa att Kålltorp och Torp är samma hållplats if (hpl.equals("Torp")) { xco += 11; hpl = " / Torp"; } karta.drawString(hpl, xco, yco, DrawGraph.Layer.BASE); } indata.close(); // Read in the lines and add to the graph indata = new Scanner(new File(file + "-lines.txt"), "ISO-8859"); grafen = new DirectedGraph<BusEdge>(noderna.noOfNodes()); Color color = new Color((float) Math.random(), (float) Math.random(), (float) Math.random()); // String lineNo = "1"; // while (indata.hasNext()) { // assume lines are correct int from = noderna.find(indata.next()).getNodeNo(); int to = noderna.find(indata.next()).getNodeNo(); grafen.addEdge(new BusEdge(from, to, indata.nextInt(), lineNo)); indata.nextLine(); // skip rest of line // Draw BusStop busFrom = noderna.find(from); BusStop busTo = noderna.find(to); karta.drawLine( busFrom.xpos, busFrom.ypos, busTo.xpos, busTo.ypos, color, 2.0f, DrawGraph.Layer.BASE); } indata.close(); } catch (FileNotFoundException fnfe) { throw new RuntimeException(" Indata till busshållplatserna saknas"); } karta.repaint(); } // end readAndDrawBIGGraph
/** @see GraphListener#edgeAdded(GraphEdgeChangeEvent) */ public void edgeAdded(GraphEdgeChangeEvent<V, E> e) { E edge = e.getEdge(); V source = graph.getEdgeSource(edge); V target = graph.getEdgeTarget(edge); // if a map does not already contain an entry, // then skip addNeighbor, since instantiating the map // will take care of processing the edge (which has already // been added) if (successorMap.containsKey(source)) { getSuccessors(source).addNeighbor(target); } else { getSuccessors(source); } if (predecessorMap.containsKey(target)) { getPredecessors(target).addNeighbor(source); } else { getPredecessors(target); } }
/** HG: measures time needed to check a pair of huge random graphs */ @Test public void testHugeGraph() { int n = 700; long time = System.currentTimeMillis(); DirectedGraph<Integer, DefaultEdge> g1 = SubgraphIsomorphismTestUtils.randomGraph(n, n * n / 50, 12345), g2 = SubgraphIsomorphismTestUtils.randomSubgraph(g1, n / 2, 54321); VF2SubgraphIsomorphismInspector<Integer, DefaultEdge> vf2 = new VF2SubgraphIsomorphismInspector<>(g1, g2); assertEquals(true, vf2.isomorphismExists()); SubgraphIsomorphismTestUtils.showLog( "|V1| = " + g1.vertexSet().size() + ", |E1| = " + g1.edgeSet().size() + ", |V2| = " + g2.vertexSet().size() + ", |E2| = " + g2.edgeSet().size() + " - " + (System.currentTimeMillis() - time) + "ms"); }
// ==================================================================== private void findShort() { // svårt att behålla linjefärgerna? int start, s**t; try { // read from station String str = from.getText(); str = Character.toUpperCase(str.charAt(0)) + str.substring(1); start = noderna.find(str).getNodeNo(); } catch (NullPointerException npe) { route.setText(felTextStart + "\n"); return; } try { // read to station String str = to.getText(); str = Character.toUpperCase(str.charAt(0)) + str.substring(1); s**t = noderna.find(str).getNodeNo(); } catch (NullPointerException npe) { route.setText(felTextSlut + "\n"); return; } double totWeight = 0; int totNodes = 0; route.setText(""); karta.clearLayer(DrawGraph.Layer.OVERLAY); Iterator<BusEdge> it = grafen.shortestPath(start, s**t); while (it.hasNext()) { BusEdge e = it.next(); route.append(makeText1(e) + "\n"); totNodes++; totWeight += e.getWeight(); // draw the shortest path BusStop from = noderna.find(e.from), to = noderna.find(e.to); karta.drawLine( from.xpos, from.ypos, to.xpos, to.ypos, Color.black, 4.0, DrawGraph.Layer.OVERLAY); } karta.repaint(); route.append("Antal: " + totNodes + " totalvikt: " + totWeight + "\n"); from.setText(""); to.setText(""); } // findShort
// ==================================================================== private void findMinSpan() { route.setText(""); Iterator<BusEdge> it = grafen.minimumSpanningTree(); if (it != null && it.hasNext()) { double totWeight = 0; int totNodes = 0; // only for easier testing karta.clearLayer(DrawGraph.Layer.OVERLAY); while (it.hasNext()) { BusEdge be = it.next(); totNodes++; totWeight += be.getWeight(); route.append(makeText2(be) + "\n"); // draw the MST BusStop from = noderna.find(be.from); BusStop to = noderna.find(be.to); karta.drawLine( from.xpos, from.ypos, to.xpos, to.ypos, Color.red, 2.5, DrawGraph.Layer.OVERLAY); } karta.repaint(); route.append("Antal: " + totNodes + " totalvikt: " + totWeight + "\n"); } else from.setText("Det fanns ej någon lösning"); to.setText(""); from.setText(""); } // findMinSpan
/** Tests edge cases on directed graphs */ @Test public void testEdgeCasesDirectedGraph() { /* ECD-1: graph and subgraph empty */ DirectedGraph<Integer, DefaultEdge> dg0v = new DefaultDirectedGraph<>(DefaultEdge.class), dg0v2 = new DefaultDirectedGraph<>(DefaultEdge.class); VF2SubgraphIsomorphismInspector<Integer, DefaultEdge> vf1 = new VF2SubgraphIsomorphismInspector<>(dg0v, dg0v2); assertEquals("[]", vf1.getMappings().next().toString()); /* ECD-2: graph non-empty, subgraph empty */ DirectedGraph<Integer, DefaultEdge> dg4v3e = new DefaultDirectedGraph<>(DefaultEdge.class); dg4v3e.addVertex(1); dg4v3e.addVertex(2); dg4v3e.addVertex(3); dg4v3e.addVertex(4); dg4v3e.addEdge(1, 2); dg4v3e.addEdge(3, 2); dg4v3e.addEdge(3, 4); VF2SubgraphIsomorphismInspector<Integer, DefaultEdge> vf2 = new VF2SubgraphIsomorphismInspector<>(dg4v3e, dg0v); assertEquals("[1=~~ 2=~~ 3=~~ 4=~~]", vf2.getMappings().next().toString()); /* ECD-3: graph empty, subgraph non-empty */ VF2SubgraphIsomorphismInspector<Integer, DefaultEdge> vf3 = new VF2SubgraphIsomorphismInspector<>(dg0v, dg4v3e); assertEquals(false, vf3.isomorphismExists()); /* ECD-4: graph non-empty, subgraph single vertex */ DirectedGraph<Integer, DefaultEdge> dg1v = new DefaultDirectedGraph<>(DefaultEdge.class); dg1v.addVertex(5); VF2SubgraphIsomorphismInspector<Integer, DefaultEdge> vf4 = new VF2SubgraphIsomorphismInspector<>(dg4v3e, dg1v); Iterator<GraphMapping<Integer, DefaultEdge>> iter4 = vf4.getMappings(); Set<String> mappings = new HashSet<>( Arrays.asList( "[1=5 2=~~ 3=~~ 4=~~]", "[1=~~ 2=5 3=~~ 4=~~]", "[1=~~ 2=~~ 3=5 4=~~]", "[1=~~ 2=~~ 3=~~ 4=5]")); assertEquals(true, mappings.remove(iter4.next().toString())); assertEquals(true, mappings.remove(iter4.next().toString())); assertEquals(true, mappings.remove(iter4.next().toString())); assertEquals(true, mappings.remove(iter4.next().toString())); assertEquals(false, iter4.hasNext()); /* ECD-5: graph empty, subgraph single vertex */ VF2SubgraphIsomorphismInspector<Integer, DefaultEdge> vf5 = new VF2SubgraphIsomorphismInspector<>(dg0v, dg1v); assertEquals(false, vf5.isomorphismExists()); /* ECD-6: subgraph with vertices, but no edges */ DirectedGraph<Integer, DefaultEdge> dg3v0e = new DefaultDirectedGraph<>(DefaultEdge.class); dg3v0e.addVertex(5); dg3v0e.addVertex(6); dg3v0e.addVertex(7); VF2SubgraphIsomorphismInspector<Integer, DefaultEdge> vf6 = new VF2SubgraphIsomorphismInspector<>(dg4v3e, dg3v0e); assertEquals(false, vf6.isomorphismExists()); /* ECD-7: graph and subgraph with vertices, but no edges */ DirectedGraph<Integer, DefaultEdge> dg2v0e = new DefaultDirectedGraph<>(DefaultEdge.class); dg2v0e.addVertex(1); dg2v0e.addVertex(2); VF2SubgraphIsomorphismInspector<Integer, DefaultEdge> vf7 = new VF2SubgraphIsomorphismInspector<>(dg3v0e, dg2v0e); Iterator<GraphMapping<Integer, DefaultEdge>> iter7 = vf7.getMappings(); Set<String> mappings7 = new HashSet<>( Arrays.asList( "[5=1 6=2 7=~~]", "[5=1 6=~~ 7=2]", "[5=2 6=1 7=~~]", "[5=~~ 6=1 7=2]", "[5=2 6=~~ 7=1]", "[5=~~ 6=2 7=1]")); assertEquals(true, mappings7.remove(iter7.next().toString())); assertEquals(true, mappings7.remove(iter7.next().toString())); assertEquals(true, mappings7.remove(iter7.next().toString())); assertEquals(true, mappings7.remove(iter7.next().toString())); assertEquals(true, mappings7.remove(iter7.next().toString())); assertEquals(true, mappings7.remove(iter7.next().toString())); assertEquals(false, iter7.hasNext()); /* ECD-8: graph no edges, subgraph contains single edge */ DirectedGraph<Integer, DefaultEdge> dg2v1e = new DefaultDirectedGraph<>(DefaultEdge.class); dg2v1e.addVertex(5); dg2v1e.addVertex(6); dg2v1e.addEdge(5, 6); VF2SubgraphIsomorphismInspector<Integer, DefaultEdge> vf8 = new VF2SubgraphIsomorphismInspector<>(dg3v0e, dg2v1e); assertEquals(false, vf8.isomorphismExists()); /* ECD-9: complete graphs of different size, * graph smaller than subgraph */ DirectedGraph<Integer, DefaultEdge> dg5c = new DefaultDirectedGraph<>(DefaultEdge.class); dg5c.addVertex(0); dg5c.addVertex(1); dg5c.addVertex(2); dg5c.addVertex(3); dg5c.addVertex(4); dg5c.addEdge(0, 1); dg5c.addEdge(0, 2); dg5c.addEdge(0, 3); dg5c.addEdge(0, 4); dg5c.addEdge(1, 2); dg5c.addEdge(1, 3); dg5c.addEdge(1, 4); dg5c.addEdge(2, 3); dg5c.addEdge(2, 4); dg5c.addEdge(3, 4); DirectedGraph<Integer, DefaultEdge> dg4c = new DefaultDirectedGraph<>(DefaultEdge.class); dg4c.addVertex(0); dg4c.addVertex(1); dg4c.addVertex(2); dg4c.addVertex(3); dg4c.addEdge(0, 1); dg4c.addEdge(0, 2); dg4c.addEdge(0, 3); dg4c.addEdge(1, 2); dg4c.addEdge(1, 3); dg4c.addEdge(2, 3); VF2SubgraphIsomorphismInspector<Integer, DefaultEdge> vf9 = new VF2SubgraphIsomorphismInspector<>(dg4c, dg5c); assertEquals(false, vf9.isomorphismExists()); /* ECD-10: complete graphs of different size, * graph bigger than subgraph */ VF2SubgraphIsomorphismInspector<Integer, DefaultEdge> vf10 = new VF2SubgraphIsomorphismInspector<>(dg5c, dg4c); Iterator<GraphMapping<Integer, DefaultEdge>> iter10 = vf10.getMappings(); Set<String> mappings10 = new HashSet<>( Arrays.asList( "[0=0 1=1 2=2 3=3 4=~~]", "[0=0 1=1 2=2 3=~~ 4=3]", "[0=0 1=1 2=~~ 3=2 4=3]", "[0=0 1=~~ 2=1 3=2 4=3]", "[0=~~ 1=0 2=1 3=2 4=3]")); assertEquals(true, mappings10.remove(iter10.next().toString())); assertEquals(true, mappings10.remove(iter10.next().toString())); assertEquals(true, mappings10.remove(iter10.next().toString())); assertEquals(true, mappings10.remove(iter10.next().toString())); assertEquals(true, mappings10.remove(iter10.next().toString())); assertEquals(false, iter10.hasNext()); /* ECD-11: isomorphic graphs */ VF2SubgraphIsomorphismInspector<Integer, DefaultEdge> vf11 = new VF2SubgraphIsomorphismInspector<>(dg4v3e, dg4v3e); Iterator<GraphMapping<Integer, DefaultEdge>> iter11 = vf11.getMappings(); assertEquals("[1=1 2=2 3=3 4=4]", iter11.next().toString()); assertEquals(false, iter11.hasNext()); /* ECD-12: not connected graphs of different size */ DirectedGraph<Integer, DefaultEdge> dg6v4enc = new DefaultDirectedGraph<>(DefaultEdge.class); dg6v4enc.addVertex(0); dg6v4enc.addVertex(1); dg6v4enc.addVertex(2); dg6v4enc.addVertex(3); dg6v4enc.addVertex(4); dg6v4enc.addVertex(5); dg6v4enc.addEdge(1, 2); dg6v4enc.addEdge(2, 3); dg6v4enc.addEdge(3, 1); dg6v4enc.addEdge(4, 5); DirectedGraph<Integer, DefaultEdge> dg5v4enc = new DefaultDirectedGraph<>(DefaultEdge.class); dg5v4enc.addVertex(6); dg5v4enc.addVertex(7); dg5v4enc.addVertex(8); dg5v4enc.addVertex(9); dg5v4enc.addVertex(10); dg5v4enc.addEdge(7, 6); dg5v4enc.addEdge(9, 8); dg5v4enc.addEdge(10, 9); dg5v4enc.addEdge(8, 10); VF2SubgraphIsomorphismInspector<Integer, DefaultEdge> vf12 = new VF2SubgraphIsomorphismInspector<>(dg6v4enc, dg5v4enc); Iterator<GraphMapping<Integer, DefaultEdge>> iter12 = vf12.getMappings(); Set<String> mappings12 = new HashSet<>( Arrays.asList( "[0=~~ 1=8 2=10 3=9 4=7 5=6]", "[0=~~ 1=9 2=8 3=10 4=7 5=6]", "[0=~~ 1=10 2=9 3=8 4=7 5=6]")); assertEquals(true, mappings12.remove(iter12.next().toString())); assertEquals(true, mappings12.remove(iter12.next().toString())); assertEquals(true, mappings12.remove(iter12.next().toString())); assertEquals(false, iter12.hasNext()); }
// ==================================================================== // ==================================================================== private void readAndDrawGraph() { // @TODO // hur rita flera linjer mellan 2 noder? (för flera linjer) // reading of the graph should be done in the graph itself // it should be possible to get an iterator over nodes and one over edges // read in all the stops and lines and draw the lmap Scanner indata = null; // insert into p-queue to get them sorted names = new PriorityQueue<String>(); try { // Read stops and put them in the node-table // in order to give the user a list of possible stops // assume input file is correct indata = new Scanner(new File("stops.noBOM.txt"), "UTF-8"); while (indata.hasNext()) { String hpl = indata.next().trim(); int xco = indata.nextInt(); int yco = indata.nextInt(); noderna.add(new BusStop(hpl, xco, yco)); names.add(hpl); // Draw /* // Denna fix som slår ihop Kålltorp och Torp är förvirrande eftersom de är olika noder i grafen. // Tror man att det är samma nod blir resultatet förrvirrande. // Till nästa gång: Gör till samma nod med namnet Virginsgatan. Så är det i verkligheten nu. // this is a fix: fixa att Kålltorp och Torp är samma hållplats if ( hpl.equals("Torp") ) { xco += 11; hpl = " / Torp"; } */ karta.drawString(hpl, xco, yco, DrawGraph.Layer.BASE); } indata.close(); // Read in the lines and add to the graph indata = new Scanner(new File("lines.noBOM.txt"), "UTF-8"); grafen = new DirectedGraph<BusEdge>(noderna.noOfNodes()); while (indata.hasNext()) { String lineNo = indata.next(); int antal = indata.nextInt() - 1; int from = noderna.find(indata.next()).getNodeNo(); // hur rita flera linjer mellan 2 noder? // enkel inc fungerar inte // färgen kunde vara "äkta" dvs linjefärg Color color = new Color((float) Math.random(), (float) Math.random(), (float) Math.random()); for (int i = 0; i < antal; i++) { int to = noderna.find(indata.next()).getNodeNo(); grafen.addEdge(new BusEdge(from, to, indata.nextInt(), lineNo)); // Draw BusStop busFrom = noderna.find(from); BusStop busTo = noderna.find(to); karta.drawLine( busFrom.xpos, busFrom.ypos, busTo.xpos, busTo.ypos, color, 2.0f, DrawGraph.Layer.BASE); from = to; } } indata.close(); } catch (FileNotFoundException fnfe) { throw new RuntimeException(" Indata till busshållplatserna saknas"); } karta.repaint(); } // end readAndDrawGraph
private void addToGraph(JavaClass newClass) { if (!graph.addVertex(newClass)) { replaceVertex(newClass); } }
/** @see CrossComponentIterator.Specifics#edgesOf(Object) */ public Set<? extends EE> edgesOf(VV vertex) { return graph.outgoingEdgesOf(vertex); }
@Test public void testExhaustive() { /* DET-1: * * 0 3 * | /| 0 2 * g1 = | 2 | g2 = |/ * |/ | 1 * 1 4 */ SimpleGraph<Integer, DefaultEdge> g1 = new SimpleGraph<>(DefaultEdge.class), g2 = new SimpleGraph<>(DefaultEdge.class); g1.addVertex(0); g1.addVertex(1); g1.addVertex(2); g1.addVertex(3); g1.addVertex(4); g2.addVertex(0); g2.addVertex(1); g2.addVertex(2); g1.addEdge(0, 1); g1.addEdge(1, 2); g1.addEdge(2, 3); g1.addEdge(3, 4); g2.addEdge(0, 1); g2.addEdge(1, 2); VF2SubgraphIsomorphismInspector<Integer, DefaultEdge> vf2 = new VF2SubgraphIsomorphismInspector<>(g1, g2); assertEquals(true, SubgraphIsomorphismTestUtils.containsAllMatchings(vf2, g1, g2)); /* DET-2: * * g3 = ... g4 = ... * */ DirectedGraph<Integer, DefaultEdge> g3 = new DefaultDirectedGraph<>(DefaultEdge.class), g4 = new DefaultDirectedGraph<>(DefaultEdge.class); g3.addVertex(0); g3.addVertex(1); g3.addVertex(2); g3.addVertex(3); g3.addVertex(4); g3.addVertex(5); g4.addVertex(0); g4.addVertex(1); g4.addVertex(2); g4.addVertex(3); g3.addEdge(0, 1); g3.addEdge(0, 5); g3.addEdge(1, 4); g3.addEdge(2, 1); g3.addEdge(2, 4); g3.addEdge(3, 1); g3.addEdge(4, 0); g3.addEdge(5, 2); g3.addEdge(5, 4); g4.addEdge(0, 3); g4.addEdge(1, 2); g4.addEdge(1, 3); g4.addEdge(2, 3); g4.addEdge(2, 0); VF2SubgraphIsomorphismInspector<Integer, DefaultEdge> vf3 = new VF2SubgraphIsomorphismInspector<>(g3, g4); assertEquals(true, SubgraphIsomorphismTestUtils.containsAllMatchings(vf3, g3, g4)); /* DET-3: * * 1----0 0---2 * | | / * g5 = | g6 = | / * | |/ * 2----3 1 */ SimpleGraph<Integer, DefaultEdge> g5 = new SimpleGraph<>(DefaultEdge.class), g6 = new SimpleGraph<>(DefaultEdge.class); g5.addVertex(0); g5.addVertex(1); g5.addVertex(2); g5.addVertex(3); g6.addVertex(0); g6.addVertex(1); g6.addVertex(2); g5.addEdge(0, 1); g5.addEdge(1, 2); g5.addEdge(2, 3); g6.addEdge(0, 1); g6.addEdge(1, 2); g6.addEdge(2, 0); VF2SubgraphIsomorphismInspector<Integer, DefaultEdge> vf4 = new VF2SubgraphIsomorphismInspector<>(g5, g6); assertEquals(true, SubgraphIsomorphismTestUtils.containsAllMatchings(vf4, g5, g6)); }
/** * Tests graph types: In case of invalid graph types or invalid combination of graph arguments * UnsupportedOperationException or InvalidArgumentException is expected */ @Test public void testGraphTypes() { DirectedGraph<Integer, DefaultEdge> dg1 = new DefaultDirectedGraph<>(DefaultEdge.class); dg1.addVertex(1); dg1.addVertex(2); dg1.addEdge(1, 2); SimpleGraph<Integer, DefaultEdge> sg1 = new SimpleGraph<>(DefaultEdge.class); sg1.addVertex(1); sg1.addVertex(2); sg1.addEdge(1, 2); Multigraph<Integer, DefaultEdge> mg1 = new Multigraph<>(DefaultEdge.class); mg1.addVertex(1); mg1.addVertex(2); mg1.addEdge(1, 2); Pseudograph<Integer, DefaultEdge> pg1 = new Pseudograph<>(DefaultEdge.class); pg1.addVertex(1); pg1.addVertex(2); pg1.addEdge(1, 2); /* GT-0 test graph=null */ try { @SuppressWarnings("unused") VF2SubgraphIsomorphismInspector<Integer, DefaultEdge> gt0 = new VF2SubgraphIsomorphismInspector<>(null, sg1); Assert.fail("Expected UnsupportedOperationException"); } catch (NullPointerException ex) { } /* GT-1: multigraphs */ try { @SuppressWarnings("unused") VF2SubgraphIsomorphismInspector<Integer, DefaultEdge> gt1 = new VF2SubgraphIsomorphismInspector<>(mg1, mg1); Assert.fail("Expected UnsupportedOperationException"); } catch (UnsupportedOperationException ex) { } /* GT-2: pseudographs */ try { @SuppressWarnings("unused") VF2SubgraphIsomorphismInspector<Integer, DefaultEdge> gt2 = new VF2SubgraphIsomorphismInspector<>(pg1, pg1); Assert.fail("Expected UnsupportedOperationException"); } catch (UnsupportedOperationException ex) { } /* GT-3: simple graphs */ VF2SubgraphIsomorphismInspector<Integer, DefaultEdge> gt3 = new VF2SubgraphIsomorphismInspector<>(sg1, sg1); assertEquals(true, gt3.getMappings().hasNext()); /* GT-4: directed graphs */ VF2SubgraphIsomorphismInspector<Integer, DefaultEdge> gt4 = new VF2SubgraphIsomorphismInspector<>(dg1, dg1); assertEquals("[1=1 2=2]", gt4.getMappings().next().toString()); /* GT-5: simple graph + multigraph */ try { @SuppressWarnings("unused") VF2SubgraphIsomorphismInspector<Integer, DefaultEdge> gt5 = new VF2SubgraphIsomorphismInspector<>(sg1, mg1); Assert.fail("Expected UnsupportedOperationException"); } catch (UnsupportedOperationException ex) { } /* GT-6: simple graph + pseudograph */ try { @SuppressWarnings("unused") VF2SubgraphIsomorphismInspector<Integer, DefaultEdge> gt6 = new VF2SubgraphIsomorphismInspector<>(sg1, pg1); Assert.fail("Expected UnsupportedOperationException"); } catch (UnsupportedOperationException ex) { } /* GT-7: directed graph + multigraph */ try { @SuppressWarnings("unused") VF2SubgraphIsomorphismInspector<Integer, DefaultEdge> gt7 = new VF2SubgraphIsomorphismInspector<>(dg1, mg1); Assert.fail("Expected UnsupportedOperationException"); } catch (UnsupportedOperationException ex) { } /* GT-8: directed graph + pseudograph */ try { @SuppressWarnings("unused") VF2SubgraphIsomorphismInspector<Integer, DefaultEdge> gt8 = new VF2SubgraphIsomorphismInspector<>(dg1, pg1); Assert.fail("Expected UnsupportedOperationException"); } catch (UnsupportedOperationException ex) { } /* GT-9: pseudograph + multigraph */ try { @SuppressWarnings("unused") VF2SubgraphIsomorphismInspector<Integer, DefaultEdge> gt9 = new VF2SubgraphIsomorphismInspector<>(pg1, mg1); Assert.fail("Expected UnsupportedOperationException"); } catch (UnsupportedOperationException ex) { } /* GT-10: simple graph + directed graph */ try { @SuppressWarnings("unused") VF2SubgraphIsomorphismInspector<Integer, DefaultEdge> gt10 = new VF2SubgraphIsomorphismInspector<>(sg1, dg1); Assert.fail("Expected IllegalArgumentException"); } catch (IllegalArgumentException ex) { } }