问题:
最小化x1+x2+...+xn
已知k1*x1+k2*x2+...kn*xn = T
k1,k2,...,kn
和T
是已知的整数,> 0
k1 > k2 > k3 > ... > kn
所有x也是整数,> = 0
查找所有x
我试图使用Rglpk和Glpk。但我找不到只有一行矩阵的例子。这是整数编程吗?它可以解决吗?非常感谢。
我写的一些Ruby代码:
ks = [33, 18, 15, 5, 3]
t = 999
problem = Rglpk::Problem.new
problem.name = "test"
problem.obj.dir = Rglpk::GLP_MIN
rows = problem.add_rows(1)
rows[0].name = "sum of x equals t"
rows[0].set_bounds(Rglpk::GLP_UP, t, t)
cols = problem.add_cols(ks.size)
ks.each_with_index do |k,index|
cols[index].name = "k: #{k}"
cols[index].set_bounds(Rglpk::GLP_LO, 0.0, 0.0)
end
problem.obj.coefs = Array.new(ks.size, 1)
problem.set_matrix(ks)
problem.simplex
minimum_x_sum = problem.obj.get
xs = []
cols.each do |col|
xs << col.get_prim
end
xs
答案 0 :(得分:2)
是的,它是一个整数程序,一个相当着名的程序,即所谓的&#34; knapsack problem&#34;。因此,您可以使用您提到的任何一个包来解决它(假设变量的数量不是太大),但更有效的方法是使用动态编程(参见上面的链接)。这里使用DP非常简单。 This是我通过Googling找到的一个Ruby实现。
我应该提一些相关的花絮。首先,您的约束是一个等式约束:
k 1 x 1 + k 2 x 2 + ... + k n x n = T
但通常认为这是(DP)背包算法的不等式:
k 1 x 1 + k 2 x 2 + ... + k n x n &lt; = T
要处理等式约束,您可以稍微修改算法,或添加术语:
M *(T - x 1 + x 2 + ... + x n )
到最小化的目标,其中M
是一个非常大的数字(可能是10 6 ),从而在最优解决方案中强制平等。 (扩展时,每个x i 的系数变为1-M
。常数项MT
可以忽略不计。)
另外两个细节:
1
以外的系数(当所有系数等于1
时,效率没有增益);和