Hello,
I am writing a optmodel procedure, with the following constraint, the optimal solution is infeasible:
con unit_con{c in bucket, a in AMOUNTS}: unit[c,a] * Move[c,a] >= 50;
However, without the above constraint, solution is more reasonable.
What I want to do is to tell the model that if a cell has less than 50 units than don't consider this cell.
The full code is here:
proc optmodel;
/* Index Sets */
set bucket;
set AMOUNTS=2000..17000 by 1000;
/* Parameters */
number orig_amount {bucket, AMOUNTS} init 0;
number loss_amount {bucket, AMOUNTS} init 0;
number profit {bucket, AMOUNTS} init 0;
number unit {bucket, AMOUNTS} init 0;
/* Binary decision variables--approve (1) or deny (0) an amount per customer */
var Move {bucket, AMOUNTS} binary;
read data GRP1 nomiss
into bucket=[BK_Group]
{a in AMOUNTS} < orig_amount[BK_Group,a]=col("OR"||a)
loss_amount[BK_Group,a]=col("LO"||a)
profit[BK_Group,a]=col("PR"||a)
unit[BK_Group,a]=col("UN"||a)>;
print unit;
print move;
print profit;
print orig_amount;
/* Set up amount max and profit max objectives */
min Total_delta_loss = sum{c in bucket, a in AMOUNTS} loss_amount[c,a] * Move[c,a];
/* Approve at most one loan amount per group */
con One_Amount_con{c in bucket}: sum{a in AMOUNTS} Move[c,a] <= 1;
con worse_con{i in bucket, j in AMOUNTS, k1 in 1..(10-i), k2 in 1000..(17000-j) by 1000}: Move[i,j] + Move[i+k1, j+k2] <= 1;
/*con unit_con{c in bucket}: sum{a in AMOUNTS} unit[c,a] * Move[c,a] >= 20;*/
impvar Total_delta_orig = sum{c in bucket, a in AMOUNTS} orig_amount[c,a] * Move[c,a];
impvar Total_Profit = (Total_delta_orig - Total_delta_loss) * 0.45924 - Total_delta_loss;
/* profit constraint: loss no more than 200,000 of profit */
con profit_con: Total_Profit >= -200000;
con unit_con{c in bucket, a in AMOUNTS}: unit[c,a] * 1 >= 50;
problem Problem1 include
Move
Total_delta_loss
unit_con
One_Amount_con profit_con worse_con
;
use problem Problem1;
solve;
print Move;
create data solution
from [BK_Group LO]
={c in bucket, g in AMOUNTS: Move[c,g]^=0}
amount=Move;
print Total_Profit;
print Total_delta_orig;
quit;
Any help is appreciated!
Lucas
I figured out myself.
The constraint should be this:
con unit_con{c in bucket}: sum{a in AMOUNTS} (unit[c,a] * Move[c,a]) >= sum{a in AMOUNTS}(50 * Move[c,a]);
Can you please share the data?
unit | ||||||||||||||||
2000 | 3000 | 4000 | 5000 | 6000 | 7000 | 8000 | 9000 | 10000 | 11000 | 12000 | 13000 | 14000 | 15000 | 16000 | 17000 | |
1 | 109 | 165 | 218 | 129 | 169 | 222 | 184 | 146 | 109 | 90 | 241 | 57 | 29 | 22 | 12 | 15 |
2 | 108 | 145 | 223 | 126 | 116 | 170 | 153 | 96 | 96 | 64 | 192 | 40 | 24 | 16 | 9 | 8 |
3 | 65 | 134 | 171 | 113 | 101 | 155 | 128 | 104 | 79 | 44 | 138 | 39 | 13 | 13 | 10 | 1 |
4 | 59 | 123 | 143 | 92 | 99 | 129 | 113 | 82 | 81 | 49 | 123 | 31 | 11 | 10 | 9 | 1 |
5 | 45 | 121 | 152 | 96 | 89 | 118 | 118 | 69 | 61 | 50 | 99 | 24 | 6 | 6 | 10 | 3 |
6 | 52 | 122 | 125 | 79 | 67 | 125 | 75 | 62 | 49 | 37 | 96 | 18 | 15 | 5 | 6 | 1 |
7 | 47 | 104 | 125 | 69 | 68 | 130 | 101 | 65 | 59 | 42 | 88 | 16 | 13 | 10 | 5 | 5 |
8 | 50 | 89 | 125 | 65 | 67 | 119 | 84 | 55 | 54 | 33 | 75 | 20 | 12 | 8 | 4 | 3 |
9 | 50 | 89 | 109 | 49 | 57 | 113 | 72 | 52 | 35 | 31 | 56 | 8 | 7 | 9 | 3 | 0 |
10 | 21 | 51 | 60 | 50 | 31 | 102 | 54 | 38 | 26 | 34 | 35 | 13 | 8 | 6 | 3 | 0 |
and this is the structure of Move:
Move | ||||||||||||||||
2000 | 3000 | 4000 | 5000 | 6000 | 7000 | 8000 | 9000 | 10000 | 11000 | 12000 | 13000 | 14000 | 15000 | 16000 | 17000 | |
1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
2 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
3 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
4 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
5 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
6 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
7 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
8 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
9 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
10 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
And Move is supposed to be a matrix with 1s and 0s
I figured out myself.
The constraint should be this:
con unit_con{c in bucket}: sum{a in AMOUNTS} (unit[c,a] * Move[c,a]) >= sum{a in AMOUNTS}(50 * Move[c,a]);
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
Learn how to run multiple linear regression models with and without interactions, presented by SAS user Alex Chaplin.
Find more tutorials on the SAS Users YouTube channel.