## Single dimension Constraint on two dimensional Optimization Problem

I have below data:

id \$ cost profit_1 profit_2 score;
A -1 10 11 500
B -0.6 10 5 700
C -0.75 10 10.5 700
D -0.75 10.5 10 600
E -0.65 12 11 300
F -0.65 12 13 350;
Following code does the work when considering profits only:

proc optmodel;
set <str> ITEMS;
num cost {ITEMS};
set CASES = 1..2;
num profit {ITEMS, CASES};
read data have into ITEMS=[id] cost {j in CASES} <profit[id,j]=col('profit_'||j)>;
var X {ITEMS, CASES} binary;
max TotalProfit = sum {i in ITEMS, j in CASES} profit[i,j] * X[i,j];
con ChooseOne {i in ITEMS}: sum {j in CASES} X[i,j] <= 1;
con Budget: sum {i in ITEMS, j in CASES} cost[i] * X[i,j] <= 1.5;
solve;
print X;
quit;

but I want to add another constraint on score.
Something like SCORE must be greater than 500, i tried inserting following -
num score {ITEMS}

then in read data statement- SCORE[id] = col('SCORE')

And finally the constraint- con MinScore SCORE{i in ITEMS}: SCORE[id]>=500

but this is leading to infeasible solution because of cases where SCORE >=500.

Can anyone help in how to do this and what am I doing wrong?

1 ACCEPTED SOLUTION

Accepted Solutions

## Re: Single dimension Constraint on two dimensional Optimization Problem

Here are four ways, in increasing order of efficiency.

1. Impose explicit constraint:

``````/* if X[i,j] = 1 then score[i] >= 500 */
con MinScore {i in ITEMS, j in CASES}: score[i] >= 500 * X[i,j];``````

2. Fix variables to 0:

``````/* if score[i] < 500 then X[i,j] = 0 */
for {i in ITEMS: score[i] < 500} for {j in CASES} fix X[i,j] = 0;``````

3. Modify index set after reading data:

``````read data have into ITEMS=[id] cost score {j in CASES} <profit[id,j]=col('profit_'||j)>;
ITEMS = {i in ITEMS: score[i] >= 500};``````

4. Use WHERE= in READ DATA:

``````read data have(where=(score >= 500)) into ITEMS=[id] cost score {j in CASES} <profit[id,j]=col('profit_'||j)>;
``````

4 REPLIES 4

## Re: Single dimension Constraint on two dimensional Optimization Problem

Here are four ways, in increasing order of efficiency.

1. Impose explicit constraint:

``````/* if X[i,j] = 1 then score[i] >= 500 */
con MinScore {i in ITEMS, j in CASES}: score[i] >= 500 * X[i,j];``````

2. Fix variables to 0:

``````/* if score[i] < 500 then X[i,j] = 0 */
for {i in ITEMS: score[i] < 500} for {j in CASES} fix X[i,j] = 0;``````

3. Modify index set after reading data:

``````read data have into ITEMS=[id] cost score {j in CASES} <profit[id,j]=col('profit_'||j)>;
ITEMS = {i in ITEMS: score[i] >= 500};``````

4. Use WHERE= in READ DATA:

``````read data have(where=(score >= 500)) into ITEMS=[id] cost score {j in CASES} <profit[id,j]=col('profit_'||j)>;
``````

## Re: Single dimension Constraint on two dimensional Optimization Problem

Thanks a lot for your response. I was able to do 3 and 4, but it was subsetting my observations in output, so wasn't inclined. Finally I found 2 but was quite sure that this can be done in CON statement. Thanks again for 1. Very grateful for what I am learning from you.

## Re: Single dimension Constraint on two dimensional Optimization Problem

Glad to help.  By the way, because of the ChooseOne constraint, you can tighten the MinScore constraint as follows:

``con MinScore {i in ITEMS}: score[i] >= 500 * sum {j in CASES} X[i,j];``

In either case, the MILP presolver will force X[i,j] to 0 if score[i] < 500.

## Re: Single dimension Constraint on two dimensional Optimization Problem

Thanks again 🙂
Discussion stats
• 4 replies
• 644 views
• 2 likes
• 2 in conversation