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
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.
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.
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;
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;
Your objective function is constant (200), so every feasible solution (including the zero solution) is equally desirable.
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
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.
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
What do the declarations of n_calc_cost_adj, n_primary_cost_adj, and n_secondary_cost_adj look like?
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 16. 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.