how do I limit the number of unique parameters

I would like to limit up to 4 picks to maximize the sum.

set i index of elements in the matrix /1*11/
parameter A(i) the row matrix
/1 0
2 -2
3 3
4 0
5 5
6 6
7 7
8 -8
9 9
10 -10
11 11/
;


Variables
     total;

binary variable pick(i);

Equations
     cost_func        define objective function
     limit_selection;

cost_func ..        total  =e=  sum(i, pick(i) * A(i));
limit_selection .. card(pick) =l= 4;

Model alveva /all/;

Solve alveva using MINLP maximizing total;
display total.l, total.m;

I was expecting total of 11 + 9 + 7 + 6 = 33, but the result shows 11 + 9 + 7 + 6 + 5 + 3 = 41. Additionally card(pick) is 0 in my constraint equation.

Can anyone help me fix this?

It helps to look at the equation listing. You equation limit_selection reads there:

---- limit_selection  =L=  
                NONE

The reason is that card(sym) gives you the number of records in a symbol. Since at the start of model generation there are no variable records in pick (they are all at default value) you constraint evaluates to 0 <= 4 which is always true. What you want to do is:

limit_selection .. sum(i, pick(i)) =l= 4;

If you do that you get what you expect:

----     32 VARIABLE pick.L  
6  1.000,    7  1.000,    9  1.000,    11 1.000

----     32 VARIABLE total.L               =       33.000  
            VARIABLE total.M               =        0.000

-Michael

I’m grateful of your help. I understand a bit more of GAMS now :slight_smile:.

I started learning this yesterday and everything is new to me.

If pick(i) is nonbinary(could be any integer), how should I write the constraint equation such that there are at most 4 unique values in pick(i)?

If pick(i) is nonbinary(could be any integer), how should I write the constraint equation such that there are at most 4 unique values in pick(i)?

I don’t understand the question. pick(i) is a set of variables and for every i they take a value. What constraint to you want to enforce on these |i| values?

-Michael

There might be smarter ways doing this, but here is one which requires the integer range that pick(i) can take is limited between lets say 1 and K. In this case you introduce |i|*K binary variables b(i,k) and K variables y(k) with pick(i) =e= sum(k, b(i,k)ord(k)); for all i and sum(k, b(i,k)) =e= 1 for all i and sum(i, b(i,k)) =l= Ky(k) for all k and sum(k, y(k)) =l= 4; With b(i,k) you pick one of the ks for the value pick(i). The y(k) indicates if a k has been picked by any k and that you can now limit by 4.

-Michael