001/*
002 * Copyright 2006 - 2013
003 *     Stefan Balev     <stefan.balev@graphstream-project.org>
004 *     Julien Baudry    <julien.baudry@graphstream-project.org>
005 *     Antoine Dutot    <antoine.dutot@graphstream-project.org>
006 *     Yoann Pigné      <yoann.pigne@graphstream-project.org>
007 *     Guilhelm Savin   <guilhelm.savin@graphstream-project.org>
008 * 
009 * This file is part of GraphStream <http://graphstream-project.org>.
010 * 
011 * GraphStream is a library whose purpose is to handle static or dynamic
012 * graph, create them from scratch, file or any source and display them.
013 * 
014 * This program is free software distributed under the terms of two licenses, the
015 * CeCILL-C license that fits European law, and the GNU Lesser General Public
016 * License. You can  use, modify and/ or redistribute the software under the terms
017 * of the CeCILL-C license as circulated by CEA, CNRS and INRIA at the following
018 * URL <http://www.cecill.info> or under the terms of the GNU LGPL as published by
019 * the Free Software Foundation, either version 3 of the License, or (at your
020 * option) any later version.
021 * 
022 * This program is distributed in the hope that it will be useful, but WITHOUT ANY
023 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
024 * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
025 * 
026 * You should have received a copy of the GNU Lesser General Public License
027 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
028 * 
029 * The fact that you are presently reading this means that you have had
030 * knowledge of the CeCILL-C and LGPL licenses and that you accept their terms.
031 */
032package org.graphstream.algorithm.generator;
033
034import java.util.Random;
035
036import org.graphstream.algorithm.Toolkit;
037import org.graphstream.graph.Edge;
038
039/**
040 * Dorogovtsev - Mendes graph generator.
041 * 
042 * <p>
043 * This generator creates graph using the Dorogovtsev - Mendes algorithm. This
044 * starts by creating three nodes and tree edges, making a triangle, and then
045 * add one node at a time. Each time a node is added, an edge is chosen randomly
046 * and the node is connected via two new edges to the two extremities of the
047 * chosen edge.
048 * </p>
049 * 
050 * <p>
051 * This process generates a power-low degree distribution, as nodes that have
052 * more edges have more chances to be selected since their edges are more
053 * represented in the edge set.
054 * </p>
055 * 
056 * <p>
057 * The Dorogovtsev - Mendes algorithm always produce planar graphs.
058 * </p>
059 * 
060 * <h2>Usage</h2>
061 * 
062 * <p>
063 * The more this generator is iterated, the more nodes are generated. It can
064 * therefore generate trees of any size. A each call to {@link #nextEvents()},
065 * a new node and two edges are added.
066 * </p>
067 * 
068 * <h2>Complexity</h2>
069 * 
070 * At each step only one node and two edges are added.
071 * 
072 * <h2>Example</h2>
073 * 
074 * <pre>
075 * Graph graph = new SingleGraph("Dorogovtsev mendes");
076 * Generator gen = new DorogovtsevMendesGenerator();
077 * gen.addSink(graph);
078 * gen.begin();
079 * for(int i=0; i<100; i++) {
080 *              gen.nextEvents();
081 * }
082 * gen.end();
083 * graph.display();
084 * </pre>
085 * 
086 * <h2>References</h2>
087 * 
088 * <p>
089 * This kind of graph is described, among others, in the "Evolution of networks"
090 * by Dorogovtsev and Mendes.
091 * </p>
092 * 
093 * @reference S. N. Dorogovtsev and J. F. F. Mendes, "Evolution of networks", in
094 *            Adv. Phys. 51, 2002, 1079--1187, 
095 *                        arXiv:cond-mat/0106144v2
096 * 
097 * @since 20070117
098 */
099public class DorogovtsevMendesGenerator extends BaseGenerator {
100        /**
101         * Used to generate node names.
102         */
103        protected int nodeNames = 0;
104
105        /**
106         * Create a new generator with default random object.
107         */
108        public DorogovtsevMendesGenerator() {
109                setUseInternalGraph(true);
110        }
111
112        /**
113         * New generator with the given random number generator.
114         * 
115         * @param random
116         *            The number generator to use.
117         */
118        public DorogovtsevMendesGenerator(Random random) {
119                this();
120
121                this.random = random;
122        }
123
124        /**
125         * Init the generator. An initial full graph of three nodes is build here.
126         * 
127         * @see org.graphstream.algorithm.generator.Generator#begin()
128         */
129        public void begin() {
130                this.random = this.random == null ? new Random(
131                                System.currentTimeMillis()) : this.random;
132
133                addNode("0");
134                addNode("1");
135                addNode("2");
136
137                addEdge("0-1", "0", "1");
138                addEdge("1-2", "1", "2");
139                addEdge("2-0", "2", "0");
140
141                nodeNames = 3;
142        }
143
144        /**
145         * Step of the DorogovtsevMendes generator. Add a new node <i>n</i>, then an
146         * edge is chosen randomly and its extremities are connected to the new node
147         * <i>n</i>.
148         * 
149         * @see org.graphstream.algorithm.generator.Generator#nextEvents()
150         */
151        public boolean nextEvents() {
152                String name = Integer.toString(nodeNames++);
153                Edge edge = Toolkit.randomEdge(internalGraph, random);
154                String n0 = edge.getNode0().getId();
155                String n1 = edge.getNode1().getId();
156
157                addNode(name);
158
159                addEdge(n0 + "-" + name, n0, name);
160                addEdge(n1 + "-" + name, n1, name);
161
162                return true;
163        }
164
165        /*
166         * (non-Javadoc)
167         * 
168         * @see org.graphstream.algorithm.generator.Generator#end()
169         */
170        @Override
171        public void end() {
172                super.end();
173        }
174}