示例#1
-1
  /**
   * Generates a synthetic network for provided vertices in the given graphh such that the provided
   * expected number of communities are generated with the specified expected number of edges.
   *
   * @param graph
   * @param vertices
   * @param expectedNumCommunities
   * @param expectedNumEdges
   * @return The actual number of edges generated. May be different from the expected number.
   */
  public int generate(
      Graph graph, Iterable<Vertex> vertices, int expectedNumCommunities, int expectedNumEdges) {
    if (communitySize == null)
      throw new IllegalStateException("Need to initialize community size distribution");
    if (edgeDegree == null)
      throw new IllegalStateException("Need to initialize degree distribution");
    int numVertices = SizableIterable.sizeOf(vertices);
    Iterator<Vertex> iter = vertices.iterator();
    ArrayList<ArrayList<Vertex>> communities =
        new ArrayList<ArrayList<Vertex>>(expectedNumCommunities);
    Distribution communityDist = communitySize.initialize(expectedNumCommunities, numVertices);
    while (iter.hasNext()) {
      int nextSize = communityDist.nextValue(random);
      ArrayList<Vertex> community = new ArrayList<Vertex>(nextSize);
      for (int i = 0; i < nextSize && iter.hasNext(); i++) {
        community.add(iter.next());
      }
      if (!community.isEmpty()) communities.add(community);
    }

    double inCommunityPercentage = 1.0 - crossCommunityPercentage;
    Distribution degreeDist = edgeDegree.initialize(numVertices, expectedNumEdges);
    if (crossCommunityPercentage > 0 && communities.size() < 2)
      throw new IllegalArgumentException("Cannot have cross links with only one community");
    int addedEdges = 0;

    // System.out.println("Generating links on communities: "+communities.size());

    for (ArrayList<Vertex> community : communities) {
      for (Vertex v : community) {
        int degree = degreeDist.nextValue(random);
        degree =
            Math.min(degree, (int) Math.ceil((community.size() - 1) / inCommunityPercentage) - 1);
        Set<Vertex> inlinks = new HashSet<Vertex>();
        for (int i = 0; i < degree; i++) {
          Vertex selected = null;
          if (random.nextDouble() < crossCommunityPercentage
              || (community.size() - 1 <= inlinks.size())) {
            // Cross community
            ArrayList<Vertex> othercomm = null;
            while (othercomm == null) {
              othercomm = communities.get(random.nextInt(communities.size()));
              if (othercomm.equals(community)) othercomm = null;
            }
            selected = othercomm.get(random.nextInt(othercomm.size()));
          } else {
            // In community
            while (selected == null) {
              selected = community.get(random.nextInt(community.size()));
              if (v.equals(selected) || inlinks.contains(selected)) selected = null;
            }
            inlinks.add(selected);
          }
          addEdge(graph, v, selected);
          addedEdges++;
        }
      }
    }
    return addedEdges;
  }