Hi all,
This is a follow-up question to my last post. Basically, i need to maximize the correlation between 'ads' and 'dep' by changing the variable 's' with some constrains. Thanks for RobPratt's help that i was able to achieve this optimization without constrains. Now i need to put the constrains in.
The constrains need to follow a simple rule: same value repeating for every 8 observations. In other words, s[1] = s[2] = .....s[7] = s [8], s[9] = s[10] = .....s[16], s[17] = s[18] = s[19]. i wrote a very elementary constrains in my program but looks like it didn't work quite well. My main two questions are:
1. Why s[1] to s[0] are all 0? I must did something wrong. (s[9] to s[19] looks ok.). Pls refer to the SAS output below the program.
2. Any macro or creative way to simplify my constrains? In the real data set, there will be hundreds of observations that are still needed to repeat in 8. I don't want to kill myself to manually write one by one
Thanks for the help in advance.
HY
--------------------------------------------
data cor;
input org dep;
cards;
11785895 7.42
2335492 7.58
2345245 7.58
2392912 7.53
12755890 7.63
2918402 7.67
2773183 7.68
2824198 7.65
12263433 7.53
2420611 7.53
2338870 7.63
2268830 7.74
2462173 7.74
10775045 7.80
2834195 7.75
2666271 7.55
2734586 7.65
11722258 7.60
2366007 7.71
;
run;
%let wk = 19;
proc optmodel;
set w;
number org{w};
number dep{w};
var s{w} >= 0 <= .8 init 1;
impvar ads{i in w} = org * s;
read data work.cor into w = [_n_] org dep;
max correlation = (&wk*sum{i in w}(ads*dep) - (sum{i in w}(ads)) * (sum{i in w}(dep)))
/ (sqrt(&wk*sum{i in w}(ads^2) - (sum{i in w}(ads))^2) * sqrt(&wk*sum{i in w}(dep^2) - (sum{i in w}(dep))^2));
con s[1]=s[2], s[2]=s[3], s[3]=s[4], s[4]=s[5], s[5]=s[6], s[6]=s[7], s[7]=s[8];
con s[9]=s[10], s[10]=s[11], s[11]=s[12], s[12]=s[13], s[13]=s[14], s[14]=s[15], s[15]=s[16];
con s[17]=s[18], s[18]=s[19];
solve;
print s ads correlation;
quit;
SAS Output:
[1] s ads
1 0.0000000 0.0
2 0.0000000 0.0
3 0.0000000 0.0
4 0.0000000 0.0
5 0.0000000 0.0
6 0.0000000 0.0
7 0.0000000 0.0
8 0.0000000 0.0
9 0.0084904 104120.9
10 0.0084904 20551.8
11 0.0084904 19857.8
12 0.0084904 19263.2
13 0.0084904 20904.7
14 0.0084904 91483.9
15 0.0084904 24063.3
16 0.0084904 22637.6
17 0.0006025 1647.6
18 0.0006025 7062.6
19 0.0006025 1425.5
correlation
0.16488
I don't see anything wrong with s[1] = ... = s[8] = 0. That is feasible to your bounds and constraints.
You can use the following CON statement to declare your constraints:
con c {i in w diff {card(w)}: mod(i,8) ne 0}: s = s[i+1];
Alternatively, you can omit the constraints and declare only three s variables in the first place:
var s{1..ceil(card(w)/8)} >= 0 <= .8 init 1;
impvar ads{i in w} = org * s[ceil(i/8)];
I don't see anything wrong with s[1] = ... = s[8] = 0. That is feasible to your bounds and constraints.
You can use the following CON statement to declare your constraints:
con c {i in w diff {card(w)}: mod(i,8) ne 0}: s = s[i+1];
Alternatively, you can omit the constraints and declare only three s variables in the first place:
var s{1..ceil(card(w)/8)} >= 0 <= .8 init 1;
impvar ads{i in w} = org * s[ceil(i/8)];
Thanks so very much RobPratt! You are my hero:)
Have a good weekend!
hey RobPratt, one more question for you.
does the label name in input statement need to be exact same to those in 'read data" part in proc optmodel? In the below example, should "org" and "dep" be consistent in input and read data?
data cor;
input org dep;
cards;
read data work.cor into w = [_n_] org dep;
Thanks!
No, the names do not have to be the same. If they are different, say org1 and dep1 in the data set, then you can use org=org1 dep=dep1 in the READ DATA statement.
by the way, which one of your two solutions (w constrains and w/o) runs more efficiently in sas assuming i will run hundreds of times using macro?
thanks!
The second version (with fewer variables and no constraints) is more efficient. Also, depending on how different your hundreds of runs are, you might be better off doing all the looping within one PROC OPTMODEL session, instead of calling PROC OPTMODEL hundreds of times.
Join us for SAS Innovate 2025, our biggest and most exciting global event of the year, in Orlando, FL, from May 6-9. Sign up by March 14 for just $795.
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.