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-2024.png

Don't miss out on SAS Innovate - Register now for the FREE Livestream!

Can't make it to Vegas? No problem! Watch our general sessions LIVE or on-demand starting April 17th. Hear from SAS execs, best-selling author Adam Grant, Hot Ones host Sean Evans, top tech journalist Kara Swisher, AI expert Cassie Kozyrkov, and the mind-blowing dance crew iLuminate! Plus, get access to over 20 breakout sessions.

 

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