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;
Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
Register now!
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.