/*
* 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.importance;
import org.apache.commons.collections15.BidiMap;
import cern.colt.matrix.DoubleMatrix2D;
import edu.uci.ics.jung.algorithms.matrix.GraphMatrixOperations;
import edu.uci.ics.jung.algorithms.util.Indexer;
import edu.uci.ics.jung.graph.UndirectedGraph;
/**
* /**
* Computes s-t betweenness centrality for each vertex in the graph. The betweenness values in this case
* are based on random walks, measuring the expected number of times a node is traversed by a random walk
* from s to t. The result is that each vertex has a UserData element of type
* MutableDouble whose key is 'centrality.RandomWalkBetweennessCentrality'
*
* A simple example of usage is: <br>
* RandomWalkSTBetweenness ranker = new RandomWalkBetweenness(someGraph,someSource,someTarget); <br>
* ranker.evaluate(); <br>
* ranker.printRankings(); <p>
*
* Running time is: O(n^3).
* @see "Mark Newman: A measure of betweenness centrality based on random walks, 2002."
* @author Scott White
*/
public class RandomWalkSTBetweenness<V,E> extends AbstractRanker<V,E> {
public static final String CENTRALITY = "centrality.RandomWalkSTBetweennessCentrality";
private DoubleMatrix2D mVoltageMatrix;
private BidiMap<V,Integer> mIndexer;
V mSource;
V mTarget;
/**
* Constructor which initializes the algorithm
* @param g the graph whose nodes are to be analyzed
* @param s the source vertex
* @param t the target vertex
*/
public RandomWalkSTBetweenness(UndirectedGraph<V,E> g, V s, V t) {
initialize(g, true, false);
mSource = s;
mTarget = t;
}
protected BidiMap<V,Integer> getIndexer() {
return mIndexer;
}
protected DoubleMatrix2D getVoltageMatrix() {
return mVoltageMatrix;
}
protected void setUp() {
mVoltageMatrix = GraphMatrixOperations.<V,E>computeVoltagePotentialMatrix((UndirectedGraph<V,E>) getGraph());
mIndexer = Indexer.<V>create(getGraph().getVertices());
}
protected void computeBetweenness() {
setUp();
for (V v : getGraph().getVertices()) {
setVertexRankScore(v,computeSTBetweenness(v,mSource, mTarget));
}
}
public double computeSTBetweenness(V ithVertex, V source, V target) {
if (ithVertex == source || ithVertex == target) return 1;
if (mVoltageMatrix == null) {
setUp();
}
int i = mIndexer.get(ithVertex);
int s = mIndexer.get(source);
int t = mIndexer.get(target);
double betweenness = 0;
for (V jthVertex : getGraph().getSuccessors(ithVertex)) {
int j = mIndexer.get(jthVertex);
double currentFlow = 0;
currentFlow += mVoltageMatrix.get(i,s);
currentFlow -= mVoltageMatrix.get(i,t);
currentFlow -= mVoltageMatrix.get(j,s);
currentFlow += mVoltageMatrix.get(j,t);
betweenness += Math.abs(currentFlow);
}
return betweenness/2.0;
}
/**
* the user datum key used to store the rank scores
* @return the key
*/
@Override
public String getRankScoreKey() {
return CENTRALITY;
}
@Override
public void step() {
computeBetweenness();
}
}