/** 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");
  }
  /** RG-1: Tests if a all matchings are correct (on some random graphs). */
  @Test
  public void testRandomGraphs() {
    Random rnd = new Random();
    rnd.setSeed(54321);

    for (int i = 1; i < 50; i++) {
      int vertexCount = 2 + rnd.nextInt(i),
          edgeCount = vertexCount + rnd.nextInt(vertexCount * (vertexCount - 1)) / 2,
          subVertexCount = 1 + rnd.nextInt(vertexCount);

      DirectedGraph<Integer, DefaultEdge>
          g1 = SubgraphIsomorphismTestUtils.randomGraph(vertexCount, edgeCount, i),
          g2 = SubgraphIsomorphismTestUtils.randomSubgraph(g1, subVertexCount, i);

      VF2SubgraphIsomorphismInspector<Integer, DefaultEdge> vf2 =
          new VF2SubgraphIsomorphismInspector<>(g1, g2);

      SubgraphIsomorphismTestUtils.showLog(i + ": " + vertexCount + "v, " + edgeCount + "e ");

      for (Iterator<GraphMapping<Integer, DefaultEdge>> mappings = vf2.getMappings();
          mappings.hasNext(); ) {
        assertEquals(true, SubgraphIsomorphismTestUtils.isCorrectMatching(mappings.next(), g1, g2));
        SubgraphIsomorphismTestUtils.showLog(".");
      }
      SubgraphIsomorphismTestUtils.showLog("\n");
    }
  }
  /** RG-2: Tests if all matchings are correct and if every matching is found (on random graphs). */
  @Test
  public void testRandomGraphsExhaustive() {
    Random rnd = new Random();
    rnd.setSeed(12345);

    for (int i = 1; i < 100; i++) {
      int vertexCount = 3 + rnd.nextInt(5),
          edgeCount = rnd.nextInt(vertexCount * (vertexCount - 1)),
          subVertexCount = 2 + rnd.nextInt(vertexCount),
          subEdgeCount = rnd.nextInt(subVertexCount * (subVertexCount - 1));

      DirectedGraph<Integer, DefaultEdge>
          g1 = SubgraphIsomorphismTestUtils.randomGraph(vertexCount, edgeCount, i),
          g2 = SubgraphIsomorphismTestUtils.randomGraph(subVertexCount, subEdgeCount, i);

      VF2SubgraphIsomorphismInspector<Integer, DefaultEdge> vf2 =
          new VF2SubgraphIsomorphismInspector<>(g1, g2);

      SubgraphIsomorphismTestUtils.showLog(i + ": " + vertexCount + "v, " + edgeCount + "e ....\n");

      assertEquals(true, SubgraphIsomorphismTestUtils.containsAllMatchings(vf2, g1, g2));
    }
  }
  @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));
  }