/*
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;
import sim.field.network.*;
import java.util.*;
import sim.util.*;
public class DegreeStatistics
{
/**
Returns the sum of degrees of all nodes in the network.
*/
public static int getSumOfDegrees( final Network network )
{
return 2*NetworkStatistics.getNumberActualEdges(network);
}
/**
Returns the minimum in degree of nodes in the graph.
*/
public static int getMinInDegree( final Network network )
{
int N = NetworkStatistics.getNumberNodes(network);
int min = Integer.MAX_VALUE;
for( int i = 0 ; i < N; i++ )
{
Bag temp = network.getEdgesIn( network.allNodes.objs[i] );
if( min > temp.numObjs )
min = temp.numObjs;
}
return min;
}
/**
Returns the minimum out degree of nodes in the graph.
*/
public static int getMinOutDegree( final Network network )
{
int N = NetworkStatistics.getNumberNodes(network);
int min = Integer.MAX_VALUE;
for( int i = 0 ; i < N; i++ )
{
Bag temp = network.getEdgesOut( network.allNodes.objs[i] );
if( min > temp.numObjs )
min = temp.numObjs;
}
return min;
}
/**
Returns the maximum in degree of nodes in the graph.
*/
public static int getMaxInDegree( final Network network )
{
int N = NetworkStatistics.getNumberNodes(network);
int max = Integer.MIN_VALUE;
for( int i = 0 ; i < N; i++ )
{
Bag temp = network.getEdgesIn( network.allNodes.objs[i] );
if( max < temp.numObjs )
max = temp.numObjs;
}
return max;
}
/**
Returns the maximum out degree of nodes in the graph.
*/
public static int getMaxOutDegree( final Network network )
{
int N = NetworkStatistics.getNumberNodes(network);
int max = Integer.MIN_VALUE;
for( int i = 0 ; i < N; i++ )
{
Bag temp = network.getEdgesOut( network.allNodes.objs[i] );
if( max < temp.numObjs )
max = temp.numObjs;
}
return max;
}
/**
Returns the mean in degree of nodes in the graph.
*/
public static double getMeanInDegree( final Network network )
{
final int groupSize = NetworkStatistics.getNumberNodes(network);
if( groupSize == 0 )
return 0;
return (double)NetworkStatistics.getNumberActualEdges(network)/(double)groupSize;
}
/**
Returns the mean out degree of nodes in the graph.
*/
public static double getMeanOutDegree( final Network network )
{
final int groupSize = NetworkStatistics.getNumberNodes(network);
if( groupSize == 0 )
return 0;
return (double)NetworkStatistics.getNumberActualEdges(network)/(double)groupSize;
}
/**
Returns the variance of the in degree of nodes in the graph.
*/
public static double getVarInDegree( final Network network )
{
/*
* m=Sum(x)/n
* sigma^2 = = Sum[(x-m)^2]/(n-1)
* = [Sum(x^2)-2mSum(x)+Sum(m^2)]/(n-1)
* = [Sum(x^2)-2nm^2+n m^2]/(n-1)
* = [Sum(x^2)-(S^2)/n]/(n-1).
* = [Sum(x^2)n-S^2]/[n(n-1)]
*/
int sumSq=0;
int sum = NetworkStatistics.getNumberActualEdges(network);
int N = NetworkStatistics.getNumberNodes(network);
for( int i = 0 ; i < N; i++ )
{
Bag temp = network.getEdgesIn( network.allNodes.objs[i] );
final int inD = temp.numObjs;
sumSq += inD*inD;
}
return (double)(sumSq*N-sum*sum)/(N*(N-1)); //I hope hotspot will reuse N-1 ;)
}
/**
Returns the variance of the out degree of nodes in the graph.
*/
public static double getVarOutDegree( final Network network )
{
/*
* m=Sum(x)/n
* sigma^2 = = Sum[(x-m)^2]/(n-1)
* = [Sum(x^2)-2mSum(x)+Sum(m^2)]/(n-1)
* = [Sum(x^2)-2nm^2+n m^2]/(n-1)
* = [Sum(x^2)-(S^2)/n]/(n-1).
* = [Sum(x^2)n-S^2]/[n(n-1)]
*/
int sumSq=0;
int sum=NetworkStatistics.getNumberActualEdges(network);
int N = NetworkStatistics.getNumberNodes(network);
for( int i = 0 ; i < N; i++ )
{
Bag temp = network.getEdgesOut( network.allNodes.objs[i] );
final int outD = temp.numObjs;
sumSq += outD*outD;
}
return (double)(sumSq*N-sum*sum)/(N*(N-1)); //I hope hotspot will reuse N-1 ;)
}
//If one needs both the in and out degree histographs,
//I could avoid iterating through indexOutInHash twice
//by computing them in the same loop.
//TODO I could receive 2 IntBags for in and out degrees
//(one can be null if I should not care about it)
//Otherwise, the int[] might get extended for multigraphs,
//so the pointers would be useless.
static public int[] getDegreeHistogram(final Network network, boolean out)
{
int n = network.allNodes.numObjs;
int[] histogram = new int[n];
Iterator i = network.indexOutInHash.values().iterator();
for(int k=0;k<n;k++)
{
Network.IndexOutIn ioi= (Network.IndexOutIn)i.next();
Bag b = out?ioi.out:ioi.in;
int degree = (b==null)?0:b.numObjs;
if(degree>=histogram.length)//for multigraphs
{
int[] newhistogram = new int[degree+1];
System.arraycopy(histogram, 0, newhistogram, 0, histogram.length);
histogram = newhistogram;
}
histogram[degree]++;
}
return histogram;
}
/**
* CCDF = complementary cummulative distribution function
*/
static public double[] getDegreeCCDF(final Network network, boolean out)
{
int[] histogram = getDegreeHistogram(network, out);
int len = histogram.length;
double[] ccdf = new double[len];
for(int i=1;i<len;i++)
histogram[i]+= histogram[i-1];
int sum = histogram[len-1];
for(int i=0;i<len;i++)
ccdf[i]= 1d- ((double)histogram[i])/sum;
return ccdf;
}
}