I think this is quite simple but given I have no experience with optimisation using proc optmodel I am struggling to find solution.
I have a list of customers that are eligible for various offers. I would like to assign offers with 2 constrains.
-One customer can only be assigned to 2 offers.
-for every customers -assigned offers can not be from the same conflict group
Objective is to maximize sum of ranking.
I have managed to do first constrain but I am struggling with second.
Here is the code. Would be great if someone could help on this.
data opti1;
input custid $ output_code $ conflict_group ranking;
datalines;
ab1 a 1 45
ab1 b 1 8
ab1 c 2 91
ab1 d 3 80
ab5 a 1 51
ab5 b 1 8
ab5 c 2 2
ab5 d 3 91
ab5 e 3 23
ab5 f 4 58
ab8 a 1 72
ab8 b 1 48
ab8 c 2 27
ab8 d 3 43
ab8 e 3 96
ab8 f 4 5
ab8 g 4 49
;
proc sort data=opti1 out=opti2 nodupkey;
by custid;
run;
proc optmodel;
set <str,str> CUST_camp;
num ranking {CUST_camp};
num conflict_group {CUST_camp};
read data opti1 into CUST_camp=[custid output_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 2- 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;
If I understand correctly, the following should do what you want:
set CONFLICT_GROUPS {i in CUST} = setof {<(i),j> in CUST_CAMP} conflict_group[i,j];
con cust_conflict {i in cust, g in CONFLICT_GROUPS}:
sum {<(i),j> in CUST_CAMP: conflict_group[i,j] = g} assign[i,j] <= 1;
expand cust_conflict;
If I understand correctly, the following should do what you want:
set CONFLICT_GROUPS {i in CUST} = setof {<(i),j> in CUST_CAMP} conflict_group[i,j];
con cust_conflict {i in cust, g in CONFLICT_GROUPS}:
sum {<(i),j> in CUST_CAMP: conflict_group[i,j] = g} assign[i,j] <= 1;
expand cust_conflict;
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 25. 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.