// Catalano Graph Library
// The Catalano Framework
//
// Copyright © Diego Catalano, 2012-2016
// diego.catalano at live.com
//
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
//
package Catalano.Graph.Network;
import Catalano.Graph.AdjacencyMatrix;
/**
* PageRank algorithm.
* PageRank is a way of measuring the importance of website pages.
* @author Diego Catalano
*/
public class PageRank {
private double epsilon = 0.001;
private double factor = 0.85;
private int it = 0;
/**
* Get epsilon value.
* @return Epsilon value.
*/
public double getEpsilon() {
return epsilon;
}
/**
* Set epsilon value.
* Epsilon value, is the stop criteria.
* @param epsilon Epsilon value.
*/
public void setEpsilon(double epsilon) {
if(epsilon == 0)
throw new IllegalArgumentException("The epsilon value must be different of zero.");
this.epsilon = epsilon;
}
/**
* Get damping factor.
* @return Damping factor.
*/
public double getFactor() {
return factor;
}
/**
* Set damping factor.
* @param factor Damping factor.
*/
public void setFactor(double factor) {
this.factor = Math.min(1, Math.max(0, factor));
}
/**
* Get number of iterations executed by the algorithm.
* @return Number of iterations.
*/
public int getNumberOfIterations() {
return it;
}
/**
* Initialize a new instance of the PageRank class.
*/
public PageRank() {}
/**
* Initialize a new instance of the PageRank class.
* @param factor Damping factor.
*/
public PageRank(double factor){
setFactor(factor);
}
/**
* Compute PageRank.
* @param matrix Adjacency matrix.
* @return Ranks.
*/
public double[] Compute(AdjacencyMatrix matrix){
//Basic weights. 1/n
double[] w = new double[matrix.getData().length];
double t = 1 / w.length;
for (int i = 0; i < w.length; i++) {
w[i] = t;
}
return Compute(matrix,w);
}
/**
* Compute PageRank.
* @param matrix Adjacency matrix.
* @param weights Inital weights,
* @return Ranks.
*/
public double[] Compute(AdjacencyMatrix matrix, double[] weights){
if(matrix.getData().length != weights.length)
throw new IllegalArgumentException("The matrix lenght must be the same lenght of the weights.");
double[][] m = matrix.getData();
double[] ranks = new double[m.length];
double[] outs = new double[m.length];
//Calculate the number of outs for each node
for (int i = 0; i < m.length; i++) {
double sum = 0;
for (int j = 0; j < m[0].length; j++) {
if(m[i][j] != 0)
sum++;
}
outs[i] = sum;
}
//Inital wwights to all nodes
ranks = weights;
//Common calculation for all nodes
double part1 = (1 - factor) / (double)m.length;
double maxDiff = Double.MAX_VALUE;
double[] oldRanks = ranks.clone();
while(maxDiff > epsilon){
//Calculate page rank
for (int j = 0; j < m[0].length; j++) {
double part2 = 0;
for (int i = 0; i < m.length; i++) {
if(m[i][j] != 0){
part2 += ranks[i] / outs[i];
}
}
ranks[j] = part1 + factor * part2;
}
maxDiff = Convergency(oldRanks, ranks);
it++;
}
return ranks;
}
/**
* Test for convergency.
* @param oldRanks Old ranks value.
* @param ranks New ranks value.
* @return Convergeny.
*/
private double Convergency(double[] oldRanks, double[] ranks){
double maxDiff = Double.MAX_VALUE;
for (int i = 0; i < ranks.length; i++) {
maxDiff = Math.min(maxDiff, oldRanks[i] - ranks[i]);
}
return maxDiff;
}
}
Ads help maintain this website.