@RobPratt
I am playing the codes. I still have one confusion. Sorry OPT Model is quite new to me.
Initially it is to pick 1 out 4 Methods and 2 out 18 Treatments, right?
If loose the constrains, say, 2/4 for Methods and 4/18 for Treatments, the final Result Score should be better off, Right?
BUT the best one is only -45. The before is -21, right? I am confused.
con CardinalityMethod:
sum {m in METHODS} SelectMethod[m] = 2;
con CardinalityTreatment:
sum {t in TREATMENTS} SelectTreatment[t] = 4;
FULL CODE is below, seems nothing altered. If switch back to SelectMethod[m] = 1; and SelectTreatment[t] = 2;, the top
result score is -21.
/*
https://communities.sas.com/t5/Mathematical-Optimization/HOW-TO-Find-the-Best-Combination-Of-Treatments-for-Date-BLOC-dt/m-p/975265#M4360
*/
%let optds=mm_out_x6_x;
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..4;
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 SelectMethod {METHODS} binary;
var SelectTreatment {TREATMENTS} binary;
var IsGood {DATE_BLOCK} binary;
/* if IsGood[d,b] = 1 then Score[d,b] = 1 else Score[d,b] = -5 */
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 CardinalityMethod:
sum {m in METHODS} SelectMethod[m] = 1;
con CardinalityTreatment:
sum {t in TREATMENTS} SelectTreatment[t] = 2;
/* if IsGood[d,b] = SelectMethod[m] = SelectTreatment[t] = 1 then outcome[d,b,t,m] < _tmin_orig[d,b,t] */
con NoGood {<d,b,t> in DATE_BLOCK_TREATMENT, m in METHODS: outcome[d,b,t,m] >= _tmin_orig[d,b,t]}:
IsGood[d,b] + SelectMethod[m] + SelectTreatment[t] <= 2;
/* 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;*/
/*solver, top n
num numSolsWanted = 5;
num numSolsFound init 0;
set SOLS = 1..numSolsFound;
set TREATMENTS_s {SOLS};
con ExcludeSolution {s in SOLS}:
sum {t in TREATMENTS_s[s]} SelectTreatment[t] <= card(TREATMENTS_s[s]) - 1;
for {1..numSolsWanted} do;
solve;
numSolsFound = numSolsFound + 1;
put numSolsFound=;
TREATMENTS_s[numSolsFound] = {t in TREATMENTS: SelectTreatment[t].sol > 0.5};
create data ('want_m'||numSolsFound) from [method] SelectMethod;
create data ('want_t'||numSolsFound) from [treatment] SelectTreatment;
create data(' want_d'||numSolsFound) from [dt bloc] IsGood Score;
end;*/
num numSolsWanted = 5;
num numSolsFound init 0;
set SOLS = 1..numSolsFound;
set TREATMENTS_s {SOLS};
con ExcludeSolution {s in SOLS}:
sum {t in TREATMENTS_s[s]} SelectTreatment[t] <= card(TREATMENTS_s[s]) - 1;
for {1..numSolsWanted} do;
put numSolsFound=;
solve;
numSolsFound = numSolsFound + 1;
TREATMENTS_s[numSolsFound] = {t in TREATMENTS: SelectTreatment[t].sol > 0.5};
create data want_method from [method] sol=numSolsFound SelectMethod;
create data want_treatment from [treatment] sol=numSolsFound SelectTreatment;
create data want_dt_bloc from [dt bloc] sol=numSolsFound IsGood Score;
submit;
proc append base=want_method_all data=want_method;
run;
proc append base=want_treatment_all data=want_treatment;
run;
proc append base=want_dt_bloc_all data=want_dt_bloc;
run;
endsubmit;
end;
quit;
... View more