`
Jelen_123
  • 浏览: 71053 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

Weighted PageRank算法实现

 
阅读更多

PageRank里面的边是没有权重的,就是说每一个点对另一个点的影响都是一样的,但是会有一些情况,一个点对另一个点的影响大小不一致,这就需 要用到了给边加权重的方法,这就有了Weighted PageRank这个算法。WPR算法的理论资料相对于PR算法会少很多的,可以在Google scholar 上找到这篇论文 Weighted PageRank Algorithm . ,还可以到一些学校的网站找到这个算法的讲解,就差不多了。

我的实现方法是,先构建一个没有权重的关系矩阵,然后根据已经获得的矩阵,和WPR的权重出度和入读的方法计算出权重矩阵,然后有WPR的算法实现。实现的只是一个简单的实例,具体到实际的数据时还需要做修改。

代码如下:

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;

public class WeightPageRank {
       private static int count;            //矩阵的维数
       static int[][] matrix;        //二维数组,构造关系矩阵
       static double[][] weightMatrix; //二维数组,边的权重矩阵
       static double[] outLinks;      //每个点的出链接数
       static double[] inLinks;      //每个点的入链接数
       static double[] pageRank;   //PageRank值
       static double d = 0.85;        //抑制因素,设为0.85
       boolean flag = true;        //控制循环,收敛后则为false,停止计算
       
       /**
        * 构造函数
        * @param count  //矩阵的维数
        */
       public WeightPageRank(int count)
       {
           this.count = count;
           pageRank = new double[count];
           for(int i = 0; i < count; i++)
               pageRank[i] = 1/count;           //将每个页面的初始PR值设为1
       }
       
       
       /**
        * 初始化矩阵
        * @throws IOException
        */
       public void InitialMatrix() throws IOException
       {
           matrix = new int[count][count];               //关系矩阵
           File file = new File("graph.txt"); //读取文件中的关系信息
           FileReader fr;
           BufferedReader br;
           if(file.exists())            //文件存在
           {
                fr = new FileReader(file);
                br = new BufferedReader(fr);  //读取文件信息
                int i;
                while(br.ready())
                {
                    String[] words = new String[20];
                    String[] fromNodes = new String[20];  //起始点
                    String[] toNodes = new String[20];    //指向的点
                    words = br.readLine().split("-");
                    fromNodes[0] = words[0];
                    toNodes = words[1].split(",");
                    int row = 0;
                    for(i = 0;i < toNodes.length;i++)
                    {
                        int column = 0;
                        //System.out.println(fromNodes[0]+toNodes[i]);
                        switch(fromNodes[0].charAt(0))
                        {
                        case 'A': row = 0;break;
                        case 'B': row = 1;break;
                        case 'C': row = 2;break;
                        case 'D': row = 3;break;
                        case 'E': row = 4;break;
                        case 'F': row = 5;break;
                        case 'G': row = 6;break;
                        case 'H': row = 7;break;
                        case 'I': row = 8;break;
                        default : row = 0;break;
                        }
                        switch(toNodes[i].charAt(0))
                        {
                        case 'A': column = 0;break;
                        case 'B': column = 1;break;
                        case 'C': column = 2;break;
                        case 'D': column = 3;break;
                        case 'E': column = 4;break;
                        case 'F': column = 5;break;
                        case 'G': column = 6;break;
                        case 'H': column = 7;break;
                        case 'I': column = 8;break;
                        default : column = 0;break;
                        }  
                        matrix[row][column] = 1;      //将有边的两点赋值为1
                        //System.out.println(matrix[row][column]);
                    }
                   
                }
           }
           else            //文件存在
           {
               System.out.println("文件不存在!");
               System.exit(0);
           }
       }
       
       /**
        * 计算每个点的入链接数
        * 即,计算矩阵中每一列的和
        */
       public void inLinks()
       {
           inLinks = new double[count];
           for(int i = 0;i < count; i++)
           {
               for(int j = 0; j < count; j++)
               {
                   inLinks[i] += matrix[j][i];
               }
               //System.out.println(inLinks[i]);
           }
       }
       /**
        *
        * 计算每一个点的链出数
        * 即,计算矩阵中的每一行的和
        */
       public void outLinks()
       {
           outLinks = new double[count];
           for(int i = 0;i < count; i++)
           {
               for(int j = 0; j < count; j++)
               {
                   outLinks[i] += matrix[i][j];
               }
               //System.out.println(outLinks[i]);
           }
       }
       
       /**
        * 构建权重矩阵,根据关系矩阵,有边则计算该边的权重
        * 由入度权重和出度权重相乘得到
        * 入度权重计算方法为:(i,j)边的入度权重为i指向的边j的入度除以i指向的所有点的入度和
        * 出度权重计算方法为:(i,j)边的出度权重为i指向的边j的出度除以i指向的所有点的出度和
        */
       public void weightMatrix()
       {
           weightMatrix = new double[count][count];
           int[] sumIn = new int[count];
           int[] sumOut = new int[count];
           for(int i = 0;i < count;i++)
           {
               for(int j = 0; j < count; j++)
               {
                   if(matrix[i][j] == 1)               //有边,则统计起始点的所指向的点的入度和出度和
                   {
                       sumIn[i] += inLinks[j];         //统计点i指向的所有点的入度和
                       sumOut[i] += outLinks[j];       //统计点i指向的所有点的出度和
                   }
               }
           }
           
           //构建权重矩阵
           for(int i = 0;i < count;i++)
           {
               for(int j = 0; j < count; j++)
               {
                   if(matrix[i][j] == 1)               //有边,则计算该边的权重
                   {
                       weightMatrix[i][j] = (inLinks[j]/sumIn[i])*(outLinks[j]/sumOut[i]);
                       //System.out.println(weightMatrix[i][j]);
                   }
               }
           }
           
           
       }
       /**
        * 计算每一个页面PR值
        */
       public double[] CalculatePR(double[] pagerank)
       {
           double totle = 0;
           double pageRank1 = pagerank[0];           //第一个点前一次的PR值
           double pageRank2;                         //第一个点下一次的PR值,两个值用于判断是否收敛
           for(int j = 0; j < count; j++)
           {
               double sum = 0;
               for(int k = 0; k < count; k++)
               {
                   sum += weightMatrix[j][k]*pageRank[k]*matrix[k][j]/outLinks[k]; //计算各个PR总和
               }
               pageRank[j] = (1-d)/count + d*sum;                  //PR的计算
               totle += pageRank[j];
               System.out.print(pageRank[j]+":");
           }
           pageRank2 = pageRank[0];                        //下一次的PR值
           if(Math.abs(pageRank1-pageRank2) < Math.pow(10, -10))//收敛条件,两次的PR值的差的绝对值小于0.0000000001
               flag = false;
           else
               flag = true;
           
           //归一化处理
           for(int i = 0; i < count; i++)
           {
               pageRank[i] = pageRank[i]/totle;
           }
           return pageRank;
       }
       
       /**
        *
        * 迭代计算直到收敛
        *
        */
       public void CalculateResult()
       {
           double[] pageRanks = pageRank;
           int i = 0;
           while(flag)
           {
               System.out.println("第"+(i+1)+"轮迭代:");
               pageRanks = CalculatePR(pageRanks);           //循环调用计算PR值
               System.out.println();
               i++;
           }
           
           for(int j = 0; j < count; j++)
           {
               System.out.println("最终的结果为:");
               System.out.println((j+1)+"-----"+pageRanks[j]);
           }
               
       }
       
       public static void main(String[] args) throws IOException
       {
           WeightPageRank pg = new WeightPageRank(8);   //n维矩阵,有n个点
           pg.InitialMatrix();
           pg.inLinks();
           pg.outLinks();
           pg.weightMatrix();
           for(int i = 0; i < count;i++)
           {
               for(int j = 0; j < count; j++)
               {
                   System.out.print(matrix[i][j]+"  ");
               }
               System.out.println();
           }
           
           for(int i = 0; i < count;i++)
           {
               for(int j = 0; j < count; j++)
               {
                   System.out.print(weightMatrix[i][j]+"  ");
               }
               System.out.println();
           }
           
           pg.CalculateResult();
       }

}

分享到:
评论

相关推荐

    论文研究-一种多特征因子融合的PageRank算法研究.pdf

    摘 要:针对PageRank算法完全依据链接结构排序,未考虑网页内容分析,造成平均分配PR值、主题漂移、偏重旧网页的现象,且已有改进算法存在单一性优化等问题,提出一种多特征因子融合的PageRank算法。该算法为使搜索...

    基于相关性时间会议因素的STVRank算法.pdf

    STVRank算法是针对科学文献评价的一种改进算法,它结合了PageRank算法并引入了三个关键因素:相关性、时间间隔和会议影响力,以更全面地评估文献的重要性和影响力。传统的PageRank算法在计算网页或文献的排名时,将...

    第四代搜索引擎前沿综述归类.pdf

    PageRank算法随着时间推移不断发展,包括Weighted PageRank和Two-Layer PageRank等改进版本,以适应Web的复杂结构。 **第三代搜索引擎的局限性** 尽管PageRank提高了搜索质量,但仍存在一些问题。首先,单一的...

    第三次 图的实训报告.rar

    4. 拓展搜索:搜索引擎的PageRank算法就是基于图的模型。 通过这次实训,你将能够熟练掌握图的基本操作,理解各种图算法的工作原理,并能运用到实际问题中。在上机实践中,你可以尝试实现这些算法,对各种类型的图...

    刘雨晴+MicroRank论文阅读1

    PageRank算法是一种衡量网络中节点重要性的方法,被MicroRank改编用于区分异常和正常追踪信息的重要性。PageRank Scorer分为正常评分器和异常评分器两部分,分别计算正常和异常追踪的权重,这些权重成为后续频谱技术...

    Exploiting social circlebroadness for influential spreaders identification in social networks

    4. 社交圈加权PageRank(SCWPR)算法:文章提出了一个名为社交圈加权PageRank(Social Circle Weighted PageRank,SCWPR)的算法,用于迭代地计算每个用户全局社交圈广度的排名。 5. 实验验证:通过真实社交网络...

    networkx-master_networkx_complexnetworks_复杂网络_

    在网络动力学模拟上,`networkx`也提供了基础框架,用户可以定义自己的规则进行传播模型、演化模型等的仿真,如SIR模型(疾病传播)或者PageRank算法(网页重要性计算)。 综上所述,`networkx`是Python在复杂网络...

    基于语义位置和区域划分的兴趣点推荐模型

    接着应用边缘加权的个性化PageRank(edge-weighted personalized PageRank,EwPPR)来建模兴趣点之间的连续过渡;最后将用户时间偏好、区域偏好和连续过渡偏好融合为一个统一的推荐框架。通过在真实数据集上实验验证...

    图论课件rar

    在网页排名算法(如谷歌的PageRank)中,图论帮助确定网页的重要性;在物流和运输系统中,图论用于优化路线规划;在生物信息学中,蛋白质相互作用网络可以用图来建模。 综上所述,这个“图论课件”涵盖了图论的基础...

Global site tag (gtag.js) - Google Analytics