Assuming you want to minimize the total penalty, here is one way:
impvar Penalty {<d,b> in DATE_BLOCK} =
sum {<(d),(b),t> in DATE_BLOCK_TREATMENT, m in METHODS} (
if _tmin_orig[d,b,t] - outcome[d,b,t,m] <= 0 then -10
else if _tmin_orig[d,b,t] - outcome[d,b,t,m] > 60 then 2
else if _tmin_orig[d,b,t] - outcome[d,b,t,m] > 36 then 4
else if _tmin_orig[d,b,t] - outcome[d,b,t,m] > 24 then 8
else if _tmin_orig[d,b,t] - outcome[d,b,t,m] > 12 then 6
else if _tmin_orig[d,b,t] - outcome[d,b,t,m] > 6 then 2
else if _tmin_orig[d,b,t] - outcome[d,b,t,m] > 0 then 1
) * SelectTreatmentMethod[t,m];
min TotalPenalty = sum {<d,b> in DATE_BLOCK} Penalty[d,b];
An alternative approach is to use an FCMP function:
proc fcmp outlib=work.funcs.test;
function penaltyCoefficient(dif);
if dif <= 0 then return(-10);
else if dif > 60 then return(2);
else if dif > 36 then return(4);
else if dif > 24 then return(8);
else if dif > 12 then return(6);
else if dif > 6 then return(2);
else if dif > 0 then return(1);
endsub;
run;
option cmplib=work.funcs;
data try;
do x = -5 to 70 by 5;
p = penaltyCoefficient(x);
output;
end;
run;
Then the Penalty declaration can be written more compactly:
impvar Penalty {<d,b> in DATE_BLOCK} =
sum {<(d),(b),t> in DATE_BLOCK_TREATMENT, m in METHODS} penaltyCoefficient(_tmin_orig[d,b,t] - outcome[d,b,t,m]) * SelectTreatmentMethod[t,m];
... View more