public G generate(int N, int k, double p) {
    G graph = ringLatticeGenerator.generate(N, k);

    Set<Edge> edges = new HashSet<Edge>();
    for (Edge edge : graph.getEdges()) {
      if (random.nextDouble() < p) {
        edges.add(edge);
      }
    }

    List<V> vertices = new ArrayList<V>(graph.getVertices().size());
    vertices.addAll((Collection<? extends V>) graph.getVertices());

    int doubleEdges = 0;

    for (Edge edge : edges) {
      V source;

      if (random.nextBoolean()) {
        source = (V) edge.getVertices().getFirst();
      } else {
        source = (V) edge.getVertices().getSecond();
      }

      builder.removeEdge(graph, (E) edge);
      V target = null;
      while (target == null) {
        target = vertices.get(random.nextInt(vertices.size()));
        if (source == target) target = null;
      }

      if (builder.addEdge(graph, source, target) == null) doubleEdges++;
    }

    logger.debug(String.format("Rejected %1$s double edges.", doubleEdges));

    return graph;
  }
  @SuppressWarnings("unchecked")
  private G randomDraw(G graph, double p, long randomSeed) {
    long n = graph.getVertices().size();
    long M = n * (n - 1) / 2;
    int m = (int) (p * M);

    Random random = new Random(randomSeed);
    List<V> vertices = new ArrayList<V>((Collection<? extends V>) graph.getVertices());
    ProgressLogger.init(m, 1, 5);
    for (int i = 0; i < m; i++) {
      E edge = null;
      while (edge == null) {
        V vi = vertices.get(random.nextInt((int) n));
        V vj = vertices.get(random.nextInt((int) n));
        edge = builder.addEdge(graph, vi, vj);
      }
      ProgressLogger.step();
      //			if(i % 10000 == 0)
      //				logger.info(String.format("Created %1$s of %2$s edges.", i+1, m));
    }
    ProgressLogger.termiante();
    return graph;
  }