EppsteinPowerLawGenerator.java :  » Science » jung-2-2_0_1 » edu » uci » ics » jung » algorithms » generators » random » Java Open Source

Java Open Source » Science » jung 2 2_0_1 
jung 2 2_0_1 » edu » uci » ics » jung » algorithms » generators » random » EppsteinPowerLawGenerator.java
/*
* 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);
    }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.