+++ /dev/null
-/*
-* 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.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.commons.collections15.Factory;
-
-import edu.uci.ics.jung.graph.DirectedGraph;
-
-
-
-/**
- * This algorithm measures the importance of nodes based upon both the number and length of disjoint paths that lead
- * to a given node from each of the nodes in the root set. Specifically the formula for measuring the importance of a
- * node is given by: I(t|R) = sum_i=1_|P(r,t)|_{alpha^|p_i|} where alpha is the path decay coefficient, p_i is path i
- * and P(r,t) is a set of maximum-sized node-disjoint paths from r to t.
- * <p>
- * This algorithm uses heuristic breadth-first search to try and find the maximum-sized set of node-disjoint paths
- * between two nodes. As such, it is not guaranteed to give exact answers.
- * <p>
- * A simple example of usage is:
- * <pre>
- * WeightedNIPaths ranker = new WeightedNIPaths(someGraph,2.0,6,rootSet);
- * ranker.evaluate();
- * ranker.printRankings();
- * </pre>
- *
- * @author Scott White
- * @see "Algorithms for Estimating Relative Importance in Graphs by Scott White and Padhraic Smyth, 2003"
- */
-public class WeightedNIPaths<V,E> extends AbstractRanker<V,E> {
- public final static String WEIGHTED_NIPATHS_KEY = "jung.algorithms.importance.WEIGHTED_NIPATHS_KEY";
- private double mAlpha;
- private int mMaxDepth;
- private Set<V> mPriors;
- private Map<E,Number> pathIndices = new HashMap<E,Number>();
- private Map<Object,V> roots = new HashMap<Object,V>();
- private Map<V,Set<Number>> pathsSeenMap = new HashMap<V,Set<Number>>();
- private Factory<V> vertexFactory;
- private Factory<E> edgeFactory;
-
- /**
- * Constructs and initializes the algorithm.
- * @param graph the graph whose nodes are being measured for their importance
- * @param alpha the path decay coefficient (>= 1); 2 is recommended
- * @param maxDepth the maximal depth to search out from the root set
- * @param priors the root set (starting vertices)
- */
- public WeightedNIPaths(DirectedGraph<V,E> graph, Factory<V> vertexFactory,
- Factory<E> edgeFactory, double alpha, int maxDepth, Set<V> priors) {
- super.initialize(graph, true,false);
- this.vertexFactory = vertexFactory;
- this.edgeFactory = edgeFactory;
- mAlpha = alpha;
- mMaxDepth = maxDepth;
- mPriors = priors;
- for (V v : graph.getVertices()) {
- super.setVertexRankScore(v, 0.0);
- }
- }
-
- protected void incrementRankScore(V v, double rankValue) {
- setVertexRankScore(v, getVertexRankScore(v) + rankValue);
- }
-
- protected void computeWeightedPathsFromSource(V root, int depth) {
-
- int pathIdx = 1;
-
- for (E e : getGraph().getOutEdges(root)) {
- this.pathIndices.put(e, pathIdx);
- this.roots.put(e, root);
- newVertexEncountered(pathIdx, getGraph().getEndpoints(e).getSecond(), root);
- pathIdx++;
- }
-
- List<E> edges = new ArrayList<E>();
-
- V virtualNode = vertexFactory.create();
- getGraph().addVertex(virtualNode);
- E virtualSinkEdge = edgeFactory.create();
-
- getGraph().addEdge(virtualSinkEdge, virtualNode, root);
- edges.add(virtualSinkEdge);
-
- int currentDepth = 0;
- while (currentDepth <= depth) {
-
- double currentWeight = Math.pow(mAlpha, -1.0 * currentDepth);
- for (E currentEdge : edges) {
- incrementRankScore(getGraph().getEndpoints(currentEdge).getSecond(),//
- currentWeight);
- }
-
- if ((currentDepth == depth) || (edges.size() == 0)) break;
-
- List<E> newEdges = new ArrayList<E>();
-
- for (E currentSourceEdge : edges) { //Iterator sourceEdgeIt = edges.iterator(); sourceEdgeIt.hasNext();) {
- Number sourcePathIndex = this.pathIndices.get(currentSourceEdge);
-
- // from the currentSourceEdge, get its opposite end
- // then iterate over the out edges of that opposite end
- V newDestVertex = getGraph().getEndpoints(currentSourceEdge).getSecond();
- Collection<E> outs = getGraph().getOutEdges(newDestVertex);
- for (E currentDestEdge : outs) {
- V destEdgeRoot = this.roots.get(currentDestEdge);
- V destEdgeDest = getGraph().getEndpoints(currentDestEdge).getSecond();
-
- if (currentSourceEdge == virtualSinkEdge) {
- newEdges.add(currentDestEdge);
- continue;
- }
- if (destEdgeRoot == root) {
- continue;
- }
- if (destEdgeDest == getGraph().getEndpoints(currentSourceEdge).getFirst()) {//currentSourceEdge.getSource()) {
- continue;
- }
- Set<Number> pathsSeen = this.pathsSeenMap.get(destEdgeDest);
-
- if (pathsSeen == null) {
- newVertexEncountered(sourcePathIndex.intValue(), destEdgeDest, root);
- } else if (roots.get(destEdgeDest) != root) {
- roots.put(destEdgeDest,root);
- pathsSeen.clear();
- pathsSeen.add(sourcePathIndex);
- } else if (!pathsSeen.contains(sourcePathIndex)) {
- pathsSeen.add(sourcePathIndex);
- } else {
- continue;
- }
-
- this.pathIndices.put(currentDestEdge, sourcePathIndex);
- this.roots.put(currentDestEdge, root);
- newEdges.add(currentDestEdge);
- }
- }
-
- edges = newEdges;
- currentDepth++;
- }
-
- getGraph().removeVertex(virtualNode);
- }
-
- private void newVertexEncountered(int sourcePathIndex, V dest, V root) {
- Set<Number> pathsSeen = new HashSet<Number>();
- pathsSeen.add(sourcePathIndex);
- this.pathsSeenMap.put(dest, pathsSeen);
- roots.put(dest, root);
- }
-
- @Override
- public void step() {
- for (V v : mPriors) {
- computeWeightedPathsFromSource(v, mMaxDepth);
- }
-
- normalizeRankings();
-// return 0;
- }
-
- /**
- * Given a node, returns the corresponding rank score. This implementation of <code>getRankScore</code> assumes
- * the decoration representing the rank score is of type <code>MutableDouble</code>.
- * @return the rank score for this node
- */
- @Override
- public String getRankScoreKey() {
- return WEIGHTED_NIPATHS_KEY;
- }
-
- @Override
- protected void onFinalize(Object udc) {
- pathIndices.remove(udc);
- roots.remove(udc);
- pathsSeenMap.remove(udc);
- }
-}