优化组合算法的复杂度 示例

问题描述

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

您会得到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

解决方法

假设您的算法正确,则可以按以下方式解析确定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来说还可以,因为对于J> n1(nCr的定义),comb(n1,J)= 0

这个总和就是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)
,
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)