/* * 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 java.util.Map; import java.util.Set; import org.apache.commons.collections15.BidiMap; import org.apache.commons.collections15.functors.MapTransformer; import cern.colt.matrix.DoubleMatrix1D; import cern.colt.matrix.DoubleMatrix2D; import cern.colt.matrix.impl.DenseDoubleMatrix1D; import cern.colt.matrix.impl.SparseDoubleMatrix1D; import edu.uci.ics.jung.algorithms.matrix.GraphMatrixOperations; import edu.uci.ics.jung.algorithms.scoring.PageRank; import edu.uci.ics.jung.algorithms.util.Indexer; import edu.uci.ics.jung.graph.DirectedGraph; /** * @author Scott White and Joshua O'Madadhain * @author Tom Nelson - adapted to jung2 * @see "Algorithms for Estimating Relative Importance in Graphs by Scott White and Padhraic Smyth, 2003" */ public class MarkovCentrality<V,E> extends RelativeAuthorityRanker<V,E> { public final static String MEAN_FIRST_PASSAGE_TIME = "jung.algorithms.importance.mean_first_passage_time"; private DoubleMatrix1D mRankings; private BidiMap<V,Integer> mIndexer; public MarkovCentrality(DirectedGraph<V,E> graph, Set<V> rootNodes) { this(graph,rootNodes,null); } public MarkovCentrality(DirectedGraph<V,E> graph, Set<V> rootNodes, Map<E,Number> edgeWeightKey) { super.initialize(graph, true, false); setPriors(rootNodes); if (edgeWeightKey == null) assignDefaultEdgeTransitionWeights(); else setEdgeWeights(edgeWeightKey); normalizeEdgeTransitionWeights(); mIndexer = Indexer.<V>create(graph.getVertices()); mRankings = new SparseDoubleMatrix1D(graph.getVertexCount()); } /** * @see edu.uci.ics.jung.algorithms.importance.AbstractRanker#getRankScoreKey() */ @Override public String getRankScoreKey() { return MEAN_FIRST_PASSAGE_TIME; } /** * @see edu.uci.ics.jung.algorithms.importance.AbstractRanker#getVertexRankScore(Object) */ @Override public double getVertexRankScore(V vert) { return mRankings.get(mIndexer.get(vert)); } /** * @see edu.uci.ics.jung.algorithms.util.IterativeProcess#step() */ @Override public void step() { DoubleMatrix2D mFPTMatrix = GraphMatrixOperations.computeMeanFirstPassageMatrix(getGraph(), getEdgeWeights(), getStationaryDistribution()); mRankings.assign(0); for (V p : getPriors()) { int p_id = mIndexer.get(p); for (V v : getVertices()) { int v_id = mIndexer.get(v); mRankings.set(v_id, mRankings.get(v_id) + mFPTMatrix.get(p_id, v_id)); } } for (V v : getVertices()) { int v_id = mIndexer.get(v); mRankings.set(v_id, 1 / (mRankings.get(v_id) / getPriors().size())); } double total = mRankings.zSum(); for (V v : getVertices()) { int v_id = mIndexer.get(v); mRankings.set(v_id, mRankings.get(v_id) / total); } } /** * Loads the stationary distribution into a vector if it was passed in, * or calculates it if not. * * @return DoubleMatrix1D */ private DoubleMatrix1D getStationaryDistribution() { DoubleMatrix1D piVector = new DenseDoubleMatrix1D(getVertexCount()); PageRank<V,E> pageRank = new PageRank<V,E>(getGraph(), MapTransformer.getInstance(getEdgeWeights()), 0); pageRank.evaluate(); for (V v : getGraph().getVertices()) piVector.set(mIndexer.get(v), pageRank.getVertexScore(v)); return piVector; } }