我正在尝试针对以下值有效实施inclusion-exclusion:
2/5, 2/5, 2/10, 2/10, 2/15, 2/15, ...
当然,该程序不能无限长地运行,所以我想对术语数量设置可配置的限制。
例如,假设我将计算范围限制为:
2/5, 2/5, 2/10, 2/10
那么计算将是:
+ 2/5 + 2/5 + 2/10 + 2/10 # choose 1 out of 4 terms
- 4/25 - 4/50 - 4/50 - 4/50 - 4/50 - 4/100 # choose 2 out of 4 terms
+ 8/250 + 8/250 + 8/500 + 8/500 # choose 3 out of 4 terms
- 16/2500 # choose 4 out of 4 terms
我发现以迭代方式“从y中选择x”有点复杂。
这是我当前的实现方式:
from decimal import Decimal
from decimal import getcontext
getcontext().prec = 100
def getBits(num):
bit = 0
bits = []
while num > 0:
if num & 1:
bits.append(bit)
bit += 1
num >>= 1
return bits
def prod(arr):
res = Decimal(1)
for val in arr:
res *= val
return res
SIZE = 20
sums = [Decimal(0) for k in range(SIZE)]
temp = [Decimal(2)/(5*k) for k in range(1,SIZE)]
probabilities = [p for pair in zip(temp,temp) for p in pair][:SIZE]
for n in range(1,1<<SIZE):
bits = getBits(n)
sums[len(bits)-1] += prod([probabilities[bit] for bit in bits])
total = 0
for k in range(SIZE):
total += sums[k]*(-1)**k
print(total)
如您所见,我通过生成1
和2 ** SIZE
之间的每种可能的位组合,然后在{{1}中选择项,来“从y个词中选择x个” }数组,它们位于当前位组合中标记为probabilities
的位置。
我本质上是在寻找一种更有效的方法,因为迭代次数以1
的值呈指数增长。
我知道可能不可行,因为包含-排除表达式中的项总数在技术上是指数的(Pascal三角形中一行的总和)。
但是,由于SIZE
中的值都是已知的并且是“不错的”(即2的幂除以5的乘积),因此我发现这里可能存在“快捷方式”,我忽略了。
非常感谢您提供任何想法!