@RobPratt
Thanks for helps.
I tried the codes below, two variations. Both complains "ERROR: The specified optimization technique does not allow nonlinear objectives." .
Note, TotalPenalty is like TotalScore. It is to MAX'it. Also -10 is swtiched to -20.
With Treatment/Method, if _tmin_x is less than _tmin_orig, improvement[Score>0].
The Score is consider by each BLOC/DT.
impvar Penalty {<d,b> in DATE_BLOCK} =
sum {<(d),(b),t> in DATE_BLOCK_TREATMENT, m in METHODS} (
if sum((_tmin_orig[d,b,t] - outcome[d,b,t,m])* SelectTreatmentMethod[t,m]) <= 0 then -20
else if sum((_tmin_orig[d,b,t] - outcome[d,b,t,m])* SelectTreatmentMethod[t,m]) > 60 then 2
else if sum((_tmin_orig[d,b,t] - outcome[d,b,t,m])* SelectTreatmentMethod[t,m]) > 36 then 4
else if sum((_tmin_orig[d,b,t] - outcome[d,b,t,m])* SelectTreatmentMethod[t,m]) > 24 then 8
else if sum((_tmin_orig[d,b,t] - outcome[d,b,t,m])* SelectTreatmentMethod[t,m]) > 12 then 6
else if sum((_tmin_orig[d,b,t] - outcome[d,b,t,m])* SelectTreatmentMethod[t,m]) > 6 then 2
else if sum((_tmin_orig[d,b,t] - outcome[d,b,t,m])* SelectTreatmentMethod[t,m]) > 0 then 1
) * SelectTreatmentMethod[t,m];
max TotalPenalty = sum {<d,b> in DATE_BLOCK} Penalty[d,b];
impvar Penalty {<d,b> in DATE_BLOCK} =
sum {<(d),(b),t> in DATE_BLOCK_TREATMENT, m in METHODS} (
if max(_tmin_orig[d,b,t] - outcome[d,b,t,m], 0) * SelectTreatmentMethod[t,m] <= 0 then -20
else if max(_tmin_orig[d,b,t] - outcome[d,b,t,m], 0) * SelectTreatmentMethod[t,m] > 60 then 2
else if max(_tmin_orig[d,b,t] - outcome[d,b,t,m], 0) * SelectTreatmentMethod[t,m] > 36 then 4
else if max(_tmin_orig[d,b,t] - outcome[d,b,t,m], 0) * SelectTreatmentMethod[t,m] > 24 then 8
else if max(_tmin_orig[d,b,t] - outcome[d,b,t,m], 0) * SelectTreatmentMethod[t,m] > 12 then 6
else if max(_tmin_orig[d,b,t] - outcome[d,b,t,m], 0) * SelectTreatmentMethod[t,m] > 6 then 2
else if max(_tmin_orig[d,b,t] - outcome[d,b,t,m], 0) * SelectTreatmentMethod[t,m] > 0 then 1
) * SelectTreatmentMethod[t,m];
max TotalPenalty = sum {<d,b> in DATE_BLOCK} Penalty[d,b];
Complete codes are below. Also attached is the dataset.
%let optds=Mm_out_x6_x; %let methct=4;
data have;
set &optds.;
rename _tmin=method1 _tmin_ew=method2 _tmin_wt_r=method3 _tmin_wt_r2=method4;
run;
title "OPT on &optds.";
proc optmodel;
/* read input data */
set METHODS = 1..&methct.;
set <str,num,num> DATE_BLOCK_TREATMENT;
num _tmin_orig {DATE_BLOCK_TREATMENT};
num outcome {DATE_BLOCK_TREATMENT, METHODS};
read data have into DATE_BLOCK_TREATMENT=[dt bloc condi_id] _tmin_orig
{m in METHODS} <outcome[dt,bloc,condi_id,m]=col('method'||m)>;
set TREATMENTS = setof {<d,b,t> in DATE_BLOCK_TREATMENT} t;
set DATE_BLOCK = setof {<d,b,t> in DATE_BLOCK_TREATMENT} <d,b>;
/* define optimization model */
var SelectTreatment {TREATMENTS} binary;
var SelectMethod {METHODS} binary;
var SelectTreatmentMethod {TREATMENTS, METHODS} binary;
var IsGood {DATE_BLOCK} binary;
/* IT WAS*/
impvar Score {<d,b> in DATE_BLOCK} = 1 * IsGood[d,b] - 5 * (1 - IsGood[d,b]);
max TotalScore = sum {<d,b> in DATE_BLOCK} Score[d,b];
/*con CardinalityTrtmtBloc:
sum {t in 5..6} SelectTreatment[t] = 1; /*enforce to select ONE AND ONLY ONE among 2-4[or alike]*/
con CardinalityTreatment:
sum {t in TREATMENTS} SelectTreatment[t] = 2;
con CardinalityMethod:
sum {m in METHODS} SelectMethod[m] = 2;
con Linearize1 {t in TREATMENTS, m in METHODS}:
SelectTreatmentMethod[t,m] <= SelectTreatment[t];
con Linearize2 {t in TREATMENTS, m in METHODS}:
SelectTreatmentMethod[t,m] <= SelectMethod[m];
con AtLeastOneGood {<d,b> in DATE_BLOCK}:
IsGood[d,b] <= sum {<(d),(b),t> in DATE_BLOCK_TREATMENT,
m in METHODS: outcome[d,b,t,m] < _tmin_orig[d,b,t]} SelectTreatmentMethod[t,m];
/* call MILP solver , TOP one only
solve;
create data want_method from [method] SelectMethod;
create data want_treatment from [treatment] SelectTreatment;
create data want_dt_bloc from [dt bloc] IsGood Score;
create data want_x_dtbloc from [d b]=DATE_BLOCK;
create data want_trtmt from [t]=TREATMENTS;*/
/* source: https://communities.sas.com/t5/Mathematical-Optimization/How-2-Find-the-BEST-Improvement-on-DIF-between-tmin-orig-and/m-p/976283/highlight/false#M4384
*/
/* primary objective */
solve;
create data want_method from [method] SelectMethod;
create data want_treatment from [treatment] SelectTreatment;
create data want_dt_bloc from [dt bloc] IsGood Score;
create data want_x_dtbloc from [d b]=DATE_BLOCK;
create data want_trtmt from [t]=TREATMENTS;
/* con MinScore: TotalScore >= TotalScore.sol;*/
con MinScore: TotalScore >= -5;
/*impvar difx {<d,b> in DATE_BLOCK} =
sum {<(d),(b),t> in DATE_BLOCK_TREATMENT, m in METHODS} max(_tmin_orig[d,b,t] - outcome[d,b,t,m], 0) * SelectTreatmentMethod[t,m];
max TotalDif = sum {<d,b> in DATE_BLOCK} difx[d,b];
*/
impvar Penalty {<d,b> in DATE_BLOCK} =
sum {<(d),(b),t> in DATE_BLOCK_TREATMENT, m in METHODS} (
if max(_tmin_orig[d,b,t] - outcome[d,b,t,m], 0) * SelectTreatmentMethod[t,m] <= 0 then -20
else if max(_tmin_orig[d,b,t] - outcome[d,b,t,m], 0) * SelectTreatmentMethod[t,m] > 60 then 2
else if max(_tmin_orig[d,b,t] - outcome[d,b,t,m], 0) * SelectTreatmentMethod[t,m] > 36 then 4
else if max(_tmin_orig[d,b,t] - outcome[d,b,t,m], 0) * SelectTreatmentMethod[t,m] > 24 then 8
else if max(_tmin_orig[d,b,t] - outcome[d,b,t,m], 0) * SelectTreatmentMethod[t,m] > 12 then 6
else if max(_tmin_orig[d,b,t] - outcome[d,b,t,m], 0) * SelectTreatmentMethod[t,m] > 6 then 2
else if max(_tmin_orig[d,b,t] - outcome[d,b,t,m], 0) * SelectTreatmentMethod[t,m] > 0 then 1
) * SelectTreatmentMethod[t,m];
max TotalPenalty = sum {<d,b> in DATE_BLOCK} Penalty[d,b];
/* secondary objective */
solve with milp / primalin;
put TotalScore= TotalPenalty=;
create data want_method_f from [method] SelectMethod;
create data want_treatment_f from [treatment] SelectTreatment;
create data want_dt_bloc_f from [dt bloc] IsGood Score;
create data want_x_dtbloc_f from [d b]=DATE_BLOCK;
create data want_trtmt_f from [t]=TREATMENTS;
quit;
... View more