BookmarkSubscribeRSS Feed
vanpoecke
Calcite | Level 5

Hi

Here is simple example that I hope illustrates my optimisation problem. Multiple offers per customers. Key issue for me is that I am not familiar with optmodel and I am struggling to structure it correctly. Would be great is someone could help on this. I have included my existing optmodel syntax but this is far from finish. I am sure this can not be difficult.

data opti1;

do i=1 to 250000;

do k=1 to 5;

custid=i+1000;

offer_code=round((ranuni(849)*50),1);

conflict_group=round((offer_code),10)/10;

ranking=round(ranuni(745)*100,1);

output;

end;

end;

drop k i;

run;

/*objective = maximize sum of ranking over all selected offers and customers; constrain not more than 3 offers per customer; constrain not more than one offer per customer from the same conflict group. same output code always maps to same conflict group; Customers will be rank ordered using their max ranking of allocated offers. Within top 100k of customers we would like to be able to put a constrains on volumes for offers and/or conflict group - i.e. min volume for conflict group 5 = 20000 and min volume for offer 23= 5000 and max volume for conflict group 0 = 25000;*/

proc optmodel;

set <str,str> CUST_camp;

num ranking {CUST_camp};

num conflict_group {CUST_camp};

read data opti1 into CUST_camp=[custid offer_code] ranking conflict_group;

set <str> CUST;

read data opti2 into CUST=[custid];

var assign{cust_camp} binary;

*constrain 1- max 2 offers per customer;

con cust_max_con {i in cust}:

sum {<(i),j> in cust_camp} assign[i,j] <=2; *not more than 2 per custid;

/*

*constrain 1- 2 selected offers per custid can not be in the same conflict group;

con cust_conflict {i in cust}:

((setof{<(i),j> in cust_camp} conflict_group[i,j] * assign[i,j]) inter (setof{<(i),j> in cust_camp} conflict_group[i,j] * assign[i,j]))={0};

*/

max response=sum {<i,j> in cust_camp} ranking[i,j] * assign[i,j];

solve with milp;

quit;

1 REPLY 1
RobPratt
SAS Super FREQ

Here's one way to impose the "min volume for conflict group 5" constraint:

num cust_ranking {i in cust} = max {<(i),j> in CUST_camp} ranking[i,j];
print cust_ranking;
   con cust_conflict_5:
      sum {<i,j> in CUST_CAMP: cust_ranking >= 100000 and conflict_group[i,j] = 5} assign[i,j] >= 20000;

You can also store the high-ranking customers in a set and use that set instead:

set CUST_HIGHRANK = {i in cust: cust_ranking >= 100000};

   con cust_conflict_5:

      sum {<i,j> in CUST_CAMP: i in CUST_HIGHRANK and conflict_group[i,j] = 5} assign[i,j] >= 20000;

You can mimic this logic to get the other constraints.

SAS Innovate 2025: Save the Date

 SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

Save the date!

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
  • 1 reply
  • 1181 views
  • 0 likes
  • 2 in conversation