zoukankan      html  css  js  c++  java
  • HDU 5097 Page Rank (模拟)

    题目背景是以前用来对网页进行排名的Page Rank算法,是早期Google的革命性发明。

    背后的原理是矩阵和图论。这个数学模型是由Google的创始人拉里·佩奇和谢尔盖·布林发现的。

    如果一个网页被很多网页链接那么它的排名就高,当然不同的网页应该用不同的权值加以区分,

    一个网页的排名来自指向它的网页权值之和,这就带来一个问题,计算排名过程需要用到网页本身排名。

    这个问题可以变成一个二维矩阵相差,一开始认为所有的网页的排名都是相同,然后迭代算出排名。

    从理论上可以证明无论初始值如何选取,这种算法最后都会收敛于真实值。

    还有一个实际问题,互联网网页是非常大的,这个矩阵需要稀疏化处理。

    此题是简化版,给一个矩阵,Eij = 1表示i到j有个超链接,假设点击都是随机的,求S矩阵,S的j行和i列表示从i到j的概率。

    迭代计算直到收敛为止。

    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    const double eps = 1e-10;
    
    const int N = 3000+10;
    
    double G[N][N];
    
    const double alpha = 0.85;
    char buf[N][N];
    
    bool ok(double *q1,double *q2,int n)
    {
        double s = 0;
        for(int i = 0; i < n; i++) s += fabs(q1[i]-q2[i]);
        return s < eps;
    }
    double q0[N];
    double q1[N];
    double q2[N];
    
    int main()
    {
       // freopen("in.txt","r",stdin);
        int n;
        for(int i = 0; i < N; i++) q0[i] = 1;
        while(~scanf("%d",&n)){
            double beta = (1-alpha)/n;
            for(int i = 0; i < n; i++){
                scanf("%s",buf[i]);
            }
            for(int i = 0; i < n; i++){
                int cnt = 0;
                for(int j = 0; j < n; j++)
                    if(buf[i][j] == '1') cnt++;
                for(int j = 0; j < n; j++)
                    if(buf[i][j] == '1'){
                        G[j][i] = (cnt?alpha/cnt:0)+beta;
                    }
                    else G[j][i] = beta;
            }
    
            memcpy(q1,q0,sizeof(double)*n);
            double *qCur = q1, *qNxt = q2;
            do{
                for(int i = 0; i < n; i++){
                    qNxt[i] = 0;
                    for(int j = 0; j < n; j++){
                        qNxt[i] += G[i][j]*qCur[j];
                    }
                }
                std::swap(qCur,qNxt);
            }while(!ok(qCur,qNxt,n));
            for(int i = 0,sz = n-1; i < sz; i++)
                printf("%.2lf ",qCur[i]);
            printf("%.2lf
    ",qCur[n-1]);
        }
        return 0;
    }
  • 相关阅读:
    TopCoder SRM502 Div1 500 贪心 01背包
    TopCoder SRM502 Div1 1000 动态规划
    LOJ#6433. 「PKUSC2018」最大前缀和 状压dp
    Codeforces 830D Singer House 动态规划
    Codeforces 830C Bamboo Partition 其他
    UOJ#275. 【清华集训2016】组合数问题 数位dp
    Codeforces 806 D. Perishable Roads Dijkstra
    UOJ#53. 【UR #4】追击圣诞老人 树链剖分 k短路
    Java第二天——标识符命名规则、Java的知识、快捷键的使用、Scanner获取值的常用方法
    Scanner的例子
  • 原文地址:https://www.cnblogs.com/jerryRey/p/4656442.html
Copyright © 2011-2022 走看看