一个网络(有向带权图)中节点u的PageRank的计算公式:

PR(u)表示节点u的PageRank值,d为衰减因子(damping factor)或阻尼系数,一般取d=0.85,N为网络中的节点总数,nb(u)表示节点u的所有邻居节点的集合,d(v)表示节点v的出度(如果是无向图,就是度),w(u,v)表示节点v的边<u,v>所占的权重(如果对于无权图或者认为每条边的权重都一样,那么w(u,v)=1),PR(v)表示节点v的PageRank值。

由此可以看出要算出节点u的PR值需要先知道它的每个邻居节点的PR值,似乎是个递归的过程。其实初始状态下,可以给每个节点的PR值都赋值为一个任意正数,例如1,然后通过上述公式不断迭代计算更新每个节点的PR值,数学证明,最终每个节点的PR值都会收敛到一个稳定的PR值(初值PR不同,最终的PR值也不同,但最后各节点之间PR的大小排名不因初值而改变)。编程时如何确定某个节点u的PR值已经收敛?如果这次的PR值与上次的PR值相差很小的时候就可以认为收敛了。很小是多小?越小越好,但不要太小,免得迭代次数太多浪费时间,可取10的-4或-5次方。

PageRank的数学原理的详细说明,可参考:

深入浅出PageRank算法

PageRank on undirected and weighted graph

《集体智慧编程》上的例子:

Java实现代码:

Program.java:

  1. package dd.lt;
  2.  
  3. import dd.lt.entity.Node;
  4.  
  5. public class Program
  6. {
  7. //计算每个节点的PageRank值
  8. public static void CalcPageRank(ArrayList<Node> graph)
  9. {
  10. double distance = 0.00001;
  11. double d = 0.85;// damping factor
  12. double common = (1 - d) / graph.size();
  13. while (true)
  14. {
  15. for (Node n : graph)
  16. {
  17. double sum = 0.0;
  18. for (int nodeId : n.getNeighbors())
  19. {
  20. Node nb = getNodeById(nodeId,graph);
  21. sum += nb.getPR() / nb.getDegree();
  22. }
  23. double newPR = common + d * sum;
  24. //如果尚未收敛,赋新值,否则结束迭代
  25. if (Math.abs(n.getPR() - newPR) > distance)
  26. n.setPR(newPR);
  27. else
  28. return;
  29. }
  30. }
  31. }
  32.  
  33. public static Node getNodeById(int nodeId,ArrayList<Node> graph)
  34. {
  35. for(Node n:graph)
  36. {
  37. if (n.nodeId==nodeId)
  38. return n;
  39. }
  40. return null;
  41. }
  42.  
  43. public static ArrayList<Node> buildGraph()
  44. {
  45. ArrayList<Node> graph = new ArrayList<Node>();//图以节点集合形式来表示
  46. //加载数据,组装好图结构
  47. ....
  48. return graph;
  49. }
  50.  
  51. public static void main(String[] args)
  52. {
  53. ArrayList<Node> graph = buildGraph();
  54. CalcPageRank(graph);
  55. for(Node n:graph)
  56. {
  57. System.out.println("PageRank of %d is %.2f",n.nodeId,n.getPR());
  58. }
  59. }
  60. }

Node.java:

  1. package dd.lt.entity;
  2.  
  3. import java.util.ArrayList;
  4.  
  5. public class Node implements Comparable<Node>
  6. {
  7. public int nodeId;
  8. private ArrayList<Integer> neighbors = new ArrayList<Integer>();//邻接表的形式表示图结构
  9. private double pr=1;
  10. public Node(int nodeId)
  11. {
  12. this.nodeId = nodeId;
  13. }
  14.  
  15. public int getDegree()
  16. {
  17. return this.neighbors.size();
  18. }
  19.  
  20. public ArrayList<Integer> getNeighbors()
  21. {
  22. return this.neighbors;
  23. }
  24. public void setNeighbors(ArrayList<Integer> neighbors)
  25. {
  26. this.neighbors=neighbors;
  27. }
  28.  
  29. public double getPR()
  30. {
  31. return pr;
  32. }
  33. public void setPR(double val)
  34. {
  35. this.pr=val;
  36. }
  37.  
  38. // 按PageRank值排序
  39. public int compareTo(Node anotherNode)
  40. {
  41. if (this.neighbors != null && anotherNode.neighbors != null)
  42. {
  43. // 降序排列
  44. if (anotherNode.getPR() >this.getPR())
  45. return 1;
  46. else if (anotherNode.getPR() <this.getPR())
  47. return -1;
  48. else
  49. return 0;
  50. // 升序排列
  51. // return this.getPR()-anotherNode.getPR();
  52. }
  53. return 0;
  54. }
  55. }

PageRank的java实现的更多相关文章

  1. PageRank算法MapReduce实现

    如果你现在需要计算网页的排名只有4一:数据如下面的: baidu 10.00 google,sina,nefu google 10.00 baidu sina 10.00 google nefu 10 ...

  2. PageRank在Hadoop和spark下的实现以及对比

    关于PageRank的地位,不必多说. 主要思想:对于每个网页,用户都有可能点击网页上的某个链接,例如 A:B,C,D B:A,D C:AD:B,C 由这个我们可以得到网页的转移矩阵      A   ...

  3. mr实现pagerank

    PageRank计算什么是pagerankPageRank是Google专有的算法,用于衡量特定网页相对于搜索引擎索引中的其他网页而言的重要程度.是Google创始人拉里·佩奇和谢尔盖·布林于1997 ...

  4. 【Hadoop学习之十一】MapReduce案例分析三-PageRank

    环境 虚拟机:VMware 10 Linux版本:CentOS-6.5-x86_64 客户端:Xshell4 FTP:Xftp4 jdk8 hadoop-3.1.1 什么是pagerank?算法原理- ...

  5. 数据挖掘之权重计算(PageRank)

    刘  勇  Email:lyssym@sina.com 简介 鉴于在Web抓取服务和文本挖掘之句子向量中对权重值的计算需要,本文基于MapReduce计算模型实现了PageRank算法.为验证本文算法 ...

  6. 20-hadoop-pagerank的计算

    转: http://www.cnblogs.com/rubinorth/p/5799848.html 参考尚学堂视频 1, 概念( 来自百度百科) PageRank是Google专有的算法,用于衡量特 ...

  7. Spark案例分析

    一.需求:计算网页访问量前三名 import org.apache.spark.rdd.RDD import org.apache.spark.{SparkConf, SparkContext} /* ...

  8. pagerank

    http://jung.sourceforge.net/ https://github.com/louridas/pagerank/blob/aeb9b17ada1f925bb525961574f6d ...

  9. 如何用70行Java代码实现深度神经网络算法(转)

    对于现在流行的深度学习,保持学习精神是必要的——程序员尤其是架构师永远都要对核心技术和关键算法保持关注和敏感,必要时要动手写一写掌握下来,先不用关心什么时候用到——用不用是政治问题,会不会写是技术问题 ...

随机推荐

  1. js实现可拖动Div

    随着时代的变化,越来越感觉到js的重要性,js不仅可以做web页面(如Ext框架),还可以做一些web的特效,这些特效不仅兼容PC,而且兼容手机端,毕竟是基于浏览器的,和平台没关系.现在微软的wind ...

  2. Memcached+PHP+Mysql+Linux 实践

    首先确保你的服务器环境已经具备了memcached和lamp,关于在Linux上搭建memcahced+php环境可以参考我的另外一篇帖子( http://www.cnblogs.com/codeAB ...

  3. [日常训练]string

    Description 给定一个长度为$n$的字符串,串中的字符保证是前$k$个小写字母.你可以在字符串后再添加$m$个字符,使得新字符串所包含的不同的子序列数量尽量多.当然,前提是只能添加前$k$个 ...

  4. Parallel.Foreach

    随着多核时代的到来,并行开发越来越展示出它的强大威力! 使用并行程序,充分的利用系统资源,提高程序的性能.在.net 4.0中,微软给我们提供了一个新的命名空间:System.Threading.Ta ...

  5. css3学习--border

    http://blog.sina.com.cn/s/blog_61671b520101gelr.html border-radius border-radius: 50px 20px;上下都是50px ...

  6. UVA725

    虽然是暴力求解,但是也要观察条件,尽量提高效率.如本题,原本要枚举10个数,但是分析可知通过枚举fghij就可以了. #include<stdio.h> #include<strin ...

  7. Shell入门

    前言 日常用Python多一些,不过很多时候shell脚本更简单实用一些,所以有必要熟悉一下shell脚本.当然shell有他特定的一些场景,比方说我曾经改过一个vpn断线自动重连的脚本,简单实用. ...

  8. ARM-汇编指令集(总结)

    ARM汇编指令集 指令.伪指令 (汇编)指令:   是机器码的助记符,经过汇编器编译后,由CPU执行. (汇编)伪指令:用来指导指令执行,是汇编器的产物,最终不会生成机器码. 有两种不同风格的ARM指 ...

  9. UP Board 超详细开箱评测

    前言 原创文章,转载引用务必注明链接. 江浙沪就是好,昨天发货今天收到.另外爱板太省了,外包装小纸箱还是6s钢化膜的重复利用. 注意:拍照自带抖动功能,画质大家凑合着看.冬日天气干燥,手触摸板子前建议 ...

  10. php跳转页面

    1.header(location:'url'); header函数前面不能有输出 ! 可以先输出到缓存. 2js echo "<script language='javascript ...