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

Hi,

 

Am finding it very difficult to code in proc optmodel. here is the code , i tried it out, but it does not give me any optimized values.

 

my example has only one input data which contain all the variables in it, but i see lot of threads ,where people read 2 or more datasets in optmodel? can i model with only one dataset?

 

question on con statement:

 

con c1{i in rxid}: new_mac_price[i] = mac_price[i];

 

new_mac_price is the variable am interested to find optimal solution.

 

mac_price is available in my input dataset.

 

am i coding it correct?

 

How can i use filter in constraints?

for example 

if gpi = 1 then con c1{i in rxid}: new_mac_price[i] = mac_price[i];

else if gpi =0 then con c1{i in rxid}: new_mac_price[i] = 90

 

do we have any such method to filter and apply constraint?

 

 proc optmodel;
set <num> d;
num mac_price {id};
num new_mac_price_by_user{id};
num is_reprice_allowed{id};
num is_present_in_gpi{id};
num lb_slack{id};
num upper_bound{id};
num lower_bound{id};
read data lp.opt_subset into id=[rx_id] mac_price new_mac_price_by_user is_reprice_allowed is_present_in_gpi
upper_bound lower_bound ;
var new_mac_price{rxid} ;
var calc_ingred_cost{rxid} >=0;
var post_awp_cost{rxid};
max imp = sum{rx_id in rxid} ((0.165 * post_awp_cost[rx_id])- calc_ingred_cost[rx_id]) ;

con c1{i in rxid}: new_mac_price[i] = mac_price[i];
solve ;expand;
print new_mac_price;

 

after expand:

Var new_mac_price[674523592]
Var new_mac_price[674563238]
Var new_mac_price[674563792]
Var new_mac_price[674569261]
Var new_mac_price[674587992]
Var calc_ingred_cost[674523592] >= 0
Var calc_ingred_cost[674563238] >= 0
Var calc_ingred_cost[674563792] >= 0
Var calc_ingred_cost[674569261] >= 0
Var calc_ingred_cost[674587992] >= 0
Var post_awp_cost[674523592]
Var post_awp_cost[674563238]
Var post_awp_cost[674563792]
Var post_awp_cost[674569261]
Var post_awp_cost[674587992]
Maximize imp=0.165*post_awp_cost[674523592] - calc_ingred_cost[674523592] + 0.165*post_awp_cost[674563238] -
calc_ingred_cost[674563238] + 0.165*post_awp_cost[674563792] - calc_ingred_cost[674563792] + 0.165*post_awp_cost[674569261] -
calc_ingred_cost[674569261] + 0.165*post_awp_cost[674587992] - calc_ingred_cost[674587992]
Constraint c1[674523592]: new_mac_price[674523592] = 0.13537
Constraint c1[674563238]: new_mac_price[674563238] = 0.13537
Constraint c1[674563792]: new_mac_price[674563792] = 0.13537
Constraint c1[674569261]: new_mac_price[674569261] = 0.13537
Constraint c1[674587992]: new_mac_price[674587992] = 0.13537


 

results;

 all my values are zero

 

please help me to fix my codes.

 

thanks in advance

1 ACCEPTED SOLUTION

Accepted Solutions
RobPratt
SAS Super FREQ

Yes, you can have as many data sets as you want or none at all.

 

To encode the logic you want for the c1 constraint, you can use an IF-THEN/ELSE expression in the right-hand side as follows:

con c1{i in rxid}:
   new_mac_price[i] = (if gpi = 1 then mac_price[i] else if gpi = 0 then 90);

 

It looks like your problem is unbounded.  The post_awp_cost variables that appear with positive coefficients in the objective function are not constrained at all, so you can get an arbitrarily large objective value by making these variables big enough.  In this situation, the LP solver returns a solution status of Unbounded and does not update the variables from their default values of 0.

View solution in original post

9 REPLIES 9
RobPratt
SAS Super FREQ

Yes, you can have as many data sets as you want or none at all.

 

To encode the logic you want for the c1 constraint, you can use an IF-THEN/ELSE expression in the right-hand side as follows:

con c1{i in rxid}:
   new_mac_price[i] = (if gpi = 1 then mac_price[i] else if gpi = 0 then 90);

 

It looks like your problem is unbounded.  The post_awp_cost variables that appear with positive coefficients in the objective function are not constrained at all, so you can get an arbitrarily large objective value by making these variables big enough.  In this situation, the LP solver returns a solution status of Unbounded and does not update the variables from their default values of 0.

sarathgk
Fluorite | Level 6
Thanks for your support Rob, it works for me.
sarathgk
Fluorite | Level 6

Hi Rob,

 

your input was very useful to me, however i have some other questions.

here in the code, i have declared two constraints with (if then statement), the single con is broke into two constraints. the real constraint looks like this in python:

if f_GP('is_reprice_allowed',tup)==0:
opt_prob += new_mac_price[tup] == f_GP('mac_price',tup)
opt_prob += lb_slack[tup]==0
elif (f_GP('is_reprice_allowed',tup)==1) & (f_GP('is_present_in_gpi',tup)==1) :
opt_prob += new_mac_price[tup] == f_GP('new_mac_price_by_user',tup)
opt_prob += lb_slack[tup]==0
elif (f_GP('is_reprice_allowed',tup)==1) & (f_GP('is_present_in_gpi',tup)==0):
opt_prob += new_mac_price[tup] <= f_GP('upper_bound',tup)
opt_prob += new_mac_price[tup] >= f_GP('lower_bound',tup)-lb_slack[tup]

 

is ok to break the constraints ?

 

is my if then statement is correct?

 

the variables used in the if then statement is not declared any where in my optmodel, but still it gives me results. is this the right way?


proc optmodel;
set <num> rxid;
num mac_price {rxid};
num new_mac_price_by_user{rxid};
num is_reprice_allowed{rxid};
num is_present_in_gpi{rxid};
num lb_slack{rxid};
num upper_bound{rxid};
num lower_bound{rxid};
read data lp.opt_subset into rxid=[rx_id] mac_price new_mac_price_by_user is_reprice_allowed is_present_in_gpi
upper_bound lower_bound ;
var new_mac_price{rxid} ;
var calc_ingred_cost{rxid} >=0;
var post_awp_cost{rxid};
/* used a maximum number for objective function*/
max imp =200;
con c1{i in rxid}: new_mac_price[i] = (if is_reprice_allowed[i] = 0 then mac_price[i]
else if is_reprice_allowed[i] and is_present_in_gpi[i] =1 then new_mac_price_by_user[i] );
con c2{i in rxid}: new_mac_price[i] <= (if is_reprice_allowed[i]=1 and is_present_in_gpi[i] =0 then upper_bound[i]);
/*con c2{i in rxid is_reprice_allowed[i] =}:new_mac_price[i] = (if is_reprice_allowed[i] and is_present_in_gpi[i] =0 then new_mac_price[i] <= upper_bound[i]);*/

solve ;expand;
print new_mac_price;

 

 

 

sarathgk
Fluorite | Level 6

am running this code, but not getting any optimized resulted, every thing is zero.

 

please help me to fix it. am running late for delivery

 

proc optmodel;
set <num> rxid;
num mac_price {rxid};
num new_mac_price_by_user{rxid};
num is_reprice_allowed{rxid};
num is_present_in_gpi{rxid};
num lb_slack{rxid};
num upper_bound{rxid};
num lower_bound{rxid};
num check_for_paybase{rxid};
num check_for_lesser_code{rxid};
num primary_cost_adj{rxid};
num secondary_cost_adj{rxid};
num calc_cost_adj{rxid};
num calc_ingred_cost{rxid};
num repriced_disp_fee{rxid};

read data lp.opt_subset into rxid=[rx_id] mac_price new_mac_price_by_user is_reprice_allowed is_present_in_gpi
upper_bound lower_bound ;
var new_mac_price{rxid} ;
var new_primary_cost_adj{rxid};
var new_secondary_cost_adj{rxid};
var new_calc_cost_adj{rxid};
var new_ingred_cost{rxid};
var new_disp_fee_final{rxid};

/* used a maximum number for objectivefunction*/
max imp =200;
/* #Constraints on MAC Price*/
con c1{i in rxid}: new_mac_price[i] = (if is_reprice_allowed[i] = 0 then mac_price[i]
else if is_reprice_allowed[i] and is_present_in_gpi[i] =1 then new_mac_price_by_user[i] );
con c2{i in rxid}: new_mac_price[i] <= (if is_reprice_allowed[i]=1 and is_present_in_gpi[i] =0 then upper_bound[i]);

/*#Parity Constraints*/

/*need clarity*/
con c3{i in rxid}:new_primary_cost_adj[i] = (if is_reprice_allowed[i] = 0 | check_for_paybase[i] =0 | check_for_lesser_code[i] =1
then primary_cost_adj[i]);
con c4{i in rxid}:new_secondary_cost_adj[i] = (if is_reprice_allowed[i] = 0 or check_for_paybase[i] =1 or check_for_lesser_code[i] =1
then secondary_cost_adj[i]);
con c5{i in rxid}:new_calc_cost_adj[i] = (if is_reprice_allowed[i] = 0 or check_for_paybase[i] =1 or check_for_lesser_code[i] =1
then calc_cost_adj[i]);
con c6{i in rxid}:new_ingred_cost[i] = (if is_reprice_allowed[i] = 0 or check_for_paybase[i] =1 or check_for_lesser_code[i] =1
then calc_ingred_cost[i]);
con c7{i in rxid}:new_disp_fee_final[i] = (if is_reprice_allowed[i] = 0 or check_for_paybase[i] =1 or check_for_lesser_code[i] =1
then repriced_disp_fee[i]);

solve ;
print new_mac_price new_primary_cost_adj new_secondary_cost_adj new_calc_cost_adj new_ingred_cost
new_disp_fee_final;

RobPratt
SAS Super FREQ

Your objective function is constant (200), so every feasible solution (including the zero solution) is equally desirable.

sarathgk
Fluorite | Level 6

i need  to write down this constraint in  a proper way. am sure , there is mistake in my code in the third (if condition), where i declare bounds.

 

need to define ub and lb here for the given filter

 

con c1{i in rxid}: new_mac_price[i] = (if is_reprice_allowed[i] = 0 then mac_price[i]
else if is_reprice_allowed[i]=1 and is_present_in_gpi[i] =1 then new_mac_price_by_user[i]
else if is_reprice_allowed[i]=1 and is_present_in_gpi[i] =0 then lower_bound[i] <= new_mac_price[i] <= upper_bound[i]);

 

how do i write this :
else if is_reprice_allowed[i]=1 and is_present_in_gpi[i] =0 then lower_bound[i] <= new_mac_price[i] <= upper_bound[i]);

 

if i remove <= new_mac_price[i] <= upper_bound[i]) , i am getting lower bound results ,when the  filters are true.

 

Thanks in advance

RobPratt
SAS Super FREQ

I think the following statements enforce your desired behavior:

for {i in rxid} do;
   if is_reprice_allowed[i] = 0 then fix new_mac_price[i] = mac_price[i];
   else if is_reprice_allowed[i] = 1 and is_present_in_gpi[i] = 1 then fix new_mac_price[i] = new_mac_price_by_user[i];
   else if is_reprice_allowed[i] = 1 and is_present_in_gpi[i] = 0 then do;
      new_mac_price[i].lb = lower_bound[i];
      new_mac_price[i].ub = upper_bound[i];
   end;
end;

You can use the EXPAND statement to see the resulting problem instance. 

sarathgk
Fluorite | Level 6

i have the following constraint in my optmodel. i need to linearise the  min function. which is the right way to do in my MILP solver?

 

i tried this ;

con c23{i in rxid}: n_calc_cost_adj[i] = min(n_primary_cost_adj[i],n_secondary_cost_adj[i]);

 

when i expanded , this is what i got. will there be auto linearization happening here:

 

Constraint c23[674523592]: n_calc_cost_adj[674523592] - MIN(n_primary_cost_adj[674523592], n_secondary_cost_adj[674523592]) = 0
Constraint c23[674563238]: n_calc_cost_adj[674563238] - MIN(n_primary_cost_adj[674563238], n_secondary_cost_adj[674563238]) = 0
Constraint c23[674563792]: n_calc_cost_adj[674563792] - MIN(n_primary_cost_adj[674563792], n_secondary_cost_adj[674563792]) = 0

 

 

RobPratt
SAS Super FREQ

What do the declarations of n_calc_cost_adj, n_primary_cost_adj, and n_secondary_cost_adj look like?

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

Register now!

Multiple Linear Regression in SAS

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.

Discussion stats
  • 9 replies
  • 1321 views
  • 2 likes
  • 2 in conversation