PageRank 标准计算 C++

7 篇文章 0 订阅
5 篇文章 0 订阅

标准PageRank

在这里插入图片描述

增量PageRank在这里插入图片描述

#include<iostream>
#include<cstdio>
#include<fstream>
#include<string>
#include<cstring>
#include<algorithm>
using namespace std;
#define  top 10
#define MAX 100000

bool recordVertex[MAX]={false};  //标记顶点是否被访问过
int dout[MAX]={0};       //累计顶点的出度
int din[MAX]={0};       //累计顶点的出度
double PR[MAX]={0};   //
double newPR[MAX]={0};//

//定义边
struct edge{
    int u;
    int v;
}edge[5200000];

//比较排序:降序排列
int cmp(const int &a, const int &b){
    if(PR[recordVertex[a]] > PR[recordVertex[b]])
        return 1;
    return 0;
}

//比较排序2:降序排列
bool cmp2(pair<int, double> a, pair<int, double> b){
    //return a.first > b.first;//根据fisrt的值降序排序
    return a.second > b.second;//根据second的值降序排序
}

void pagerank(){
    //ifstream fin("E://edge-test.txt");
    ifstream fin("E://facebook_combined.txt");
    //ifstream fin("E://web-Google.txt");
    ofstream fout("E://out-edge.txt");
    memset(edge,0,sizeof(edge));//初始化
    string s;

    int ncnt=0;    //记录顶点数
    int ecnt=0;    //记录边数
    int cnt=0;     //迭代次数
    double eps=0.1;//误差值
    bool flag = true;
    int i;
    cout << "------PRBeginning-----" <<endl;

    //读文件
    for(i=0; fin >> edge[i].u >> edge[i].v; ++i){
        //判断顶点U是否被访问过
        if(!recordVertex[edge[i].u]) {
            recordVertex[edge[i].u]=flag;
            ncnt++;

        }
        //判断顶点V是否被访问过
        if(!recordVertex[edge[i].v]){
            recordVertex[edge[i].v]=flag;
            ncnt++;

        }
        dout[edge[i].u]++;//
        din[edge[i].v]++;//
    }
    ecnt=i;

    //1初始化pr值
    for(i=0; i<ncnt; ++i){
        PR[i]=(double)1/ncnt;
    }

    //设置 ε=10^(-5), 控制迭代次数
    while(eps>0.00001){
        printf("%d %.5lf\n",cnt,eps);
        eps=0;
        cnt++;
        //2利用出度计算newPR
        for(int i=0; i<ecnt; ++i){
            newPR[edge[i].v]+=PR[edge[i].u]/dout[edge[i].u];
        }
        //3添加随机值β
        for(int i=0; i<ncnt; ++i){
            newPR[i]=newPR[i]*0.8+(0.2*1/ncnt);
            //比较误差的累加值是否在eps之内
            eps+=PR[i]>newPR[i]?(PR[i]-newPR[i]):(newPR[i]-PR[i]);
            PR[i]=newPR[i];
            newPR[i]=0;
        }
    }
    cout << "------PREnding-----" <<endl;

    pair<int, double> No_PR[ncnt];
    for(i=0; i<ncnt; ++i) {
        No_PR[i] = make_pair(i, PR[i]);
    }
    //这个排序,需要很大内存,可能会导致程序崩溃
    sort(No_PR, No_PR+ncnt, cmp2);

    //降序输出前top个顶点-顶点PR
    for(i=0; i<top; ++i) {
        fout << No_PR[i].first << ' ' << No_PR[i].second << endl;
        cout << No_PR[i].first << ' ' << No_PR[i].second << endl;
    }
    cout << "-----End------" <<endl;

}
int main(){
    pagerank();
    return 0;
}

数据集链接:SNAP

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值