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 647-782: 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 control1-control3;
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;
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
That works perfectly!
Thanks a million.
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
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:
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
PROC OPTNET does not do one-to-many matching directly, but you can transform a one-to-many matching problem to an equivalent one-to-one matching problem, as done in the popular Mayo clinic macro %vmatch, which uses the (legacy) PROC ASSIGN:
http://www.mayo.edu/research/documents/vmatchsas/DOC-10027394
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.