【问题标题】:Optimise complexity of combinatoric algorithm优化组合算法的复杂度
【发布时间】:2021-01-20 09:28:59
【问题描述】:

我正在努力针对以下问题优化我的代码:

您有 N 个从 1 到 N 索引的框。每个框包含 没有硬币或一枚硬币。空箱数量和数量 有一枚硬币的盒子分别用 n0 和 n1 表示。你拿 框的随机子集,其中每个子集具有相同的相同 被选中的概率。空集和集合本身是 被认为是一个子集。

给定n0和n1,总数的概率是多少 随机子集中的硬币是偶数吗?

约束:N = n0 + n1

示例

1
  • 输入:n0 = 1,n1 = 0
  • 输出:1.0
  • 说明:有两个子集:[] 和 [0]。两者的总和是偶数。
2
  • 输入:n0 = 0,n1 = 2
  • 输出:0.5
  • 说明:有四个子集:[]、[1]、[1] 和 [1, 1]。 [] 和 [1,1] 之和是偶数。

到目前为止,我尝试在 Python 3.8 中实现,但我认为它工作正常,但计算更大的数字需要很长时间。

prob = 0

n0 = 1
n1 = 4

for j in range(0, n1+1):
        if (j % 2 == 0):
            prob += comb(n1, j)

total_prob = (2**n0 * prob) / (2 ** (n0+n1))
total_prob

【问题讨论】:

  • 这是一个有趣的任务。我必须说它与 Python 无关。最好在math.stackexchange.com 上提问
  • @Roger -- 大数的大概大小是多少,例如数百、数千等?
  • Constraint: N = n0 + n1 < 100000 所以是的,低于 100k !
  • @Roger——如果您在上面发布的方法的组合数量很大,则无法计算。你可以从Strirling's Approximation for factorial 看到这个,它有 n! ~ (n^n)*sqrt(2*pi*n)。随着 n~ 100K,n^n ~ (100k)^(100k) ~ (10^5)^100k ~ 10^500k 变得不可计算(相比之下,宇宙中有 10^82 个原子)。
  • @Roger——虽然我们无法计算总和,但它简化了我发布的答案的分析。

标签: python optimization combinations mathematical-optimization


【解决方案1】:

假设您的算法是正确的,total_prob 可以解析确定如下。

这个总结:

prob = 0
for j in range(0, n1+1):
        if (j % 2 == 0):
            prob += comb(n1, j)

正在计算二项式系数的偶数项,即:

comb(n1, 0) + comb(n1, 2) + ... + comb(n1, J)
    where J is even and J>=n1

J > n1 没关系,因为 comb(n1, J) = 0 for J > n1(nCr 的定义)

这个总和就是source

prob = 2**(n1 - 1)

代入total_prob方程中的prob:

total_prob = (2**n0) *(2**(n1-1)) / (2 ** (n0+n1))
total_prob = 2**(n0 + n1 - 1)/(2**(n0+n1))

total_prob = 0.5  (always)

【讨论】:

【解决方案2】:
import math

def comb(n, k):  # Calculates the combination based on n and k values
    return math.factorial(n) // math.factorial(n - k) //math.factorial(k)

def question(n0, n1):    # probability that the total number of coins in the random subset is even
    """probability of sums of even / total probability"""
    p = 0
    for i in range(0, n1+1):
        if (i % 2 == 0):
            p += comb(n1, i)

    return  p / (2 ** n1)

【讨论】:

  • 请解释这段代码的作用,以及它是如何做到的;永远不要只发布代码作为答案。
  • 我知道,但您必须解释您是如何创建解决方案的;你改变了什么,它做了什么,它是如何做到的。否则提问的人不会学到任何东西。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-22
  • 1970-01-01
相关资源
最近更新 更多