【问题标题】:Dynamic Programming and Probability动态规划和概率
【发布时间】:2016-07-21 06:40:57
【问题描述】:

我已经盯着这个问题看了好几个小时,但我仍然像刚开始时一样迷茫。自从我学习离散数学或统计数据以来已经有一段时间了,所以我尝试在 youtube 上观看一些视频,但我找不到任何可以帮助我在比指数时间更短的时间内解决问题的东西。非常感谢任何有关如何解决以下问题的提示!

某种蕨类植物在郁郁葱葱的多雨地区茁壮成长,那里几乎每天都会下雨。 然而,预计未来 n 天会发生干旱,一个植物学家团队担心 物种在干旱中的生存。具体来说,团队确信以下几点 假设:当且仅当至少 n/2 天下雨时,蕨类植物种群才能生存 n 天干旱。换句话说,要让物种生存下去,至少要有同样多的雨天 作为非雨天。 当地气象专家预测,某天下雨的概率 i ∈ {1, . . . , n} 是 pi ∈ [0, 1],并且这 n 个随机事件是独立的。假设植物学家和 气象专家是正确的,展示了如何计算蕨类植物在干旱中存活的概率。 你的算法应该在 O(n2) 时间内运行。

【问题讨论】:

  • 这很简单。 “下雨会超过 n/2 天吗?”的递归。是“(今天下雨的概率 * 剩余几天中下雨 n/2-1 天的概率)+(今天不下雨的概率 * 剩余几天中下雨 n/2 天的概率)” .显然,计算中的两个分支有很多重叠。例如,可以设置 dp 矩阵,以便 DP[i][j] 存储剩余 j 天 i 天下雨的概率。
  • 我想我开始掌握它了。非常感谢!
  • 不客气。我还为另一个流行的入门级 DP 问题here 编写了一个详尽的类似教程的答案,您可能会觉得它很有教育意义。

标签: algorithm


【解决方案1】:

动态编程问题可以自上而下或自下而上的方式解决。

您已经了解了自下而上的版本。要执行自上而下的版本,请编写一个递归函数,然后添加一个缓存层,这样您就不会重新计算任何您已经计算过的结果。在伪代码中:

cache = {}
function whatever(args)
    if args not in cache
        compute result
        cache[args] = result
    return cache[args]

这个过程称为“记忆”,许多语言都有自动记忆事物的方法。

这是这个特定示例的 Python 实现:

def prob_survival(daily_probabilities):
    days = len(daily_probabilities)
    days_needed = days / 2

    # An inner function to do the calculation.
    cached_odds = {}
    def prob_survival(day, rained):
        if days_needed <= rained:
            return 1.0
        elif days <= day:
            return 0.0
        elif (day, rained) not in cached_odds:
            p = daily_probabilities[day]
            p_a = p * prob_survival(day+1, rained+1)
            p_b = (1- p) * prob_survival(day+1, rained)
            cached_odds[(day, rained)] = p_a + p_b
        return cached_odds[(day, rained)]

    return prob_survival(0, 0)

然后你会这样称呼它:

print(prob_survival([0.2, 0.4, 0.6, 0.8])

【讨论】:

    【解决方案2】:

    有一个(n + 1)×n 矩阵使得C[i][j] 表示在ith 天之后会有j 下雨天的概率(i1 运行到n , j0 运行到 n)。初始化:

    • C[1][0] = 1 - p[1]
    • C[1][1] = p[1]
    • C[1][j] = 0j &gt; 1

    现在循环这些天并像这样设置矩阵的值:

    • C[i][0] = (1 - p[i]) * C[i-1][0]
    • C[i][j] = (1 - p[i]) * C[i-1][j] + p[i] * C[i - 1][j - 1]j &gt; 0

    最后,将C[n][n/2]C[n][n]的值相加,得到蕨类植物存活的概率。

    【讨论】:

      猜你喜欢
      • 2014-05-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-21
      • 2017-06-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多