Algorithm 使用边界查找前提数的算法?
我想知道是否有一种算法可以告诉我,如果我在边界内寻找排列,会得到多少结果 我有一个寻找组合的程序。最好的解释方法是举个例子,假设你有4件东西想在商店买:苹果、桃子、梨和橘子。你想知道每个篮子能装多少百分比,但你告诉自己,你想每个篮子最少装20个,每个篮子最多装60个(所以苹果:25,桃子:25,梨:25,橘子:25效果很好,但苹果:0,桃子:0,梨:50,橘子:50,因为我们把最小值设为25)。如果运行此示例,返回的正确项目数将为1771 有没有办法提前计算而不是运行实际的程序?我有一个程序需要做预计算,我正试图找到理想的组合,所以我想写一个程序,给我正确的输出,然后我会对输入进行蒙特卡罗模拟,找到我喜欢的项目/范围的组合 这是我使用的程序(在我的情况下,当顶部波段从未使用时,它可以工作,但如果范围是tigher,1-4,则它不工作,因为它给我的组合没有考虑范围): 这给了我正确的答案(1771),因为它不需要考虑最大值(60),因为它从未达到(它只使用20作为输入)。但是,有没有一种方法可以修改这个公式(或者使用其他方法)来告诉我,如果我有40个项目,范围是2-5,或者其他什么东西(也可以考虑最大值),那么预期的结果是多少Algorithm 使用边界查找前提数的算法?,algorithm,Algorithm,我想知道是否有一种算法可以告诉我,如果我在边界内寻找排列,会得到多少结果 我有一个寻找组合的程序。最好的解释方法是举个例子,假设你有4件东西想在商店买:苹果、桃子、梨和橘子。你想知道每个篮子能装多少百分比,但你告诉自己,你想每个篮子最少装20个,每个篮子最多装60个(所以苹果:25,桃子:25,梨:25,橘子:25效果很好,但苹果:0,桃子:0,梨:50,橘子:50,因为我们把最小值设为25)。如果运行此示例,返回的正确项目数将为1771 有没有办法提前计算而不是运行实际的程序?我有一个程序需要
有没有一种算法可以满足我的要求 您可以使用包含排除原则找到数字。假设
distributions(itemCount,bucketCount)
是itemCount
项到bucketCount
存储桶的无限制分发数。我忽略了下限,因为这是通过减去bucketCount*lowerLimit
项来处理的
将itemCount
项目分配到bucketCount
存储桶(每个存储桶最多包含upperLimit
项目)的方法的数量是无限制分配的数量减去至少一个存储桶包含超过upperLimit
项目的无限制分配的数量。后者可用包含排除原则计算,如下所示:
- 有
选择的存储桶至少包含bucketCount
项,还有upperLimit+1
项要分发到itemCount-(upperLimit+1)
存储桶:bucketCount
必须从无限制分发的数量中减去bucketCount * distributions(itemCount - (upperLimit+1), bucketCount)
- 但是我们已经减去了两个bucket包含超过
项的分布两次,我们必须纠正这一点并加上上限
同样,因为有两个桶的nCr(bucketCount,2) * distributions(itemCount - 2*(upperLimit+1), bucketCount)
选择nCr(bucketCount,2)
- 但是我们已经减去了三个桶中包含超过
项的分布三次,然后再加三次(上限
),所以我们必须减去nCr(3,2)
纠正这一点。等等nCr(bucketCount,3) * distributions(itemCount - 3*(upperLimit+1), bucketCount)
m
∑ (-1)^k * nCr(bucketCount,k) * distributions(itemCount - k*(upperLimit+1), bucketCount)
k=0
在哪里
(因为无法分配负数的项目)
更正了gist中的代码,实现了计算项目分配方式的函数,包括下限和上限:
import math
def nCr(n,r):
f = math.factorial
return f(n) / f(r) / f(n-r)
def itemCount_cal(target, items, minValue):
return target- items*minValue
def distributions(itemCount, bucketCount):
# There's one way to distribute 0 items to any number of buckets: all get 0 items
if itemCount == 0:
return 1
# we can't distribute fewer than 0 items, and we need at least one bucket
if itemCount < 0 or bucketCount < 1:
return 0
# If there's only one bucket, there's only one way
if bucketCount == 1:
return 1
#get all possible solutions
# The number of ways to distribute n items to b buckets is
# nCr(n+b-1,n)
f = math.factorial
return f(itemCount + bucketCount-1)/(f(itemCount) * f(bucketCount-1))
def ways(items,buckets,lower,upper):
if upper < lower: # upper limit smaller than lower: impossible
return 0
if buckets*upper < items: # too many items: impossible
return 0
necessary = buckets*lower
if items == necessary: # just enough items to meet the minimum requirement
return 1
if items < necessary: # too few items: impossible
return 0
# put the minimum required number in each bucket, leaving
# items - necessary
# to distribute
left = items - necessary
# We have put 'lower' items in each bucket, so each bucket can now take
# at most (upper - lower) more
# any more, and the bucket is overfull
over = upper + 1 - lower
# maximal number of buckets we can put more than upper in at all
# after we fulfilled the minimum requirement
m = left // over
# We start with the number of ways to distribute the items disregarding
# the upper limit
ws = distributions(left,buckets)
# Sign for inclusion-exclusion, (-1)**k
sign = -1
# Number of overfull buckets
k = 1
while k <= m:
# Add or subtract the number of ways to distribute
# 'left' items to 'buckets' buckets with
# k buckets overfull
#
# nCr(buckets,k) choices of the buckets we overfill at the start
#
# That leaves (left - k*over) items to distribute.
ws += sign * nCr(buckets,k) * distributions(left - k*over,buckets)
# flip sign and increment number of overfull buckets
sign = -sign
k += 1
return ws
导入数学
def nCr(n,r):
f=数学阶乘
返回f(n)/f(r)/f(n-r)
def itemCount_cal(目标、项目、最小值):
返回目标-项目*最小值
def分配(itemCount、bucketCount):
#有一种方法可以将0个项目分配到任意数量的bucket:all get 0个项目
如果itemCount==0:
返回1
#我们不能分发少于0个项目,我们至少需要一个存储桶
如果itemCount<0或bucketCount<1:
返回0
#如果只有一个水桶,只有一条路
如果bucketCount==1:
返回1
#获得所有可能的解决方案
#将n个项目分配到b个存储桶的方法数为
#不合格报告(n+b-1,n)
f=数学阶乘
返回f(项目计数+bucketCount-1)/(f(项目计数)*f(bucketCount-1))
def通道(项目、铲斗、下部、上部):
如果上限<下限:#上限小于下限:不可能
返回0
如果桶*上部<项目:#项目太多:不可能
返回0
必要=铲斗*较低
如果项目==必要:#刚好足够满足最低要求的项目
返回1
如果项目<必要:#项目太少:不可能
返回0
#在每个桶中放入所需的最小数量,留下
#项目-必要
#分发
左=项目-必要
#我们在每个桶中放入了“较低”的物品,因此每个桶现在都可以
#最多(上-下)更多
#再多的话,桶就满了
上方=上方+1-下方
#我们可以放入的桶的最大数量超过上限
#在我们达到最低要求之后
m=剩余//剩余
#我们首先介绍了分配项目的方法的数量
#上限
ws=分布(左,桶)
#包含排除符号,(-1)**k
符号=-1
#满桶数
k=1
而k是您最初示例中篮子的容量100个项目?在您编写的程序中,听起来好像您在说您的购物篮容量为20,您在4种商品类型中进行选择,这与说每个商品至少有计数20,您的购物篮容量为100是一样的。我认为您应该停止在示例中使用百分比,因为实际上,你只需要对正整数进行这些运算。只要说你想要100个项目,其中25个是苹果等等…无论如何+1,我希望看到一个t的封闭公式
m = min { bucketCount, floor(itemCount/(upperLimit+1)) }
import math
def nCr(n,r):
f = math.factorial
return f(n) / f(r) / f(n-r)
def itemCount_cal(target, items, minValue):
return target- items*minValue
def distributions(itemCount, bucketCount):
# There's one way to distribute 0 items to any number of buckets: all get 0 items
if itemCount == 0:
return 1
# we can't distribute fewer than 0 items, and we need at least one bucket
if itemCount < 0 or bucketCount < 1:
return 0
# If there's only one bucket, there's only one way
if bucketCount == 1:
return 1
#get all possible solutions
# The number of ways to distribute n items to b buckets is
# nCr(n+b-1,n)
f = math.factorial
return f(itemCount + bucketCount-1)/(f(itemCount) * f(bucketCount-1))
def ways(items,buckets,lower,upper):
if upper < lower: # upper limit smaller than lower: impossible
return 0
if buckets*upper < items: # too many items: impossible
return 0
necessary = buckets*lower
if items == necessary: # just enough items to meet the minimum requirement
return 1
if items < necessary: # too few items: impossible
return 0
# put the minimum required number in each bucket, leaving
# items - necessary
# to distribute
left = items - necessary
# We have put 'lower' items in each bucket, so each bucket can now take
# at most (upper - lower) more
# any more, and the bucket is overfull
over = upper + 1 - lower
# maximal number of buckets we can put more than upper in at all
# after we fulfilled the minimum requirement
m = left // over
# We start with the number of ways to distribute the items disregarding
# the upper limit
ws = distributions(left,buckets)
# Sign for inclusion-exclusion, (-1)**k
sign = -1
# Number of overfull buckets
k = 1
while k <= m:
# Add or subtract the number of ways to distribute
# 'left' items to 'buckets' buckets with
# k buckets overfull
#
# nCr(buckets,k) choices of the buckets we overfill at the start
#
# That leaves (left - k*over) items to distribute.
ws += sign * nCr(buckets,k) * distributions(left - k*over,buckets)
# flip sign and increment number of overfull buckets
sign = -sign
k += 1
return ws