Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Python中有效地获得总和为10或以下的所有组合_Python_Itertools - Fatal编程技术网

如何在Python中有效地获得总和为10或以下的所有组合

如何在Python中有效地获得总和为10或以下的所有组合,python,itertools,Python,Itertools,假设您正试图在一些地区(例如t=5)上分配一些固定资源(例如n=10)。我试图找出如何有效地获得总和n或以下的所有组合 例如,10,0,0,0,0是好的,以及0,0,5,5,0等,而3,3,3,3,3显然是错误的 我走了这么远: import itertools t = 5 n = 10 r = [range(n+1)] * t for x in itertools.product(*r): if sum(x) <= n: print x 可能的

假设您正试图在一些地区(例如
t=5
)上分配一些固定资源(例如
n=10
)。我试图找出如何有效地获得总和
n
或以下的所有组合

例如,
10,0,0,0,0
是好的,以及
0,0,5,5,0
等,而
3,3,3,3,3
显然是错误的

我走了这么远:

import itertools
t = 5
n = 10
r = [range(n+1)] * t
for x in itertools.product(*r): 
   if sum(x) <= n:          
       print x

可能的办法如下。肯定会小心使用(几乎没有测试过,但n=10和t=5的结果看起来合理)

该方法不涉及递归。生成具有m个元素(示例中为5个)的数字n(示例中为10)的分区的算法来自Knuth的第4卷。如果需要,每个分区都会进行零扩展,所有不同的排列都是使用Aaron Williams的算法生成的,我已经看到了这个算法。这两种算法都必须翻译成Python,这增加了出错的可能性。Williams算法需要一个链表,为了避免编写链表类,我不得不用2D数组来伪造链表

有一个下午了

Code(注意您的n是我的maxn,您的t是我的p):

导入itertools
def访问(上午、下午):
“”“将分区添加到列表的实用程序函数”“”
x、 追加(a[1:m+1])
def部件(a、n、m):
“Knuth算法H,组合算法,前分册3B
查找n个元素正好有m个元素的所有分区。
运行时间的上限为(3 x
找到分区)+m。不是递归的!
"""
而(一):
参观(上午、下午)
当a[2]=a[1]-1时:
s+=a[j]
j+=1
如果j>m:
打破
x=a[j]+1
a[j]=x
j-=1
当j>1时:
a[j]=x
s-=x
j-=1
a[1]=s
def distinct_perms(分区):
“Aaron Williams算法1,”多重集的无环生成
按前缀移位排列“。查找所有不同的排列
一张有重复项目的清单。我不完全按照报纸上说的去做
嗯,但它可能有一个成比例的运行时间
到置换的数量(每个置换有3个移位操作
平均排列)。不是递归的!
"""
perms=[]
val=0
nxt=1
l1=[[i]分区,i+1]表示范围内的i(len(分区))]
l1[-1][nxt]=无
#打印(l1)
水头=0
i=len(l1)-2
afteri=i+1
tmp=[]
tmp+=[l1[头部][val]]
c=头部
而l1[c][nxt]!=无:
tmp+=[l1[c][nxt][val]]
c=l1[c][nxt]
perms.extend([tmp])
而(l1[afteri][nxt]!=None)或(l1[afteri][val]=l1[l1[afteri][nxt][val]):
前后
其他:
beforek=i
k=l1[之前][nxt]
l1[beforek][nxt]=l1[k][nxt]
l1[k][nxt]=水头
如果l1[k][val]=2)
x=[[i]表示范围内的i(maxn+1)]
#主要案例:运行零件fn(最大^2+最大)/2次
对于范围(2,最大值+1)内的i:
对于范围(2,min(p+1,i+1))内的j:
m=j
n=i
a=[0,n-m+1]+[1]*(m-1)+[-1]+[0]*(n-m-1)
零件(a、n、m)
y=[]
#对于每个分区,如果需要,添加零,然后查找
#不同的排列。运行一次distinct_perms函数
#对于每个分区。
对于第x部分:
如果len(部分)
您可以使用动态规划优化算法

基本上,有一个数组
a
,其中
a[i][j]
的意思是“我可以得到
j
的和,其中的元素一直到
j-th
元素(并且使用
jth
元素,假设您的元素在数组
t
(不是您提到的数字))

然后你就可以填充数组了

a[0][t[0]] = True
for i in range(1, len(t)):
    a[i][t[i]] = True
    for j in range(t[i]+1, n+1):
         for k in range(0, i):
             if a[k][j-t[i]]:
                 a[i][j] = True
然后,使用此信息,您可以回溯解决方案:)


创建自己的递归函数,除非可以使sum=0,否则该函数不会与元素一起递归: 收益率 返回 对于r中的x:
如果x>n:#您可以使用
itertools
创建所有排列,并使用
numpy
解析结果

>>> import numpy as np
>>> from itertools import product

>>> t = 5
>>> n = 10
>>> r = range(n+1)

# Create the product numpy array
>>> prod = np.fromiter(product(r, repeat=t), np.dtype('u1,' * t))
>>> prod = prod.view('u1').reshape(-1, t)

# Extract only permutations that satisfy a condition
>>> prod[prod.sum(axis=1) < n]
>>将numpy作为np导入
>>>来自itertools进口产品
>>>t=5
>>>n=10
>>>r=范围(n+1)
#创建产品numpy数组
>>>prod=np.fromiter(product(r,repeat=t),np.dtype('u1,*t))
>>>产品=产品视图('u1')。重塑(-1,t)
#仅提取满足条件的置换
>>>产品[prod.sum(轴=1)
时间:

>>> %%timeit 
    prod = np.fromiter(product(r, repeat=t), np.dtype('u1,' * t))
    prod = prod.view('u1').reshape(-1, t)
    prod[prod.sum(axis=1) < n]

10 loops, best of 3: 41.6 ms per loop
>>%%timeit
prod=np.fromiter(product(r,repeat=t),np.dtype('u1,*t))
产品=产品视图('u1')。重塑(-1,t)
产品[prod.sum(轴=1)

您甚至可以通过以下方式加快乘积计算。

您想找到一个数字的所有和组合吗?@qqvc听起来不错?可能重复?这里的任务是找到所有的和。@Tony虽然有些想法可能适用,但问题是
def backtrack(j = len(t)-1, goal = n):
    print j, goal
    all_solutions = []
    if j == -1:
       return []
    if goal == t[j]:
       all_solutions.append([j])
    for i in range(j-1, -1, -1):
       if a[i][goal-t[j]]:
          r = backtrack(i, goal - t[j])
          for l in r:
              print l
              l.append(j)
              all_solutions.append(l)
    all_solutions.extend(backtrack(j-1, goal))
    return all_solutions


 backtrack() # is the answer
def f(r, n, t, acc=[]):
    if t == 0:
        if n >= 0:
            yield acc
        return
    for x in r:
        if x > n:  # <---- do not recurse if sum is larger than `n`
            break
        for lst in f(r, n-x, t-1, acc + [x]):
            yield lst

t = 5
n = 10
for xs in f(range(n+1), n, 5):
    print xs
>>> import numpy as np
>>> from itertools import product

>>> t = 5
>>> n = 10
>>> r = range(n+1)

# Create the product numpy array
>>> prod = np.fromiter(product(r, repeat=t), np.dtype('u1,' * t))
>>> prod = prod.view('u1').reshape(-1, t)

# Extract only permutations that satisfy a condition
>>> prod[prod.sum(axis=1) < n]
>>> %%timeit 
    prod = np.fromiter(product(r, repeat=t), np.dtype('u1,' * t))
    prod = prod.view('u1').reshape(-1, t)
    prod[prod.sum(axis=1) < n]

10 loops, best of 3: 41.6 ms per loop