Calcite | Level 5

## optmodel for marketing campaigns

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;

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;

SAS Super FREQ

## Re: optmodel for marketing campaigns

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.

Discussion stats