reset;
option randseed'';
param N := 10; # Number of projects/workers
param w {i in 1..N,j in 1..N} := round(Uniform(5,(i+j)^2)); # willingness of worker j to take project i
########### 1 Linear integer ###############
var x {i in 1..N,j in 1..N} binary; # whether worker j takes project i
maximize LP1: sum{i in 1..N,j in 1..N} w[i,j]*x[i,j]; # maximize total willingness
subject to NBa1{j in 1..N}: sum{i in 1..N} x[i,j] = 1; # each project has to be taken
subject to NBb1{i in 1..N}: sum{j in 1..N} x[i,j] = 1; # each worker has to take one project
objective LP1;
option solver cplex;
solve;
var y {j in 1..N} = sum{i in 1..N} w[i,j]*x[i,j]; # received utility of worker j
display LP1, y, min{j in 1..N} y[j], max{j in 1..N} y[j];
#end;
############ 2 Linear continuous (relaxation) #############
fix x; drop NBa1; drop NBb1; # fix variables x, drop constraints of 1st model
var x2 {i in 1..N,j in 1..N} >=0, <=1; # whether worker j takes project i (now continuous)
maximize LP2: sum{i in 1..N,j in 1..N} w[i,j]*x2[i,j]; # maximize total willingness
subject to NBa2{j in 1..N}: sum{i in 1..N} x2[i,j] = 1; # each project has to be taken
subject to NBb2{i in 1..N}: sum{j in 1..N} x2[i,j] = 1; # each worker has to take one project
objective LP2;
option solver cplex;
var y2 {j in 1..N} = sum{i in 1..N} w[i,j]*x2[i,j]; # received utility of worker j
solve;
display LP2, y2, min{j in 1..N} y2[j], max{j in 1..N} y2[j]; # relaxed solution integer?
#end;
############ 3 Nonlinear continuous relaxation (maybe no integer solution!)
fix x2; drop NBa2; drop NBb2; # fix variables x2, drop constraints of 2nd model
var x3 {i in 1..N,j in 1..N} >=0, <=1; # whether worker j takes project i
maximize LP3: sum{i in 1..N} (sum{j in 1..N} w[i,j]*x3[i,j])^0.5; # utility approach
subject to NBa3{j in 1..N}: sum{i in 1..N} x3[i,j] = 1; # each project has to be taken
subject to NBb3{i in 1..N}: sum{j in 1..N} x3[i,j] = 1; # each worker has to take one project
objective LP3;
option solver minos;
var y3 {j in 1..N} = sum{i in 1..N} w[i,j]*x3[i,j]; # received utility of worker j
solve;
display LP3, y3, min{j in 1..N} y3[j], max{j in 1..N} y3[j];
#end;
########### 4 Quadric integer (transformed minimization) #############
fix x3; drop NBa3; drop NBb3; # fix variables x3, drop constraints of 3rd model
var x4 {i in 1..N,j in 1..N} binary; # whether worker j takes project i
minimize LP4: sum{i in 1..N} (sum{j in 1..N} # Transformed as quadratic minimization problem
(max{i2 in 1..N,j2 in 1..N} w[i2,j2] - w[i,j])*x4[i,j])^2;
subject to NBa4{j in 1..N}: sum{i in 1..N} x4[i,j] = 1; # each project has to be taken
subject to NBb4{i in 1..N}: sum{j in 1..N} x4[i,j] = 1; # each worker has to take one project
objective LP4;
option solver cplex; # cplex can do quadratic integer
var y4 {j in 1..N} = sum{i in 1..N} w[i,j]*x4[i,j]; # received utility of worker j
solve;
display LP4, y4, min{j in 1..N} y4[j], max{j in 1..N} y4[j];
########### 5 worst case / mixed criteria (linear) #############
fix x4; drop NBa4; drop NBb4; # fix variables x4, drop constraints of 4th model
var x5 {i in 1..N,j in 1..N} binary; # whether worker j takes project i
var zu; # variable quetscht von unten
var zo; # variable quetscht von oben
maximize LP5: sum{i in 1..N,j in 1..N} w[i,j]*x5[i,j] + 10*zu - 5*zo; # balance criteria
subject to NBa5{j in 1..N}: sum{i in 1..N} x5[i,j] = 1; # each project has to be taken
subject to NBb5{i in 1..N}: sum{j in 1..N} x5[i,j] = 1; # each worker has to take one project
subject to WC {j in 1..N}: zu<=sum{i in 1..N} w[i,j]*x5[i,j]; # quetschen von unten (for high worst case)
subject to BC {j in 1..N}: zo>=sum{i in 1..N} w[i,j]*x5[i,j]; # quetschen von oben (for low best case)
objective LP5;
option solver cplex;
var y5 {j in 1..N} = sum{i in 1..N} w[i,j]*x5[i,j];
solve;
display LP5, y5; # min{j in 1..N} y5[j], max{j in 1..N} y5[j];
############# Final Comparison of Assigment Solutions #############
display sum{i in 1..N,j in 1..N} w[i,j]*x[i,j], min{j in 1..N} y[j], max{j in 1..N} y[j];
display sum{i in 1..N,j in 1..N} w[i,j]*x2[i,j], min{j in 1..N} y2[j], max{j in 1..N} y2[j];
display sum{i in 1..N,j in 1..N} w[i,j]*x3[i,j], min{j in 1..N} y3[j], max{j in 1..N} y3[j];
display sum{i in 1..N,j in 1..N} w[i,j]*x4[i,j], min{j in 1..N} y4[j], max{j in 1..N} y4[j];
display sum{i in 1..N,j in 1..N} w[i,j]*x5[i,j], min{j in 1..N} y5[j], max{j in 1..N} y5[j];