具有邻接矩阵的概率计算

时间:2015-07-21 12:38:17

标签: c++ math

这是编程竞赛的问题。可以找到它的输入here和输出here

一个喝醉了的男人想离开酒吧回到他家。但他不记得他的家在哪里。所以,他会敲开城市的每个城市,等待他的家人接待他(总是会有人等着接待他)。

给定邻接矩阵 A 。每个值(i,j)表示醉酒男子离开第i个地方并到达第j个地方的概率。醉酒男子最多 m 步骤找不到他家的概率是多少?

到目前为止,我甚至不知道这是什么问题。搜索网络和书籍我发现要计算离开节点的概率 i a以 m 步骤进入节点 j 是由位置(i,j)给出 A 矩阵(A ^ m)的 m 幂。而且醉酒男子不能到家的概率可以直接计算或计算1 - 醉酒男子到达他家的概率(P(A)= 1 - P(不是A))。

  

输入的第一行由四行整数 n (0 <= n <= 100), t (0 k (0 m (0

对于每个测试用例,输出以两行给出,并且必须采用以下形式:

  

Instancia d
  的 v
  其中d表示实例的编号(从1开始),v是四舍五入到小数点后6位的概率。每个测试用例之间都有一个空行。

输入示例:

  

2 1 2 1
  0.5 0.5
  0.5 0.5
  3 1 2 2
  0.25 0.25 0.5
  0.25 0.5 0.25
  0.5 0.25 0.25
  0

输出示例:

  

Instancia 1
  0.500000

     

Instancia 2
  0.562500

对算法,书籍,网站或提示的任何帮助表示赞赏;

到目前为止,我必须解决这个问题的信息才能生成这个代码:

#include <stdio.h>
#include <string.h>

struct Matrix {
    double v[100][100];
    int row, col; // row x col

    Matrix(int n, int m) {
        memset(v, 0, sizeof(v));
        col = n;
        row = m;
    }

    Matrix operator*(const Matrix& x) const {
        Matrix ret(row, x.col);
        for(int i = 0; i < row; i++) {
            for(int k = 0; k < col; k++) {
                if (v[i][k])
                    for(int j = 0; j < x.col; j++)
                        ret.v[i][j] += v[i][k] * x.v[k][j];
            }
        }
        return ret;
    }
};


int main(){
    int n,t,k,m;
    int inst = 0;
    while(scanf("%d %d %d %d",&n,&t,&k,&m) == 4){
        Matrix mat(n,n);

        for (int i = 0; i < n; ++i)
            for (int j = 0; j < n; ++j)
                scanf("%lf",&mat.v[i][j]);

        //identity matrix
        Matrix aux(n,n);
        for (int i = 0; i < n; ++i)
            aux.v[i][i] = 1;


        //take the power of the matrix
        for (int i = 0; i < m; ++i) {
            aux = aux*mat;

            /* PRINT MATRIX
            for (int i = 0; i < n; ++i) {
                for (int j = 0; j < n; ++j) {
                    printf("%lf ",aux.v[i][j]);
                }
                printf("\n");
            }
             */

        }
        printf("Instancia %d\n%.6lf\n\n",++inst,aux.v[t-1][k-1]);
    }
}

2 个答案:

答案 0 :(得分:3)

正如stgatilov所说,你忘记了他到达那里后就不会离开家。

但不需要动态编程。只需稍微改变一下概率矩阵:如果他的家位于i,那么将概率从i改为i 改为1,对于不等于j的任何i,请将<{>从i升级到j 的概率更改为0

然后它应该可以正常工作。

注意:还有一个可能的优化。您可以使用Exponentiation by squaring

,而不是将矩阵乘以m

答案 1 :(得分:-1)

您似乎忘记了该男子可以而不是 m 步骤回家。现在你计算在完全 m 步骤之后他不会在家中的概率,因为他没有因任何原因而停止。

我认为您最好实施一些动态编程。例如 R [i,p] =男人没有在 i 步骤中回家的概率,并且在 i -step步骤之后他会到位 p 。重新计算有点类似于矩阵乘法,答案是通过对表 R 的相应条目求和得到的。

相关问题