BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
Lucassss
Obsidian | Level 7

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

1 ACCEPTED SOLUTION

Accepted Solutions
Lucassss
Obsidian | Level 7

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]); 

View solution in original post

4 REPLIES 4
RobPratt
SAS Super FREQ

Can you please share the data?

Lucassss
Obsidian | Level 7
This is what print unit; produces
 
unit
 200030004000500060007000800090001000011000120001300014000150001600017000
1109165218129169222184146109902415729221215
210814522312611617015396966419240241698
3651341711131011551281047944138391313101
459123143929912911382814912331111091
5451211529689118118696150992466103
652122125796712575624937961815561
74710412569681301016559428816131055
85089125656711984555433752012843
950891094957113725235315687930
1021516050311025438263435138630

 

and this is the structure of Move:

Move
 200030004000500060007000800090001000011000120001300014000150001600017000
10000000000000000
20000000000000000
30000000000000000
40000000000000000
50000000000000000
60000000000000000
70000000000000000
80000000000000000
90000000000000000
100000000000000000
Lucassss
Obsidian | Level 7

And Move is supposed to be a matrix with 1s and 0s

Lucassss
Obsidian | Level 7

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]);