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 open! SAS is returning to Vegas for an AI and analytics experience like no other! Whether you're an executive, manager, end user or SAS partner, SAS Innovate is designed for everyone on your team. Register for just $495 by 12/31/2023.
If you are interested in speaking, there is still time to submit a session idea. More details are posted on the website.
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.