/* * 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; import edu.uci.ics.jung.graph.UndirectedGraph; /** * Generates a random graph using the Erdos-Renyi binomial model (each pair of * vertices is connected with probability p). * * @author William Giordano, Scott White, Joshua O'Madadhain */ public class ErdosRenyiGenerator<V, E> implements GraphGenerator<V, E> { private int mNumVertices; private double mEdgeConnectionProbability; private Random mRandom; Factory<UndirectedGraph<V, E>> graphFactory; Factory<V> vertexFactory; Factory<E> edgeFactory; /** * * @param numVertices * number of vertices graph should have * @param p * Connection's probability between 2 vertices */ public ErdosRenyiGenerator(Factory<UndirectedGraph<V, E>> graphFactory, Factory<V> vertexFactory, Factory<E> edgeFactory, int numVertices, double p) { if (numVertices <= 0) { throw new IllegalArgumentException( "A positive # of vertices must be specified."); } mNumVertices = numVertices; if (p < 0 || p > 1) { throw new IllegalArgumentException("p must be between 0 and 1."); } this.graphFactory = graphFactory; this.vertexFactory = vertexFactory; this.edgeFactory = edgeFactory; mEdgeConnectionProbability = p; mRandom = new Random(); } /** * Returns a graph in which each pair of vertices is connected by an * undirected edge with the probability specified by the constructor. */ @Override public Graph<V, E> create() { UndirectedGraph<V, E> g = graphFactory.create(); for (int i = 0; i < mNumVertices; i++) { g.addVertex(vertexFactory.create()); } List<V> list = new ArrayList<V>(g.getVertices()); for (int i = 0; i < mNumVertices - 1; i++) { V v_i = list.get(i); for (int j = i + 1; j < mNumVertices; j++) { V v_j = list.get(j); if (mRandom.nextDouble() < mEdgeConnectionProbability) { g.addEdge(edgeFactory.create(), v_i, v_j); } } } return g; } /** * Sets the seed of the internal random number generator to {@code seed}. * Enables consistent behavior. */ public void setSeed(long seed) { mRandom.setSeed(seed); } }