PageRank算法java实现版本

PageRank算法是Google的核心搜索算法,在所有链接型文档搜索中有极大用处,而且在我们的各种关联系统中都有好的用法,比如专家评分系统,微博搜索/排名,SNS系统等。 
   PageRank算法的依据或思想: 
    1,被重要的网页链接的越多(外链)  ,此网页就越重要 
    2,此网页对外的链接越少越重要 
    这两个依据不能是独立的,是需要一起考虑的。但是问题来了,我们怎样判断本网页的外链是很重要的呢?循环判断?那不死循环了? 
    解决办法是:给定阀值,让循环在此临界处停止。 
   首先,我们准备了7个测试网页,这几个网页的链接情况如下:

i\j test1 test2 test3 test4 test5 test6 test7
test1 0 1 1 0 0 0 0
test2 1 0 0 1 0 0 0
test3 0 0 0 1 1 1 0
test4 0 1 0 0 1 0 1
test5 0 0 1 1 0 0 0
test6 1 0 0 0 1 0 0
test7 0 1 0 1 0 0 1

表格的意思是 test1链接到 test2,test3 ....依次类推 ,我们大致的根据上面两个原则可以猜一下,哪个将会是排名第一的网页?哪个最不重要? 
   貌似是test4和test6? 
   下面我们看看怎样用java实现PageRank算法。 
   首先创建html实体表示类,代码如下:

Java代码  

  1. /**
  2. * 网页entity
  3. *
  4. * @author afei
  5. *
  6. */
  7. class HtmlEntity {
  8. private String path;
  9. private String content;
  10. /* 外链(本页面链接的其他页面) */
  11. private List<String> outLinks = new ArrayList<String>();
  12. /* 内链(另外页面链接本页面) */
  13. private List<String> inLinks = new ArrayList<String>();
  14. private double pr;
  15. public String getPath() {
  16. return path;
  17. }
  18. public void setPath(String path) {
  19. this.path = path;
  20. }
  21. public String getContent() {
  22. return content;
  23. }
  24. public void setContent(String content) {
  25. this.content = content;
  26. }
  27. public double getPr() {
  28. return pr;
  29. }
  30. public void setPr(double pr) {
  31. this.pr = pr;
  32. }
  33. public List<String> getOutLinks() {
  34. return outLinks;
  35. }
  36. public void setOutLinks(List<String> outLinks) {
  37. this.outLinks = outLinks;
  38. }
  39. public List<String> getInLinks() {
  40. return inLinks;
  41. }
  42. public void setInLinks(List<String> inLinks) {
  43. this.inLinks = inLinks;
  44. }
  45. }

核心算法代码如下:

Java代码  

  1. /**
  2. * pagerank算法实现
  3. *
  4. * @author afei
  5. *
  6. */
  7. public class HtmlPageRank {
  8. /* 阀值 */
  9. public static double MAX = 0.00000000001;
  10. /* 阻尼系数 */
  11. public static double alpha = 0.85;
  12. public static String htmldoc = "D:\\workspace\\Test\\WebRoot\\htmldoc";
  13. public static Map<String, HtmlEntity> map = new HashMap<String, HtmlEntity>();
  14. public static List<HtmlEntity> list = new ArrayList<HtmlEntity>();
  15. public static double[] init;
  16. public static double[] pr;
  17. public static void main(String[] args) throws Exception {
  18. loadHtml();
  19. pr = doPageRank();
  20. while (!(checkMax())) {
  21. System.arraycopy(pr, 0, init, 0, init.length);
  22. pr = doPageRank();
  23. }
  24. for (int i = 0; i < pr.length; i++) {
  25. HtmlEntity he=list.get(i);
  26. he.setPr(pr[i]);
  27. }
  28. List<HtmlEntity> finalList=new ArrayList<HtmlEntity>();
  29. Collections.sort(list,new Comparator(){
  30. public int compare(Object o1, Object o2) {
  31. HtmlEntity h1=(HtmlEntity)o1;
  32. HtmlEntity h2=(HtmlEntity)o2;
  33. int em=0;
  34. if(h1.getPr()> h2.getPr()){
  35. em=-1;
  36. }else{
  37. em=1;
  38. }
  39. return em;
  40. }
  41. });
  42. for(HtmlEntity he:list){
  43. System.out.println(he.getPath()+" : "+he.getPr());
  44. }
  45. }
  46. /* pagerank步骤 */
  47. /**
  48. * 加载文件夹下的网页文件,并且初始化pr值(即init数组),计算每个网页的外链和内链
  49. */
  50. public static void loadHtml() throws Exception {
  51. File file = new File(htmldoc);
  52. File[] htmlfiles = file.listFiles(new FileFilter() {
  53. public boolean accept(File pathname) {
  54. if (pathname.getPath().endsWith(".html")) {
  55. return true;
  56. }
  57. return false;
  58. }
  59. });
  60. init = new double[htmlfiles.length];
  61. for (int i = 0; i < htmlfiles.length; i++) {
  62. File f = htmlfiles[i];
  63. BufferedReader br = new BufferedReader(new InputStreamReader(
  64. new FileInputStream(f)));
  65. String line = br.readLine();
  66. StringBuffer html = new StringBuffer();
  67. while (line != null) {
  68. line = br.readLine();
  69. html.append(line);
  70. }
  71. HtmlEntity he = new HtmlEntity();
  72. he.setPath(f.getAbsolutePath());
  73. he.setContent(html.toString());
  74. Parser parser = Parser.createParser(html.toString(), "gb2312");
  75. HtmlPage page = new HtmlPage(parser);
  76. parser.visitAllNodesWith(page);
  77. NodeList nodelist = page.getBody();
  78. nodelist = nodelist.extractAllNodesThatMatch(
  79. new TagNameFilter("A"), true);
  80. for (int j = 0; j < nodelist.size(); j++) {
  81. LinkTag outlink = (LinkTag) nodelist.elementAt(j);
  82. he.getOutLinks().add(outlink.getAttribute("href"));
  83. }
  84. map.put(he.getPath(), he);
  85. list.add(he);
  86. init[i] = 0.0;
  87. }
  88. for (int i = 0; i < list.size(); i++) {
  89. HtmlEntity he = list.get(i);
  90. List<String> outlink = he.getOutLinks();
  91. for (String ol : outlink) {
  92. HtmlEntity he0 = map.get(ol);
  93. he0.getInLinks().add(he.getPath());
  94. }
  95. }
  96. }
  97. /**
  98. * 计算pagerank
  99. *
  100. * @param init
  101. * @param alpho
  102. * @return
  103. */
  104. private static double[] doPageRank() {
  105. double[] pr = new double[init.length];
  106. for (int i = 0; i < init.length; i++) {
  107. double temp = 0;
  108. HtmlEntity he0 = list.get(i);
  109. for (int j = 0; j < init.length; j++) {
  110. HtmlEntity he = list.get(j);
  111. // 计算对本页面链接相关总值
  112. if (i != j && he.getOutLinks().size() != 0
  113. && he.getOutLinks().contains(he0.getPath())/*he0.getInLinks().contains(he.getPath())*/) {
  114. temp = temp + init[j] / he.getOutLinks().size();
  115. }
  116. }
  117. //经典的pr公式
  118. pr[i] = alpha + (1 - alpha) * temp;
  119. }
  120. return pr;
  121. }
  122. /**
  123. * 判断前后两次的pr数组之间的差别是否大于我们定义的阀值 假如大于,那么返回false,继续迭代计算pr
  124. *
  125. * @param pr
  126. * @param init
  127. * @param max
  128. * @return
  129. */
  130. private static boolean checkMax() {
  131. boolean flag = true;
  132. for (int i = 0; i < pr.length; i++) {
  133. if (Math.abs(pr[i] - init[i]) > MAX) {
  134. flag = false;
  135. break;
  136. }
  137. }
  138. return flag;
  139. }
  140. }

直接运行算法类,得到的结果如下:

D:\workspace\Test\WebRoot\htmldoc\test4.html : 1.102472450686259 
D:\workspace\Test\WebRoot\htmldoc\test5.html : 1.068131842865856 
D:\workspace\Test\WebRoot\htmldoc\test2.html : 1.0249590169406457 
D:\workspace\Test\WebRoot\htmldoc\test3.html : 1.0046891014946187 
D:\workspace\Test\WebRoot\htmldoc\test1.html : 0.9943895104008613 
D:\workspace\Test\WebRoot\htmldoc\test7.html : 0.9051236225340915 
D:\workspace\Test\WebRoot\htmldoc\test6.html : 0.9002344550746025

此算法可以无限改造,以满足自身要求。 
另外说一句:这个table咋编辑成这幅德行了?改都改不回来。

By 阿飞哥 转载请说明

时间: 2024-10-26 14:14:16

PageRank算法java实现版本的相关文章

MapReduce原理——PageRank算法Java版

Page Rank就是MapReduce的来源,下文是一个简单的计算PageRank的示例. import java.text.DecimalFormat; /**  * Created by jinsong.sun on 2014/7/15.  */ public class PageRankCaculator {     public static void main(String[] args) {         double[][] g = calcG(genS(), 0.85);  

PageRank算法C++代码实现标准版

对于PageRank算法,维基百科和网上很多大牛的博客已经讲得很详细了,这里附上一个自己写的PageRank算法C++实现版本: /* * Author: YANG Xiangyu * The Chinese university of Hong Kong */ #include<cstdio> #include<iostream> #include<fstream> #include<cstdlib> #include<string> #inc

&quot;如何用70行Java代码实现深度神经网络算法&quot; 的delphi版本

http://blog.csdn.net/hustjoyboy/article/details/50721535 "如何用70行Java代码实现深度神经网络算法" 的delphi版本 2016-02-23 10:58 225人阅读 评论(0) 收藏 举报 版权声明:本文为博主原创文章,未经博主允许不得转载. =====ann.pas源程序=================================== { by 阿甘 2016.2.23 参考自此篇文档如何用70行Java代码实现

微博短链接的生成算法(Java版本)

最近看到微博的短链接真是很火啊,新浪.腾讯.搜狐等微博网站都加入了短链接的功能.之所以要是使用短链接,主要是因为微博只允许发140 字,如果链接地址太长的话,那么发送的字数将大大减少.短链接的主要职责就是把原始链接很长的地址压缩成只有6 个字母的短链接地址,当我们点击这6 个字母的链接后,我们又可以跳转到原始链接地址. 开始以为短链接是按照某种算法把原始链接压缩为短链接,再根据算法从短链接反算成原始链接的.后来尝试了下压缩算法(gzip 压缩算法),发现对于url 这种字符串越是压缩,长度就越长

Hadoop应用开发实战(flume应用开发、搜索引擎算法、Pipes、集群、PageRank算法)

Hadoop是2013年最热门的技术之一,通过北风网robby老师<深入浅出Hadoop实战开发>.<Hadoop应用开发实战>两套课程的学习,普通Java开发人员可以在最快的时间内提升工资超过15000.成为一位完全精通Hadoop应用开发的高端人才. Hadoop是什么,为什么要学习Hadoop? Hadoop是一个分布式系统基础架构,由Apache基金会开发.用户可以在不了解分布式底层细节的情况下,开发分布式程序.充分利用集群的威力高速运算和存储.Hadoop实现了一个分布式

【转】深入浅出PageRank算法

原文链接 http://segmentfault.com/a/1190000000711128 PageRank算法 PageRank算法是谷歌曾经独步天下的“倚天剑”,该算法由Larry Page和Sergey Brin在斯坦福大学读研时发明的, 论文点击下载: The PageRank Citation Ranking: Bringing Order to the Web. 本文首先通过一些参考文献引出问题,然后给出了PageRank的几种实现算法, 最后将其推广至在MapReduce框架下

pagerank算法的MapReduce实现

pagerank是一种不容易被欺骗的计算Web网页重要性的工具,pagerank是一个函数,它对Web中(或者至少是抓取并发现其中连接关系的一部分web网页)的每个网页赋予一个实数值.他的意图在于,网页 的pagerank越高,那么它就越重要.并不存在一个固定的pagerank分配算法. 对于pagerank算法的推到我在这里不想做过多的解释,有兴趣的可以自己查看资料看看,这里我直接给出某个网页pagerank的求解公式: P(n)=a/G+(1-a)*求和(P(m)/C(m))     (m属

pagerank以及个性化的pagerank算法

pagerank最开始是Google提出来用来衡量网页重要度排行的算法. 她的思想是基于网页之间互相的链接作为加权投票.假如网页a指向b, 那么网页b的重要程度受网页a的影响,a越重要,则b就越重要.假如网页c也指向b, 但是c跟a对比,c指向其他网页的数量(出度)较少,那么c对b的贡献程度要大于a对b. 下面是网页i的重要程度的公式,其中d是一个概率,in(i)表示所有指向网页i的网页. 这公式的思想是模拟一个随机冲浪者的浏览网页的行为,公式左边部分表示该冲浪者以(1-d)/N的概率从浏览器输

Atitit 电子商务订单号码算法(java c# php js 微信

Atitit 电子商务订单号码算法(java c# php js  微信 1.1. Js版本的居然钱三爷里面没有..只好自己实现了. 1.2. 订单号标准化...长度16位 1.3. 订单号的结构 前4是自定义的,商户可以根据商户业务的不同,头四位不同.例如ET业务为4000,邮件业务为5000 1.4. 统一的订单结构,前边以为可以表示那个接口的订单(可以运用与微信,支付宝,银联表示 订单格式可用字符串,中间下划线分割,方便识别.纯数字兼容性更好 Atitit 微信支付总结 v2 paf 微信