Python:运行受约束的所有整数组合(查找函数的最小值)
我想找到一种方法来返回所有向量的集合[x_1,…,x_n],受约束x_1+…+x_n=常数,每个x_I是一个非负整数,顺序无关紧要。(因此[1,1,1,2]=[2,1,1,1])。我几乎没有编程经验,但在过去的一个月左右,我一直在使用Python(sage) 特别是,我试图找到一个15变量(对称)函数在非负整数上的最小值(受约束),但我想写一个程序来实现它,因为我也可以将它用于类似的项目 我已经试着写了4天的程序了,我突然意识到我必须以某种方式递归地定义我的函数……我不知道该怎么做。我有一个代码,它可以做一些类似于我想要做的事情(但它还没有完成)。即使我确信这是我想做的事情中效率最低的一种方式,我还是会发布它:Python:运行受约束的所有整数组合(查找函数的最小值),python,integer,constraints,Python,Integer,Constraints,我想找到一种方法来返回所有向量的集合[x_1,…,x_n],受约束x_1+…+x_n=常数,每个x_I是一个非负整数,顺序无关紧要。(因此[1,1,1,2]=[2,1,1,1])。我几乎没有编程经验,但在过去的一个月左右,我一直在使用Python(sage) 特别是,我试图找到一个15变量(对称)函数在非负整数上的最小值(受约束),但我想写一个程序来实现它,因为我也可以将它用于类似的项目 我已经试着写了4天的程序了,我突然意识到我必须以某种方式递归地定义我的函数……我不知道该怎么做。我有一个代码
def each_comb_first_step(vec):
row_num=floor(math.fabs((vec[0,vec.ncols()-1]-vec[0,vec.ncols()-2]))/2)+1
mat=matrix(ZZ, row_num, vec.ncols(), 0)
for j in range(row_num):
mat[j]=vec
vec[0,vec.ncols()-2]=vec[0,vec.ncols()-2]+1
vec[0,vec.ncols()-1]=vec[0,vec.ncols()-1]-1
return mat
def each_comb(num,const):
vec1=matrix(ZZ,1,num,0)
vec1[0,num-1]=const
time=0
steps=0
subtot=0
for i in (2,..,num-1):
steps=floor(const/(i+1))
for j in (1,..,steps):
time=j
for k in (num-i-1,..,num-2):
vec1[0,k]=time
time=time+1
subtot=0
for l in range(num-1):
subtot=subtot+vec1[0,l]
vec1[0,num-1]=const-subtot
mat1=each_comb_first_step(vec1)
return mat1
是否有一个函数已经实现了这一点,或者类似的功能?如有任何帮助或建议,我们将不胜感激。暴力解决方案如下:
import itertools as it
# Constraint function returns true if inputs meet constraint requirement
def constraint(x1, x2, x3, x4):
return x1 + x2 + x3 + x4 == 10
numbers = range(1,10) #valid numbers (non-negative integers)
num_variables = 4 #size of number tuple to create
#vectors contains all tuples of 4 numbers that meet constraint
vectors = [t for t in it.combinations_with_replacement(numbers, num_variables)
if constraint(*t)]
print vectors
输出
[(1, 1, 1, 7), (1, 1, 2, 6), (1, 1, 3, 5), (1, 1, 4, 4), (1, 2, 2, 5), (1, 2, 3, 4), (1, 3, 3, 3), (2, 2, 2, 4), (2, 2, 3, 3)]
运行时间是O(数字**num\u变量)
,因此使用15个变量的解决方案可能会非常慢。您可能需要研究线性规划技术。库塞拉网站上有一个免费课程,可以用来更快地解决这类问题
查看此链接以获得指向python模块的链接,该模块是一个整数约束解算器 要查找给定整数的所有固定长度。这可以迭代或递归地完成。递归算法背后的思想是添加一个helper参数,表示分区中允许的值的下限。然后,对于分区中每个可能的最小值,进行递归调用,以找出构造分区其余部分的方法
def fixed_length_partitions(n, k, min_value=0):
"""Yields all partitions of the integer n into k integers."""
if k == 0:
if n == 0:
yield []
else:
for last_num in range(min_value, 1 + n//k):
for nums in _flps(n-last_num, k-1, min_value=last_num):
# Warning: mutative
nums += [last_num]
yield nums
_flps = fixed_length_partitions
迭代算法将更快(避免大量Python函数调用开销),但可读性也更低,因为它基本上会用显式列表替换Python调用堆栈,并最终使控制流更加混乱。请重新编写代码,我怀疑return语句不在for循环中。您还可以提供一个使用您的功能的示例。在
itertools
模块中,签出带有替换的组合。