pagerank算法

来源:互联网 发布:淘宝一分钱购物 编辑:程序博客网 时间:2024/06/10 23:12

一、实验内容

  1. 采用基于“抽税”法的PageRank算法分析图1的网页排名;
    这里写图片描述

图1 Web链接实例图

  1. 图1中,若节点①和节点③是主题节点,采用面向主题的PageRank算法重新计算所有节点的PageRank值。

二、实验设计(原理分析及流程)
首先是需要建立一个初始化概率分布向量V0,因为共有6个网页,因此V0的每个分量都是1/6,且V0是一个6维列向量。之后,根据上图的网页链接关系,构造一个网页转移矩阵。
具体是先使用vector来存储初始概率分布向量V0,同时创建结果特征矩阵V2。然后使用一个选择函数Choice来根据用户输入选择合适的向量计算方法(抽税法或面向主题法)。最后,显示surplus以及最终的特征向量。
其中CalResTax 计算特征矩阵左乘概率分布向量,抽税法,参数:上一次左乘结果,这次左乘结果,转移矩阵,抽税常数。CalResThe 计算特征矩阵左乘概率分布向量,面向主题方法,参数:上一次左乘结果,这次左乘结果,主题矩阵,转移矩阵,主题常数。另外,surplus定义为两个向量对应元素差的绝对值之和,使用SurCal函数来实现。

三、代码:

// pagerank.cpp model the google pagerank algorithm// using taxation or theme oriented// surplus定义为两个向量对应元素差的绝对值之和#include <iostream>#include <vector>#include <cmath>    // 使用abs()函数 求绝对值#define PAGENUM  6  // page个数#define THENUM 2#define EPS  0.001  // 阈值#define BETA 0.85   // beta// 初始化的概率向量v0std::vector<double> V0 (PAGENUM, (double)1/6);int ThemeArr[PAGENUM] = { 0.5, 0, 0.5, 0, 0, 0};std::vector<double> VS0 (ThemeArr, ThemeArr + PAGENUM);// 手动建立的转移矩阵double TrMat[PAGENUM][PAGENUM] ={    0.0, 0.5, 1.0, 0.0, 0.0, 0.0,    0.0, 0.0, 0.0, 0.0, 0.0, 0.0,    1.0, 0.5, 0.0, 0.0, 0.5, 0.0,    0.0, 0.0, 0.0, 0.0, 0.5, 0.5,    0.0, 0.0, 0.0, 0.5, 0.0, 0.5,    0.0, 0.0, 0.0, 0.5, 0.0, 0.0};// 网页主题 esint TheMat[PAGENUM] ={    1, 0, 1, 0, 0, 0};// 根据用户输入选择抽税还是面向主题的计算pagerank方法// 输入'T'返回true表明选择抽税方法char Choice(void){    char UsCho;    std::cout << "Now choose the calculate function: " << std::endl;    std::cout << "Enter 'T' for tax, enter 'S' for Theme, enter 'Q' to quit:" << std::endl;    std::cin >> UsCho;    return tolower(UsCho);}// 计算特征矩阵左乘概率分布向量,抽税法// 参数:上一次左乘结果, 这次左乘结果, 转移矩阵, 抽税常数int CalResTax(const std::vector<double> &V1, std::vector<double> &V2,              const double TrMat[][PAGENUM], const double TAX){    double TemSum = 0.0;    for(int i = 0; i < PAGENUM; i++)                // 矩阵行变化    {        for (int j = 0; j < PAGENUM; j++)           // 矩阵列变化        {            TemSum += V1[j] * TrMat[i][j];          // 矩阵列乘以概率列向量        }        V2[i] = BETA * TemSum + TAX;                   // 存放左乘后结果 + 税        TemSum = 0.0;                               // 一行乘以一列的结果重置为0    }    return 0;}// 计算特征矩阵左乘概率分布向量,面向主题方法// 参数:上一次左乘结果, 这次左乘结果,主题矩阵, 转移矩阵,主题常数int CalResThe(const std::vector<double> &V1, std::vector<double> &V2,              const std::vector<int> &S, const double TrMat[][PAGENUM],const double THEME){    double TemSum = 0.0;    for(int i = 0; i < PAGENUM; i++)                // 矩阵行变化    {        for (int j = 0; j < PAGENUM; j++)           // 矩阵列变化        {            TemSum += V1[j] * TrMat[i][j];          // 矩阵列乘以概率列向量        }        V2[i] = BETA * TemSum + THEME * S[i];       // 存放左乘后结果 + 主题        TemSum = 0.0;                               // 一行乘以一列的结果重置为0    }    return 0;}// 计算surplus,定义见开头注释// 参数:第一个概率分布向量,第二个概率分布向量double SurCal(const std::vector<double> &V1, std::vector<double> &V2){    double Sur = 0.0;    for (int i = 0; i < PAGENUM; i++)        Sur += fabs(V2[i] - V1[i]);         // 加括号更清晰    return Sur;}int main(void){    // result property matrix    std::vector<double> V2 (PAGENUM);       // 最新的特征矩阵    std::vector<int> S(TheMat, TheMat + PAGENUM);       // 主题矩阵    using std::cout;    using std::endl;    double surplus = 1.0;    const double TAX = (double)(1.0 - BETA) / PAGENUM;    // 循环不变量外提,小优化    const double THEME = (double)(1.0 - BETA) / THENUM;   // 主题矩阵es    char cho;    while (( cho = Choice()) != 'q')    {        cout << "cho = " << cho << endl;        if (cho == 't')        {            std::vector<double> V1 (V0);            // 上一个特征矩阵            while (surplus > EPS)            {                CalResTax(V1, V2, TrMat, TAX);                surplus = SurCal(V1, V2);                V1.assign(V2.begin(), V2.end());        // 更新V1的内容,注意使用的方法            }        }        else if (cho == 's')        {            std::vector<double> V1 (VS0);            // 上一个特征矩阵            while (surplus > EPS)            {                CalResThe(V1, V2, S, TrMat, THEME);                surplus = SurCal(V1, V2);                V1.assign(V2.begin(), V2.end());        // 更新V1的内容,注意使用的方法            }        }        else            continue;        cout << "surplus: " << surplus << endl;        cout << "The result vector: " << endl;        for(auto p : V2)                        // 输出最后的特征矩阵            cout << p << endl;        surplus = 1.0;                   // 重置surplus以便其他方法调用    }    cout << "Done." << endl;    return 0;}
原创粉丝点击