10252010 06:38 PM
10262010 11:04 AM
10262010 11:18 AM
10262010 07:54 PM
10272010 09:06 AM
10272010 06:04 PM
10282010 08:38 AM
10282010 04:31 PM
07212011 02:17 PM
Sorry for digging up this old thread, but this is exactly the issue i'm trying to solve, but i can't seem to get the code above to work.
First, when i use
var Assign >=0;
I get an error on the objective function line as follows:
min z = sum {<i,j> in POSSIBLE} cost[i,j]*Assign[i,j];

647
ERROR 647782: The name 'Assign' must be an array.
I can fix this error by using the following:
var Assign{CASES,CONTROLS} >= 0;
Is this reasonable?
..
I am having a couple of additional problems. If I use this code, which I believe follows from reading all the posts in this thread, I end up with Case1 and Case3 both matching to Control3. Is there a way to prevent multiple cases matching to a single control?
data cases_and_controls;
length case $5;
input case control1control3;
datalines;
case1 . . 2
case2 1 5 .
case3 . . 1
run;
proc optmodel;
/* define sets for cases and controls */
set <str> CASES;
set <str> CONTROLS init (union{i in 1..3} {"control"i});
/* define cost parameter */
num cost{CASES, CONTROLS};
/* read in data including missing values */
read data cases_and_controls into CASES=[case] {j in CONTROLS} < cost[case, j] = col(j) >;
/* create a set of pairs which are possible, i.e. cost is not missing */
set <string, string> POSSIBLE = {i in CASES, j in CONTROLS: cost[i,j] > 0};
/* we only need variables for possible pairs */
var Assign{CASES,CONTROLS} >= 0;
num maxCost = max{<i,j> in POSSIBLE} cost[i,j];
min z = sum {<i,j> in POSSIBLE} cost[i,j]*Assign[i,j]  sum {<i,j> in POSSIBLE} (maxCost+1)*Assign[i,j];
con case_assign{i in CASES}: sum{<(i),j> in POSSIBLE} Assign[i,j] <= 1;
/* solve the model */
solve;
/* print the result */
print Assign;
create data assign from [i j] = {i in CASES, j in CONTROLS: Assign[i,j] >= 0.5} cost;
quit;
07222011 08:30 AM
Hi,
Your modification to "var ASSIGN" looks right.If you want at most one case per control you can add this constraint:
con
control_assign{j in CONTROLS}: sum{<i,(j)> in POSSIBLE} Assign[i,j] <= 1;
Philipp
07222011 08:50 AM
That works perfectly!
Thanks a million.
11262013 05:04 AM
Dear All,
sorry for opening again this old threat. I'm analysing a match control study and I have ~ 3,000 cases to match to ~12,000 controls, with a maximum of 4 controls per case and the constraint of a control to be used only once. I then have a matrix dataset; cases are rows, controls are columns, and the cells contains the distance. Need to find the matching strategy that minimises the total cost.
I've used the code provided by I get an error message 'out of memorey': do you have any idea of how to circumvent this (maybe this is not the right approach)? And do you know what are the limits in term of dataset size proc optmodel can deal with?
Many thanks in advance,
Gianmario
11262013 02:36 PM
As of SAS/OR 12.1 (released in August 2012), the recommended approach is to use PROC OPTNET:
proc optnet data_matrix=mymatrix;
linear_assignment out=out;
run;
See this SAS Usage Note for more details:
11262013 04:30 PM
Many thanks Rob!
We are installing SAS 9.3 M2 in these days so I'll be able to try it soon. I've just had a quick look at the documentation, maybe you already know whether what I need is available in proc optnet.
In my example I need to match a case with up to 4 controls (if available): is it possible to do this?
Thanks,
Gianmario
11262013 05:08 PM
PROC OPTNET does not do onetomany matching directly, but you can transform a onetomany matching problem to an equivalent onetoone matching problem, as done in the popular Mayo clinic macro %vmatch, which uses the (legacy) PROC ASSIGN:
http://www.mayo.edu/research/documents/vmatchsas/DOC10027394