【问题标题】:Calculating probabilities in a random maze walk with cycles用循环计算随机迷宫行走中的概率
【发布时间】:2018-09-05 03:10:24
【问题描述】:

我正在制作this programming challenge,其中一只青蛙随机穿过迷宫,途中有各种障碍物和炸弹到达潜在出口。

挑战是计算青蛙到达出口的概率。

我的问题是我不知道如何处理 cycles - 青蛙可以在两个或多个空间之间来回走动的情况。

想象一下你有:

     BOMB    BOMB
EXIT SPACE 1 SPACE 2 BOMB
     BOMB    BOMB

对于空间 1,到达出口的概率是直接走到出口的概率 (1/4),或者来回走直到最终到达出口的概率 (1/4^3 + 1/4) ^6 + 1/4^9...)。对于空间 2,它的 (1/4^2 + 1/4^5...)

如果您之间有多个空闲空间,这会变得更加混乱,例如

     BOMB    BOMB    BOMB
EXIT SPACE 1 SPACE 2 SPACE 3 BOMB
     BOMB    BOMB    BOMB

处理这些循环引入的复杂性的可靠算法方法是什么?

【问题讨论】:

  • 输入数据的范围很小,所以这意味着可能是一种蛮力的方法可能有效但似乎是一个好问题。
  • 如果您使用蛮力/模拟路径方法,请考虑应用方差减少技术来限制某些路径中使用的时间。
  • 我认为解决此问题的一种方法是说您想要马尔可夫链的平稳分布并在en.wikipedia.org/wiki/… 中应用数学。和brilliant.org/wiki/stationary-distributions
  • @mcdowella 所有死亡和所有逃逸都是马尔可夫链的固定分布......就像它们之间的任何比率一样。你如何确定哪个是想要的答案?

标签: algorithm computer-science graph-theory markov-chains


【解决方案1】:

我会分两个阶段解决这个问题。

第一阶段是确定您可以从哪些方格以任何方式退出。这将让您找到任何没有可能退出的闭环并将其识别为“您被卡住了”。

分析完成后,您可以将 0 分配给所有死胡同和炸弹,将 1 分配给所有出口。所有其他方格的退出概率将是一组线性方程组的唯一解,其中p(i, j) = average(p(i', j') 在所有可以一回合移动的位置上。这将是n x m 变量中的一组n x m 方程。用你最喜欢的线性代数技术解决这个问题(我建议减少行数)。

现在,对于每个方格,您都知道能够退出的确切概率。现在你的答案很简单。

请注意,如果您只是尝试第二种方法的线性代数部分,则线性方程组的解将不是唯一的。第一阶段解决了这个问题,以确保您提出正确的解决方案。

【讨论】:

    【解决方案2】:

    对于迷宫:

    +----+----+----+----+----+
    |    |BOMB|BOMB|BOMB|    |
    +----+----+----+----+----+
    |EXIT| S1 | S2 | S3 |BOMB|
    +----+----+----+----+----+
    |    |BOMB|BOMB|BOMB|    |
    +----+----+----+----+----+
    

    您可以将其映射到每次移动后发生的概率矩阵:

    //    DEAD, ESC,  S1,   S2,   S3
    p = [
        [ 1.00, 0.00, 0.00, 0.00, 0.00 ], // DEAD 
        [ 0.00, 1.00, 0.00, 0.00, 0.00 ], // ESCAPED
        [ 0.50, 0.25, 0.00, 0.25, 0.00 ], // S1 
        [ 0.50, 0.00, 0.25, 0.00, 0.25 ], // S2 
        [ 0.75, 0.00, 0.00, 0.25, 0.00 ]  // S3
    ];
    

    所以,沿着中间行阅读,如果青蛙从S1 方格开始,那么,经过一跳,有:

    • 死亡的概率为 0.5;
    • 0.25 它逃脱的概率;和
    • 在 S2 中的概率为 0.25。

    并且沿着前两行阅读 - 如果它已经死亡/逃脱,那么它将保持死亡/逃脱(分别)的概率为 1。

    要计算n 跳跃后的概率,只需将概率矩阵提高到n 的幂。

    //    DEAD, ESC,  S1,   S2,   S3
    p = [
        [ 1.00, 0.00, 0.00, 0.00, 0.00 ], // DEAD 
        [ 0.00, 1.00, 0.00, 0.00, 0.00 ], // ESCAPED
        [ 0.50, 0.25, 0.00, 0.25, 0.00 ], // S1 
        [ 0.50, 0.00, 0.25, 0.00, 0.25 ], // S2 
        [ 0.75, 0.00, 0.00, 0.25, 0.00 ]  // S3
        ];
    
    function multiply( a, b )
    {
      if ( a[0].length !== b.length )
      {
        throw "Matrices must have same a.x/b.y dimensions!";
      }
      let r = [];
      for ( let y = 0; y < a.length; y++ )
      {
        r[y] = [];
        for ( let x = 0; x < b[0].length; x++ )
        {
          r[y][x] = 0;
          for ( let i = 0; i < a[0].length; i++ )
          {
            r[y][x] += a[y][i] * b[i][x];
          }
        }
      }
      return r;
    }
    
    // Start at S1
    r = [ [ 0, 0, 1, 0, 0 ] ];
    // Output probabilities up to 10 decimal places.
    dp = 10;
    
    console.log(
      "i"
      + " " + "DEAD".padEnd(" ",dp+2)
      + " " + "ESCAPED".padEnd(" ",dp+2)
      + " " + "S1".padEnd(" ",dp+2)
      + " " + "S2".padEnd(" ",dp+2)
      + " " + "S3".padEnd(" ",dp+2)
    );
    for ( let i = 1; i <= 50; i++ ){
      r = multiply( r, p );
      if ( i < 10 || i % 10 === 0 )
      {
        console.log(
          i
          + " " + Number(r[0][0]).toFixed(dp)
          + " " + Number(r[0][1]).toFixed(dp)
          + " " + Number(r[0][2]).toFixed(dp)
          + " " + Number(r[0][3]).toFixed(dp)
          + " " + Number(r[0][4]).toFixed(dp)
        );
      }
    }

    这个简单的例子表明它很快收敛到青蛙不太可能仍然在移动的状态,并且有0.7321428571 它死了的概率和0.2678571429 它活着的概率。

    挑战将是获取输入映射并输出矩阵,然后查看优化矩阵的幂以快速找到该收敛点的方法(通过反复平方矩阵 - p = multiply(p, p); - 或 @ 987654321@).

    【讨论】:

      【解决方案3】:

      建议求解一组线性方程的答案是正确的,但这是另一种方法。

      想象一下,大量的青蛙都被放置在起始方格上,并开始在迷宫周围随机移动。青蛙们同时迈步。在每个时间步,我们可以使用一个介于 0.0 和 1.0 之间的数字来表示每个正方形上青蛙的比例。所以:

      • 在时间 0,所有青蛙都在起点,因此正方形的权重为 1.0,其余的权重为 0.0
      • 在每个时间步:
        • 炸弹上的所有青蛙都会被摧毁(将权重设置为 0.0)
        • 任何到达出口的青蛙都停留在那里
        • 任何其他方格上的青蛙平均分布在其邻居之间
        • 所有青蛙同时移动,因此这些更新需要同时执行

      在运行了很多步之后,几乎所有的青蛙都将处于以下三种状态之一:

      1. 被炸弹摧毁
      2. 在出口等候
      3. 陷入无限循环的迷宫中

      棘手的部分是根据循环的可能性决定何时停止模拟。当权重的变化不超过某个小值时,我们很容易认为我们可以停止。但是,如果有一些重复的循环,这将永远不会发生,例如在没有出口的 2x1 迷宫中,青蛙将无休止地来回跳跃,重量永远不会收敛。对于这个特定的任务,鉴于迷宫的大小是有限的,您可能会将步数固定为某个“足够大”的值。或者,您可以先找到不可能退出的所有方格,然后从收敛测试中排除这些方格(如另一个答案中所建议的那样)。

      【讨论】:

      • 您可以使用这种方法解决循环问题,方法是将过渡更改为 50% 的移动机会,50% 的保持不变的机会。然后所有封闭的部分将安定下来以停止。至于迭代次数,可以考虑直线路径的情况来寻找出路。您正在沿着一条长度为n x m 的小路走上一个醉汉的路。所以你必须做O(n^2 x m^2) 才能找到出路的机会。比如说,20 n^2 m^2 迭代将为您提供所需精度的答案...
      • 将此视为转换矩阵的重复平方将使其在更合理的时间内运行。但是您需要非常小心舍入错误。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-28
      • 1970-01-01
      • 2018-08-29
      相关资源
      最近更新 更多