Operations Research topics: SAS/OR,
SAS Optimization, and SAS Simulation Studio

optmodel for marketing campaigns

New Contributor
Posts: 2

optmodel for marketing campaigns


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;








drop k i;


/*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;


SAS Employee
Posts: 538

Re: optmodel for marketing campaigns

Posted in reply to vanpoecke

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.

Ask a Question
Discussion stats
  • 1 reply
  • 2 in conversation