HDU 5097 Page Rank (模拟)

题意有点难读,给一个矩阵,Eij = 1表示i到j有个超连接,假设都是随机的,求S矩阵,S的j行和i列表示从i到j的概率。然后求出那个矩阵,模拟乘一下。

似乎任意的q都会收敛。

#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\n",qCur[n-1]);

    }

    return 0;

}

 

你可能感兴趣的:(rank)