/*
Copyright 2010 by Sean Luke and George Mason University
Licensed under the Academic Free License version 3.0
See the file "LICENSE" for more information
*/
package sim.field.network.stats.actorcentrality;
import sim.field.network.*;
import sim.field.network.stats.*;
/**
*
* Actor Betweenness Centrality:
* <ul>
* <li>For undirected graphs (Wasserman and Faust, page 190) I count the geodesics between k and j just once
* (look for <code>j < k</code> in <code>getValue()</code>)</li>
* <li>For directed graphs (Wasserman and Faust, page 201) the geodesics from k to j are different from those from j to k, hence the
* x2 in <code>getMaxValue()</code>. I am not 100% sure about the x2 in
* <code>getMaxCummulativeDifference()</code></li>
* </ul>
*
* @author Gabriel Catalin Balan
*/
//TODO I believe that they say "transform the directed graph into and undirected one -by
//ignoring edges ij when there's no ji-, perform the standard computation and x2 the results."
public class BetweennessCentrality extends FreemanNodeIndex {
final long[][][]g3;//g_{ikj}= # shortest paths between i and j that go through k
final long[][]g2; //g_{ij} = # shortest paths between i and j
public BetweennessCentrality(final Network network)
{
super(network);
g3 = NetworkStatistics.getNumberShortestPathsWithIntermediatesMatrix( network,
UnitEdgeMetric.defaultInstance,
0d);
g2 = NetworkStatistics.getNumberShortestPathsMatrix( network,
UnitEdgeMetric.defaultInstance,
0d);
//(since the weights are integer values (hops), precisison is 0)
}
//note that g3[][0][0] is zero, so we are consistent with the idea that i must be distinct from k and j in g3[k][i][j];
public double getValue(final Object node) {
int index = network.getNodeIndex(node);
int n = network.allNodes.numObjs;
double sum = 0;
if(network.isDirected())
for(int k=0;k<n;k++)
{
if(k==index) continue;
long[] g2_k = g2[k];
long[] g3_ki = g3[k][index];
for(int j=0;j<n;j++)
sum += ((double)g3_ki[j])/g2_k[j];
}
else
for(int k=1;k<n;k++)//I start from 1 since no j can be <0.
{
if(k==index) continue;
long[] g2_k = g2[k];
long[] g3_ki = g3[k][index];
for(int j=0;j<k;j++)
sum += ((double)g3_ki[j])/g2_k[j];
}
return sum;
}
public double getMaxCummulativeDifference()
{
int n = network.allNodes.numObjs;
int value = (n-1)*(n-1)*(n-2);
if(network.isDirected())
return value;
return .5*value;
}
public double getMaxValue()
{
int n = network.allNodes.numObjs;
int value = (n-1)*(n-2);
if (network.isDirected())
return value;
return 0.5*value;
}
}