+++ /dev/null
-/*
-* Copyright (c) 2003, the JUNG Project and the Regents of the University
-* of California
-* All rights reserved.
-*
-* This software is open-source under the BSD license; see either
-* "license.txt" or
-* http://jung.sourceforge.net/license.txt for a description.
-*/
-package edu.uci.ics.jung.algorithms.generators.random;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Random;
-
-import org.apache.commons.collections15.Factory;
-
-import edu.uci.ics.jung.algorithms.generators.GraphGenerator;
-import edu.uci.ics.jung.graph.Graph;
-
-/**
- * Graph generator that generates undirected graphs with power-law degree distributions.
- * @author Scott White
- * @see "A Steady State Model for Graph Power Law by David Eppstein and Joseph Wang"
- */
-public class EppsteinPowerLawGenerator<V,E> implements GraphGenerator<V,E> {
- private int mNumVertices;
- private int mNumEdges;
- private int mNumIterations;
- private double mMaxDegree;
- private Random mRandom;
- private Factory<Graph<V,E>> graphFactory;
- private Factory<V> vertexFactory;
- private Factory<E> edgeFactory;
-
- /**
- * Creates an instance with the specified factories and specifications.
- * @param graphFactory the factory to use to generate the graph
- * @param vertexFactory the factory to use to create vertices
- * @param edgeFactory the factory to use to create edges
- * @param numVertices the number of vertices for the generated graph
- * @param numEdges the number of edges the generated graph will have, should be Theta(numVertices)
- * @param r the number of iterations to use; the larger the value the better the graph's degree
- * distribution will approximate a power-law
- */
- public EppsteinPowerLawGenerator(Factory<Graph<V,E>> graphFactory,
- Factory<V> vertexFactory, Factory<E> edgeFactory,
- int numVertices, int numEdges, int r) {
- this.graphFactory = graphFactory;
- this.vertexFactory = vertexFactory;
- this.edgeFactory = edgeFactory;
- mNumVertices = numVertices;
- mNumEdges = numEdges;
- mNumIterations = r;
- mRandom = new Random();
- }
-
- protected Graph<V,E> initializeGraph() {
- Graph<V,E> graph = null;
- graph = graphFactory.create();
- for(int i=0; i<mNumVertices; i++) {
- graph.addVertex(vertexFactory.create());
- }
- List<V> vertices = new ArrayList<V>(graph.getVertices());
- while (graph.getEdgeCount() < mNumEdges) {
- V u = vertices.get((int) (mRandom.nextDouble() * mNumVertices));
- V v = vertices.get((int) (mRandom.nextDouble() * mNumVertices));
- if (!graph.isSuccessor(v,u)) {
- graph.addEdge(edgeFactory.create(), u, v);
- }
- }
-
- double maxDegree = 0;
- for (V v : graph.getVertices()) {
- maxDegree = Math.max(graph.degree(v),maxDegree);
- }
- mMaxDegree = maxDegree; //(maxDegree+1)*(maxDegree)/2;
-
- return graph;
- }
-
- /**
- * Generates a graph whose degree distribution approximates a power-law.
- * @return the generated graph
- */
- public Graph<V,E> create() {
- Graph<V,E> graph = initializeGraph();
-
- List<V> vertices = new ArrayList<V>(graph.getVertices());
- for (int rIdx = 0; rIdx < mNumIterations; rIdx++) {
-
- V v = null;
- int degree = 0;
- do {
- v = vertices.get((int) (mRandom.nextDouble() * mNumVertices));
- degree = graph.degree(v);
-
- } while (degree == 0);
-
- List<E> edges = new ArrayList<E>(graph.getIncidentEdges(v));
- E randomExistingEdge = edges.get((int) (mRandom.nextDouble()*degree));
-
- // FIXME: look at email thread on a more efficient RNG for arbitrary distributions
-
- V x = vertices.get((int) (mRandom.nextDouble() * mNumVertices));
- V y = null;
- do {
- y = vertices.get((int) (mRandom.nextDouble() * mNumVertices));
-
- } while (mRandom.nextDouble() > ((graph.degree(y)+1)/mMaxDegree));
-
- if (!graph.isSuccessor(y,x) && x != y) {
- graph.removeEdge(randomExistingEdge);
- graph.addEdge(edgeFactory.create(), x, y);
- }
- }
-
- return graph;
- }
-
- /**
- * Sets the seed for the random number generator.
- * @param seed input to the random number generator.
- */
- public void setSeed(long seed) {
- mRandom.setSeed(seed);
- }
-}