Search code examples
mathematical-optimizationlinear-programmingpyomointeger-programming

How to count distinct number of decision variables - Linear programming


I have 5 decision variables (say) x1 - x5, lower bound for each = 5, and upper bound for each = 30 and they are allowed to take only integer values. These decision variables are leveraged to calculate gross margin (via some function), and objective function is to maximize gross margin.

Now, while choosing optimal values for x1 - x5, I have a constraint that I should not have more than 2 (say) distinct values for x1 - x5.

Can anybody please help me as to how I can formulate the above constraint, i.e. count of distinct decision variables values <= 2. I am trying to build the program in pyomo.

Thank you.


Solution

  • There are different ways to model this. Here is an easy approach. First introduce binary variables:

      y(i,k) = 1  if x(i)=k    i=1,..,5, k=5,...,30
               0  otherwise
    

    This means we can write:

      x(i) = sum(k, k*y(i,k))
      sum(k, y(i,k)) = 1       for all i
    

    to link x and y. Now introduce the binary variable:

      z(k) = 1   if some x(i)=k
             0   otherwise  (actually we will allow 0 or 1 when all x(i)<>k, see below)
    

    We want max 2 of them to be 1. This can be stated succinctly as:

      z(k) >= y(i,k)       for all i,k
      sum(k, z(k)) <= 2 
    

    Notice that this is just a bound. We have

      y(i,k) = 1  ==> z(k) = 1
    

    but actually we don't require:

      y(i,k) = 0  ==> z(k) = 0
    

    but that is good enough for this particular case. So when printing z be advised its values may be a bit difficult to interpret.

    Some of the variables can be relaxed to be continuous. That may save a bit on the number of integer/binary variables. Whether this is advantageous for the solver is not always clear, and may require some experimentation.

    *update: Added missing constraint