0

Question:

Minimising x1+x2+...+xn

Known k1*x1+k2*x2+...kn*xn = T

k1,k2,...,kn and T are known integers and > 0

k1 > k2 > k3 > ... > kn

All the x are also integers and >= 0

Find all the x

I was trying to use Rglpk and Glpk. But I can't find an example with only one row of matrix. Is this Integer programming? And is it solvable? Many thanks.


Some Ruby codes I wrote:

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
Ivan Wang
  • 8,306
  • 14
  • 44
  • 56

1 Answers1

3

Yes, it is an integer program, a rather famous one, the so-called "knapsack problem". You therefore can solve it with either of the packages you mention (provided the number of variables is not too great) but a much more efficient approach is to use dynamic programming (see the above link). The use of DP here is quite simple to implement. This is one Ruby implementation I found by Googling.

I should mention a few related tidbits. Firstly, your constraint is an equality constraint:

k1x1 + k2x2 +...+ knxn = T

but this is normally assumed to be an inequality by (DP) knapsack algorithms:

k1x1 + k2x2 +...+ knxn <= T

To deal with an equality constraint you can either modify the algorithm slightly, or add the term:

M*(T - x1 + x2 +...+ xn)

to the objective you are minimizing, where M is a very large number (106, perhaps), thereby forcing equality at the optimal solution. (When expanded, the coefficient for each xi becomes 1-M. The constant term MT can be disregarded.)

Two more details:

  • DP algorithms permit the variables in the objective to have coefficients other than 1 (and there is no gain in efficiency when all the coefficients equal 1); and
  • If the DP algorithm maximizes (rather than minimizes) the objective, you can simply negate the coefficients of the variables in the objective to obtain an optimal solution to the minimization problem.
Cary Swoveland
  • 106,649
  • 6
  • 63
  • 100
  • Thanks Cary. I got stuck at understanding how to modify the example to have non 1-0 coefficients. I can't find any example online that has knapsack with non 1-0 integers coefficients. Can you elaborate more please? – Ivan Wang Sep 07 '15 at 23:44
  • Conceptually there is no problem having any values as coefficients in the objective, but you can always convert a problem with varying objective coefficients to an equivalent problem with objective coefficients that are all `0` or `1`. Suppose `x` is the number litres of beer you can put in the knapsack, the objective value is `2` per litre and the coefficient in the constraint is `3` per litre. You can then just re-scale to have `x` be the number of half-litres of beer, in which case the coefficient in the objective would be `1` and the coefficient in the constraint would be `3/2 #=> 1.5`. – Cary Swoveland Sep 08 '15 at 00:32
  • Sorry, I'm confused. So are you suggesting take the problem as a fractional knapsack problem? But the original question requirement is that all the `x`s are integers. – Ivan Wang Sep 08 '15 at 00:44
  • No, the variables must all be non-negative integers. I was referring to their coefficients in the objective (e.g, for `2x`, `2` is `x`'s coefficient. I explained that there is no loss of generality by assuming all coefficients equal `1` (because you can scale them) but maybe you weren't asking about that. – Cary Swoveland Sep 08 '15 at 00:51
  • Oh, I think I am getting close to understand what you mean now. So using the traditional 0-1 method can solve the non 0-1 questions like this one? I am struggling at figuring how I should modify the `[ c[i,j], c[i-1,j-1] + k[j] ].max` part as now the `k`s are reusable. Would you give me more clues please? – Ivan Wang Sep 08 '15 at 01:26
  • For example, should I write `c[3,1] = [ c[2,1], c[2,1]+k[0], c[2,1]+k[1], c[2,1]+k[2], c[2,1]+k[3], c[2,1]+k[0]+k[1], c[2,1]+k[1]+k[2], c[2,1]+k[2]+k[3], c[2,1]+k[3]+k[4], .... , c[2,1]+k[0]+k[1]+k[2]+k[3]+k[4] ].max`? – Ivan Wang Sep 08 '15 at 01:56
  • 1
    I can get to your last two comment until tomorrow, but I noticed that `problem.set_matrix(ks)` should probably be `problem.set_matrix([ks])`. – Cary Swoveland Sep 08 '15 at 03:28
  • Thank you Cary. I will wait for you then. `problem.set_matrix([ks])` gives me error: "in `doubleArray_setitem': Expected argument 2 of type double" – Ivan Wang Sep 08 '15 at 04:20
  • Without reading the docs for Rglpk, I would guess that all values are expected to be floats (though it would be easy enough to apply `to_f`), so I suggest you write `ks = [33.0, 18.0, 15.0, 5.0, 3.0]`, `t = 999.0` and `problem.obj.coefs = Array.new(ks.size, 1.0)`. `set_matrix` should have an argument that is an array of rows, where each row is an array, so (because there is just one row) you need `problem.set_matrix([ks])`. I don't understand your third sentence, as you make no reference to `c[i,j]`. – Cary Swoveland Sep 08 '15 at 22:31