Hi Everyone, Im fairly new to optmodel, so this may be newbie question, but i've already spent alot of time on this and would appreciate greatly if you could help me out. The objective: I have two pools of clients that i am trying to pair based on some discreet criteria and their spend in a number of common weeks. The objective is to find pairs that fulfill the criteria and minimize the sum of weekly differences between the pairs. One client from each pool can be assigned to no more then one client from another pool. The problem: The code i wrote works fine as long as we have enough clients from the second pool to find a match for every client from the first pool. When that's not true, either due to the criteria, or simply not enough clients in pool 2 to find a match for every client in the pool1, the problems becomes infeasible. This is not the behavior i am trying to achieve - what i would like to see in a situtation when its impossible to find a match for all the clients from pool1 is matching the best possible ones(so the ones minimizing the sum of differnces) and leaving out the infeasible ones. An example: I have prepared a simplified version of the code im using, that i think clearly showcases the problem: /*Creating Datasets*/
data weeks;
do week = 201801 to 201810;
output;
end;
run;
/*5 clients in the first pool*/
data clients1;
do client_id = 1 to 5;
output;
end;
run;
/*only 4 clients in the second pool*/
data clients2;
do client_id = 101 to 104;
output;
end;
run;
data sales;
do client_id = 1 to 5;
do week = 201801 to 201810;
flag="clients1";
spends=1000*ranuni(1000);
output;
end;
end;
do client_id = 101 to 104;
do week = 201801 to 201810;
flag="clients2";
spends=1000*ranuni(1000);
output;
end;
end;
run;
proc optmodel;
set weeks;
read data weeks into weeks = [week];
/*clients 1*/
set clients1;
read data clients1 into clients1 = [client_id];
/*clients 2 spends per week */
num spends1 {clients1, weeks} init 0;
read data sales(where=(flag="clients1")) nomiss into [client_id week] spends1=spends;
/*clients2*/
set clients2;
read data clients2 into clients2 = [client_id];
/*clients 2 spends per week */
num spends2 {clients2, weeks} init 0;
read data sales(where=(flag="clients2")) nomiss into [client_id week] spends2=spends;
/*clients 1,2 matrix*/
set clientpairs = {c1 in clients1, c2 in clients2};
/*calculating the sum of absolute differences for each possible c1,c2 combination*/
impvar diff {<c1,c2> in clientpairs} = sum{w in weeks} abs(spends1[c1,w] - spends2[c2,w]);
/*finding the combination that minimizes the total sum of differences*/
var match {clientpairs} binary;
min total_diff = sum{<c1,c2> in clientpairs} diff[c1,c2]*match[c1,c2];
/*each client1 is present once(here is the problem, but removing this contraint causes no pair to match - minimizes differences)*/
con one_c1_max {c1 in clients1}:
sum {<(c1),c2> in clientpairs} match[c1,c2] = 1;
/*each client2 can not be matched to more than 1 client1*/
con one_c2_max {c2 in clients2}:
sum {<c1,(c2)> in clientpairs} match[c1,c2] <= 1;
solve;
create data res(where =(match = 1)) from [client1 client2] = {clients1, clients2} match diff;
quit;
proc sql;
select * from res;
quit; Let me know if everything is clear and how you would approach this problem. Regards, Jakub EDIT: I see that the code doesnt display properly, ive attached the original version.
... View more