Dear Bob, Paul, and all;
Earlier, I have solved my min-max MILP model for 50-80 nodes within feasible time (based on discussion in my earlier thread), but for problem with more than 100 nodes i.e., for problem instance with 200 nodes, the root relaxation phase is taking very long time and getting 'out of memory' issues. I am trying lagrangian relaxation technique to reduce the problem size which will help me to get a feasible solution from the branch and bound algorithm.
To write the LR algorithm for my model, I have followed both OPL (IBM) and AMPL implementation for the location-transportation problem at links below:
and an important document: An Applications Oriented Guide to Lagrangian Relaxation - Marshall Fisher
After following the examples of LR method with the standard subgradient algorithm, I have tried to implement the same for my model, but couldn't formulate properly for the min-max problem, thus getting incorrect results (objective function values are not correct). I know that the lagrangian dual of a minimization problem is a 'max' (lagrangian dual function with multipliers) model, but I do not know how to write an effective and equivalent LR scheme for my model to find/deduce a feasible solution (UpperBound) by employing heuristics. Could you provide me some guidelines/directions on how to apply LR technique for my problem ?.
I am using Gurobi 5.0 solver with AMPL 64-bit.
thanks much!
Syed
#loc_problem.mod
set NODES ordered; # Vertices
set EDGES within {i in NODES, j in NODES: i != j};
param T {j in NODES};
param D {i in NODES,j in NODES}; # distance-matrix
param mult {NODES} >= 0; # Lagrange multipliers for the constraint (2)
param c_f = 100;
param c_b = 50;
param npce {NODES} integer > 1; # number of pieces for PWLA
param bkp {i in NODES, p in 1..npce[i]-1}; # breakpts and slopes for PWLA
param slp {i in NODES, p in 1..npce[i]};
param UBB {i in NODES};
param d = 1;
var I {i in NODES} binary;
var m {i in NODES, j in NODES} >= 0;
var V {i in NODES} = sum {j in NODES} m[i,j] * T [j];
minimize Lagrangian: sum {i in NODES} Z[i] + sum {j in NODES} mult[j] * (sum {i in NODES} m[i,j] - 1) ;
minimize max_cost: sum {i in NODES} Z[i];
subject to limit {i in NODES}: sum {j in NODES} T[j] * D[i,j] * m[i,j] <= d * V[i]; # performance constraint (1)
subject to start {i in NODES}: sum {j in NODES} m[i,j] = 1;
# constraint 2: It ensures that a location node should be mapped to each destination node,
# Relaxed for LR relaxation.
subject to mapp {i in NODES, j in NODES}:
m[i,j] <= I[i];
# ensures that destination nodes are mapped only to active location nodes.
# implementing the max (c_f, c_b * V(i)^0.75) cost model:
subject to Zlow {i in NODES}:
Z[i] >= c_f * I[i];
subject to Zref {i in NODES}:
Z[i] >= c_b * <<{p in 1..npce[i]-1} bkp[i,p];
{p in 1..npce[i]} slp[i,p]>> V[i] - (UBB[i] * (1-I[i]));
Run file:
# Lagrangian relaxation with Subgradient algorithm for location problem
printf "\nLP RELAXATION\n\n";
model loc_problem.mod;
data loc_problem.dat;
option omit_zero_rows 1;
option display_eps .000001;
option solution_round 8;
option solver gurobi_ampl;
option gurobi_options 'lpmethod 3 outlev 1 logfreq 5 threads 5 timing 1';
option log_file '200-nodes-run';
option solver_msg 0;
option relax_integrality 1;
objective max_cost;
expand;
solve;
param LB; param UB;
let LB := max_cost.val;
let UB := sum {i in NODES} V[i];
option relax_integrality 0;
problem LowerBound: I, m, V, mapp, Lagrangian, limit;
problem UpperBound: m, V, mapp, limit, start, max_cost;
let {j in NODES} mult[j] := 0;
param slack {NODES};
param scale default 1;
param norm;
param step;
param same default 0;
param same_limit := 3;
param iter_limit := 10;
param LBlog {0..iter_limit}; let LBlog[0] := LB;
param UBlog {0..iter_limit}; let UBlog[0] := UB;
param scalelog {1..iter_limit};
param steplog {1..iter_limit};
for {k in 1..iter_limit} { printf "\nITERATION %d\n\n", k;
solve LowerBound;
printf "\n solved UB! \n \n";
printf "\n Lagrangian %f LB %f \n \n", Lagrangian, LB;
let {j in NODES} slack[j] := sum {i in NODES} m[i,j] - 1;
if Lagrangian > LB + 0.000001 then {
let LB := Lagrangian;
let same := 0; }
else let same := same + 1;
if same = same_limit then {
let scale := scale / 2;
let same := 0;
};
let norm := sum {j in NODES} slack[j]^2;
printf "\n norm value %f", norm;
let step := scale * (UB - Lagrangian) / norm;
let {j in NODES} mult[j] := mult[j] less step * slack[j];
if sum {i in NODES} I[i]
>= 1 - 1e-8 then {
solve UpperBound;
let UB := min (UB,max_cost);
printf "\n solved UB! \n \n";
printf "\n max_cost %f UB %f \n \n", max_cost, UB;
}
let LBlog[k] := LB;
let UBlog[k] := UB;
let scalelog[k] := scale;
let steplog[k] := step;
}
printf "\n\n";
display LBlog, UBlog, scalelog, steplog;
display I,V,Z;
display max_cost;
display _total_solve_time;