python中给出一个不超过10的正整数n怎么表示_在python中生成一个范围内的N个正整数,加起来等于总数...

这篇博客介绍了一种使用Python实现的算法,用于生成指定范围内具有相同选择概率的受限整数组合。通过递归公式和二项式系数计算,该算法能够均匀地生成整数分区。虽然对于大值的效率较低,但对于小输入值,它可以精确解决问题。博客还包含了预后和先决条件的检查,以确保结果的正确性。对于大规模的计算,建议采用近似解决方案。
摘要由CSDN通过智能技术生成

如果我正确理解规范,您希望随机生成受限整数compositions,这样每个可能的组合都有相同的被选择的可能性。在

我们可以将this answer应用于均匀生成随机整数partition的问题,从而精确地解决小输入值问题。我们只需要一种方法来计算受限制的k-组成。在数学的this answer中,有一个递归公式可以用来解决一个相关的问题,但事实证明,作为this answer的一部分,有一个更明确的公式,它使用二项式系数。下面是一个纯Python实现:import functools

import random

@functools.lru_cache(1 << 10)

def C1(n, k, a, b):

"Counts the compositions of `n` into `k` parts bounded by `a` and `b`"

return C2(n - k*(a - 1), k, b - (a - 1))

def C2(n, k, b):

"Computes C(n, k, 1, b) using binomial coefficients"

total = 0

sign = +1

for i in range(0, k + 1):

total += sign * choose(k, i) * choose(n - i*b - 1, k - 1)

sign = -sign

return total

def choose(n, k):

"Computes the binomial coefficient of (n, k)"

if k < 0 or k > n:

return 0

if k == 0 or k == n:

return 1

k = min(k, n - k)

c = 1

for i in range(k):

c = c * (n - i) // (i + 1)

return c

def check_pre_and_post_conditions(f):

def wrapper(n, k, a, b):

assert 1 <= k <= n, (n, k)

assert 1 <= a <= b <= n, (n, a, b)

assert k*a <= n <= k*b, (n, k, a, b)

comp = f(n, k, a, b)

assert len(comp) == k, (len(comp), k, comp)

assert sum(comp) == n, (sum(comp), n, comp)

assert all(a <= x <= b for x in comp), (a, b, comp)

return comp

return functools.wraps(f)(wrapper)

@check_pre_and_post_conditions

def random_restricted_composition(n, k, a, b):

"Produces a random composition of `n` into `k` parts bounded by `a` and `b`"

total = C1(n, k, a, b)

which = random.randrange(total)

comp = []

while k:

for x in range(a, min(b, n) + 1):

count = C1(n - x, k - 1, a, b)

if count > which:

break

which -= count

comp.append(x)

n -= x

k -= 1

return comp

要选择一个随机组合,我们只需生成一个比可能的组合总数小的随机索引,然后构造i-th字典组合(有关使用的递归关系的解释,请参阅相关问题)。这应该以同样的概率产生所有可能的结果。在

但是,因为C1(n, k, a, b)是指数增长的,对于n和{}的大值,这种方法相当慢。对于较大的值,近似的解决方案会更好地为您服务。在

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值