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算法完全依据链接结构排序,未考虑网页内容分析,造成平均分配PR值、主题漂移、偏重旧网页的现象,且已有改进算法存在单一性优化等问题,提出一种多特征因子融合的PageRank算法。该算法为使搜索...
STVRank算法是针对科学文献评价的一种改进算法,它结合了PageRank算法并引入了三个关键因素:相关性、时间间隔和会议影响力,以更全面地评估文献的重要性和影响力。传统的PageRank算法在计算网页或文献的排名时,将...
PageRank算法随着时间推移不断发展,包括Weighted PageRank和Two-Layer PageRank等改进版本,以适应Web的复杂结构。 **第三代搜索引擎的局限性** 尽管PageRank提高了搜索质量,但仍存在一些问题。首先,单一的...
4. 拓展搜索:搜索引擎的PageRank算法就是基于图的模型。 通过这次实训,你将能够熟练掌握图的基本操作,理解各种图算法的工作原理,并能运用到实际问题中。在上机实践中,你可以尝试实现这些算法,对各种类型的图...
PageRank算法是一种衡量网络中节点重要性的方法,被MicroRank改编用于区分异常和正常追踪信息的重要性。PageRank Scorer分为正常评分器和异常评分器两部分,分别计算正常和异常追踪的权重,这些权重成为后续频谱技术...
4. 社交圈加权PageRank(SCWPR)算法:文章提出了一个名为社交圈加权PageRank(Social Circle Weighted PageRank,SCWPR)的算法,用于迭代地计算每个用户全局社交圈广度的排名。 5. 实验验证:通过真实社交网络...
在网络动力学模拟上,`networkx`也提供了基础框架,用户可以定义自己的规则进行传播模型、演化模型等的仿真,如SIR模型(疾病传播)或者PageRank算法(网页重要性计算)。 综上所述,`networkx`是Python在复杂网络...
接着应用边缘加权的个性化PageRank(edge-weighted personalized PageRank,EwPPR)来建模兴趣点之间的连续过渡;最后将用户时间偏好、区域偏好和连续过渡偏好融合为一个统一的推荐框架。通过在真实数据集上实验验证...
在网页排名算法(如谷歌的PageRank)中,图论帮助确定网页的重要性;在物流和运输系统中,图论用于优化路线规划;在生物信息学中,蛋白质相互作用网络可以用图来建模。 综上所述,这个“图论课件”涵盖了图论的基础...