Search code examples
mathematical-optimizationampl

AMPL minimizing the sum of integers in a set and number of chosen elements


Previously, I posted a question where I asked about how to select a minimum number of Integers from a set, and having a sum >= a constant. My code was as shown:

option solver cplex;
set x:= {4, 5, 7, 1};
param c:= 10;
var u{x} binary;
minimize output : sum {i in x} u[i];
subject to constraint: sum {i in x} u[i]*i >= c;
solve;
display u;

I decided to add a new objective of minimizing the sum as well. In the previous example, cplex produces 12 (7 and 5). I want it to produce 11 (7 and 4). For this purpose, I added this objective:

minimize output : sum {i in x} u[i]*i;

Unfortunately, I have a student edition of AMPL, so I cant use 2 objectives. Now my new code will solve the problem but I want to ask if there is a work around or a trick to combine the 2 objectives into 1 yet still having the same functionality.

EDIT: I'm more interested in minimizing number of elements then to minimize the sum.


Solution

  • I found out a way to solve my problem. I would like to share it with you guys.

    option solver cplex;
    set x:= {4, 5, 7, 1};                                                #this is the set where I want to chose the integers from.
    param c:= 10;                                                        #this is the constant i want the sum to be >= to.
    param MinNumberOfELements;                                           #this will be used later. Explanation will be added then.
    var u{x} binary;                                                     #binary array, indicates the corresponding elements in x is used.  u[4] = 1 -->  4 is taken in the output
    minimize output : sum {i in x} u[i];                                 #here we minimize number of taken elements without caring of minimizing the sum
    subject to constraint: sum {i in x} u[i]*i >= c;                     # the sum must be >= to the constant c.
    solve;                                                               #this will cause the objective "output" to have some value
    
    let MinNumberOfELements := output;                                   # take the value of "output" and store it in this param.
    drop output;                                                         #since we can have only 1 objective, we drop the old one.
    
    minimize output2: sum {i in x} u[i]*i;                               # in this step, we minimize the sum
    subject to constraint2: sum {i in x} u[i] = MinNumberOfELements;     #number of elements chosen must be = to MinNumberOfELements
    solve;
    display output2,u;
    

    I hope you find it helpful.