Package net.wigis.graph.dnv.utilities

Source Code of net.wigis.graph.dnv.utilities.BarabasiAlbertGenerator

package net.wigis.graph.dnv.utilities;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Random;

import net.wigis.graph.dnv.DNVEdge;
import net.wigis.graph.dnv.DNVGraph;
import net.wigis.graph.dnv.DNVNode;
import net.wigis.yun.Pair;

public class BarabasiAlbertGenerator {
  private DNVGraph mGraph = null;
    private int mNumEdgesToAttachPerStep;
    private int mElapsedTimeSteps;
    private Random mRandom;
    protected int init_vertices;
    protected List<DNVNode> vertex_index;
   
    /*protected Map<DNVNode, Integer> index_vertex;*/
   
    /**
     * Constructs a new instance of the generator.
     * @param init_vertices     number of unconnected 'seed' vertices that the graph should start with
     * @param numEdgesToAttach the number of edges that should be attached from the
     * new vertex to pre-existing vertices at each time step
     * @param directed  specifies whether the graph and edges to be created should be directed or not
     * @param parallel  specifies whether the algorithm permits parallel edges
     * @param seed  random number seed
     */
    public BarabasiAlbertGenerator(int init_vertices, int numEdgesToAttach, int seed) {
        assert init_vertices > 0 : "Number of initial unconnected 'seed' vertices "
                + "must be positive";
        assert numEdgesToAttach > 0 : "Number of edges to attach "
                + "at each time step must be positive";

        mNumEdgesToAttachPerStep = numEdgesToAttach;
        mRandom = new Random(seed);
        this .init_vertices = init_vertices;
        initialize();
    }

    /**
     * Constructs a new instance of the generator, whose output will be an undirected graph,
     * and which will use the current time as a seed for the random number generation.
     * @param init_vertices     number of vertices that the graph should start with
     * @param numEdgesToAttach the number of edges that should be attached from the
     * new vertex to pre-existing vertices at each time step
     */
    public BarabasiAlbertGenerator(int init_vertices, int numEdgesToAttach) {
        this (init_vertices, numEdgesToAttach, (int) System.currentTimeMillis());
    }
    private void initialize() {

        mGraph = new DNVGraph();
       

        vertex_index = new ArrayList<DNVNode>(2 * init_vertices);
        //index_vertex = new HashMap<DNVNode, Integer>(2 * init_vertices);
        for (int i = 0; i < init_vertices; i++) {
            DNVNode node = new DNVNode(mGraph);
            mGraph.addNode(0, node);
            vertex_index.add(node);
            //index_vertex.put(node, i);
        }

        mElapsedTimeSteps = 0;
    }
    private void createRandomEdge(List<DNVNode> preexistingNodes,
      DNVNode newNode, HashSet<Pair<DNVNode, DNVNode>> added_pairs) {
      DNVNode attach_point;
        boolean created_edge = false;
        Pair<DNVNode, DNVNode> endpoints;
        do {
            attach_point = vertex_index.get(mRandom
                    .nextInt(vertex_index.size()));

            endpoints = new Pair<DNVNode, DNVNode>(newNode, attach_point);

            // if parallel edges are not allowed, skip attach_point if <newNode, attach_point>
            // already exists; note that because of the way edges are added, we only need to check
            // the list of candidate edges for duplicates.
            if (added_pairs.contains(endpoints) || added_pairs.contains(new Pair<DNVNode, DNVNode>(attach_point, newNode)))
              continue;

            double degree = attach_point.getDegree();

            // subtract 1 from numVertices because we don't want to count newNode
            // (which has already been added to the graph, but not to vertex_index)
            double attach_prob = (degree + 1)
                    / (mGraph.getEdges().size() + mGraph.getNodes(0).size() - 1);
            if (attach_prob >= mRandom.nextDouble())
                created_edge = true;
        } while (!created_edge);

        added_pairs.add(endpoints);

        added_pairs.add(new Pair<DNVNode, DNVNode>(attach_point, newNode));
    }

    public void evolveGraph(int numTimeSteps) {

        for (int i = 0; i < numTimeSteps; i++) {
            evolveGraph();
            mElapsedTimeSteps++;
            System.out.println("finish evolve step " + i);
        }
    }

    private void evolveGraph() {
        List<DNVNode> preexistingNodes = mGraph.getNodes(0);
        DNVNode newNode = new DNVNode(mGraph);

        mGraph.addNode(0, newNode);

        // generate and store the new edges; don't add them to the graph
        // yet because we don't want to bias the degree calculations
        // (all new edges in a timestep should be added in parallel)
        HashSet<Pair<DNVNode, DNVNode>> added_pairs = new HashSet<Pair<DNVNode, DNVNode>>(
                mNumEdgesToAttachPerStep * 3);

        for (int i = 0; i < mNumEdgesToAttachPerStep; i++)
            createRandomEdge(preexistingNodes, newNode, added_pairs);

        for (Pair<DNVNode, DNVNode> pair : added_pairs) {
          DNVNode v1 = pair.getFirst();
          DNVNode v2 = pair.getSecond();
            if (!v1.getNeighbors().contains(v2)){
              DNVEdge edge = new DNVEdge(mGraph);
              edge.setFrom(v1);
              edge.setTo(v2);
                mGraph.addEdge(0, edge);
            }
        }
        // now that we're done attaching edges to this new vertex,
        // add it to the index
        vertex_index.add(newNode);
        //index_vertex.put(newNode,
        //        new Integer(vertex_index.size() - 1));
    }

    public int numIterations() {
        return mElapsedTimeSteps;
    }

    public DNVGraph create() {
        return mGraph;
    }
   
    public static void main(String[] args){
      BarabasiAlbertGenerator bsg = new BarabasiAlbertGenerator(500,10);
      bsg.evolveGraph(500);
      DNVGraph graph = bsg.create();
      graph.writeGraph("/Users/scarlettteng/dev/bs1000_5000graph.dnv");
    }
}
TOP

Related Classes of net.wigis.graph.dnv.utilities.BarabasiAlbertGenerator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.