All Downloads are FREE. Search and download functionalities are using the official Maven repository.

apoc.generate.relationship.WattsStrogatzRelationshipGenerator Maven / Gradle / Ivy

package apoc.generate.relationship;

import apoc.generate.config.WattsStrogatzConfig;
import org.apache.commons.lang3.tuple.Pair;

import java.util.*;

/**
 * Watts-Strogatz model implementation.
 */
public class WattsStrogatzRelationshipGenerator extends BaseRelationshipGenerator {

    private Random random = new Random();

    public WattsStrogatzRelationshipGenerator(WattsStrogatzConfig configuration) {
        super(configuration);
    }

    /**
     * {@inheritDoc}
     * 

* Generates a ring and performs rewiring on the network. This creates * a small-world network with high clustering coefficients (ie. there * are a lot of triangles present in the network, but the diameter * scales as ln(N)). Good choice for modelling simple social network * relationships (although hubs are not present). *

* * @return ring - edge list as a list of unordered integer pairs */ @Override protected List> doGenerateEdges() { int numberOfNodes = getConfiguration().getNumberOfNodes(); int meanDegree = getConfiguration().getMeanDegree(); double beta = getConfiguration().getBeta(); HashSet> ring = new HashSet<>(numberOfNodes); // Create a ring network for (int i = 0; i < numberOfNodes; ++i) { for (int j = i + 1; j <= i + meanDegree / 2; ++j) { int friend = j % numberOfNodes; ring.add(Pair.of(i, friend)); } } /** Rewire edges with probability beta. The false rewirings change the desired probability distribution a little bit, but for large enough networks do not matter. At the moment, I am hacking my way around a bit here, due to constraints enforced by the class structure. There is a room for improvement as this implementation is not the most effective one. Also, the wiring stops when the algorithm rewires to a non-graphical set of edges. Unconnected components may appear in the graph due to rewiring. Works, but could be faster. */ HashSet> newEdges = new HashSet<>(); Iterator> iterator = ring.iterator(); while (iterator.hasNext()) { Pair edge = iterator.next(); if (random.nextDouble() <= beta) { int choice = random.nextDouble() > .5 ? edge.getLeft() : edge.getRight(); // select first/second at random while (true) { int trial = random.nextInt(numberOfNodes - 1); int partner = trial < choice ? trial : trial + 1; // avoid self loops Pair trialPair = Pair.of(choice, partner); // Allows for self-rewiring to avoid parasitic cases? // check with original definition of the model if (trialPair.equals(edge)) break; if (!ring.contains(trialPair) && !newEdges.contains(trialPair)) { iterator.remove();//ring.remove(edge); newEdges.add(trialPair); break; } } } } // add newly rewired edges to the ring ring.addAll(newEdges); return new ArrayList<>(ring); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy