# =======================================================
# Title: Single-allocation hub location problem
# Nome: Joćo Flavio de Freitas Almeida:
# =======================================================

param n >= 0;
param w{1..n, 1..n} >= 0;
param f{1..n} >= 0;
param coord_x{1..n};
param coord_y{1..n};
param cap{1..n} >= 0;
param alpha >= 0;
param gamma >= 0;
param rho >= 0;
param p >= 0;
param ex := 300;
param c{i in 1..n, j in  1..n} := sqrt((coord_x[i] - coord_x[j])^2 + (coord_y[i] - coord_y[j])^2);
param o{i in 1..n} := sum{j in 1..n:i != j} w[i,j];
param d{i in 1..n} := sum{j in 1..n:i != j} w[j,i];

# =======================================================
# Autor: J.F. Campbell
# =======================================================
/*
var z{k in 1..n, i in 1..n} binary;
var x{i in 1..n, j in 1..n, k in 1..n, m in 1..n:i < j}, >= 0;
minimize fo: sum{k in 1..n} ex * f[k] * z[k,k] 
           + sum{i in 1..n, k in 1..n} c[i,k] * (o[i] + d[i]) *z[i,k]
           + sum{i in 1..n, j in 1..n, k in 1..n, m in 1..n : i < j}  alpha * (w[i,j] * c[k,m] + w[j,i] * c[m,k]) * x[i,j,k,m] ;

s.t. r1{i in 1..n}: sum{k in 1..n} z[i,k] = 1;
s.t. r2{i in 1..n, k in 1..n: i != k}: z[i,k] <= z[k,k];
s.t. r3{i in 1..n, j in 1..n, k in 1..n, m in 1..n: i < j}: x[i,j,k,m] <= z[i,k];
s.t. r4{i in 1..n, j in 1..n, k in 1..n, m in 1..n: i < j}: x[i,j,k,m] <= z[j,m];
s.t. r5{i in 1..n, j in 1..n, k in 1..n, m in 1..n: i < j}: x[i,j,k,m] >= z[i,k] + z[j,m] - 1;
*/
# =======================================================
# Skorin
# =======================================================
/*
var z{k in 1..n, i in 1..n} binary;
var x{i in 1..n, j in 1..n, k in 1..n, m in 1..n:i < j}, >= 0;
minimize fo: sum{k in 1..n} ex * f[k] * z[k,k] 
           + sum{i in 1..n, k in 1..n} c[i,k] * (o[i] + d[i]) *z[i,k]
           + sum{i in 1..n, j in 1..n, k in 1..n, m in 1..n : i < j}  alpha * (w[i,j] * c[k,m] + w[j,i] * c[m,k]) * x[i,j,k,m] ;

s.t. r1{i in 1..n}: sum{k in 1..n} z[i,k] = 1;
s.t. r2{i in 1..n, k in 1..n: i != k}: z[i,k] <= z[k,k];
s.t. r3{i in 1..n, j in 1..n, k in 1..n: i < j}: sum{m in 1..n} x[i,j,k,m] = z[i,k];
s.t. r4{i in 1..n, j in 1..n, m in 1..n: i < j}: sum{k in 1..n} x[i,j,k,m] = z[j,m];
*/
# =======================================================
# Autor: Ernst
# =======================================================
/*
var z{k in 1..n, i in 1..n} binary;
var y{i in 1..n, k in 1..n, m in 1..n} >= 0;
minimize fo: sum{k in 1..n} ex * f[k] * z[k,k] 
           + sum{i in 1..n, k in 1..n} c[i,k] * (o[i] + d[i]) *z[i,k]
           + sum{i in 1..n, k in 1..n, m in 1..n} alpha * c[k,m] * y[i,k,m];

s.t. r1{i in 1..n}: sum{k in 1..n} z[i,k] = 1;
s.t. r2{i in 1..n, k in 1..n: i != k}: z[i,k] <= z[k,k];
s.t. r3{i in 1..n, k in 1..n: i < k}: sum{m in 1..n} y[i,k,m] - sum{m in 1..n} y[i,m,k] = o[i] * z[i,k] - sum{j in 1..n: i != j} w[i,j] * z[j,k];
s.t. r4{i in 1..n, k in 1..n}: sum{m in 1..n} y[i,k,m] = o[i]*z[i,k];
*/
# =======================================================
# Autor: Ebery
# =======================================================
/*
var z{k in 1..n, i in 1..n} binary;
var q{i in 1..n, k in 1..n} >= 0;
minimize fo: sum{k in 1..n} ex * f[k] * z[k,k] 
           + sum{i in 1..n, k in 1..n} c[i,k] * (o[i] + d[i]) *z[i,k]
           + sum{i in 1..n, k in 1..n} q[i,k];

s.t. r1{i in 1..n}: sum{k in 1..n} z[i,k] = 1;
s.t. r2{i in 1..n, k in 1..n: i != k}: z[i,k] <= z[k,k];
s.t. r3{i in 1..n, k in 1..n}: q[i,k] >= sum{j in 1..n, m in 1..n:i < j} ((w[i,j] * c[k,m] + w[j,i] * c[m,k]) * alpha * (z[i,k] + z[j,m] - 1));
*/
# =======================================================
# Autor: Ebery-Skorin
# =======================================================
/*
# ============= Autor: Ebery =============================
var z{k in 1..n, i in 1..n} binary;
var q{i in 1..n, k in 1..n} >= 0;
minimize fo: sum{k in 1..n} ex * f[k] * z[k,k] 
           + sum{i in 1..n, k in 1..n} c[i,k] * (o[i] + d[i]) *z[i,k]
           + sum{i in 1..n, k in 1..n} q[i,k];

s.t. r1{i in 1..n}: sum{k in 1..n} z[i,k] = 1;
s.t. r2{i in 1..n, k in 1..n: i != k}: z[i,k] <= z[k,k];
s.t. r3{i in 1..n, k in 1..n}: q[i,k] >= sum{j in 1..n, m in 1..n:i < j} ((w[i,j] * c[k,m] + w[j,i] * c[m,k]) * alpha * (z[i,k] + z[j,m] - 1));
# ============= Autor: Skorin ============================
var x{i in 1..n, j in 1..n, k in 1..n, m in 1..n:i < j}, >= 0;

s.t. r4{i in 1..n, j in 1..n, k in 1..n: i < j}: sum{m in 1..n} x[i,j,k,m] = z[i,k];
s.t. r5{i in 1..n, j in 1..n, m in 1..n: i < j}: sum{k in 1..n} x[i,j,k,m] = z[j,m];
s.t. r6{i in 1..n, k in 1..n}: sum{j in 1..n, m in 1..n: i < j} (w[i,j] * c[k,m] + w[j,i] * c[m,k])* alpha * x[i,j,k,m] = q[i,k];

solve;
printf "z[i,k]\n";
for{i in 1..n} {		
		for{k in 1..n} printf "%d\t",z[i,k];
		printf "\n";
	}
	
printf "q[i,k]\n";
for{i in 1..n} {		
		for{k in 1..n} printf "%d\t",q[i,k];
		printf "\n";
	}	
*/	
# =======================================================
# Autor: Ebery-Skorin : PROBLEMA MESTRE
# =======================================================

param _u{i in 1..n, j in 1..n, k in 1..n: i < j};
param _v{i in 1..n, j in 1..n, m in 1..n: i < j};
param _b{i in 1..n, k in 1..n};

var z{k in 1..n, i in 1..n} binary;
var q{i in 1..n, k in 1..n} >= 0;
minimize fo: sum{k in 1..n} ex * f[k] * z[k,k] 
           + sum{i in 1..n, k in 1..n} c[i,k] * (o[i] + d[i]) *z[i,k]
           + sum{i in 1..n, k in 1..n} q[i,k];

s.t. corte: sum{i in 1..n, j in 1..n, k in 1..n: i < j}(_u[i,j,k] * z[i,k]) 
		  + sum{i in 1..n, j in 1..n, m in 1..n: i < j}(_v[i,j,m] + z[j,m])
		  + sum{i in 1..n, k in 1..n}(_b[i,k] * q[i,k]) <= 0;
		  
s.t. r1{i in 1..n}: sum{k in 1..n} z[i,k] = 1;
s.t. r2{i in 1..n, k in 1..n: i != k}: z[i,k] <= z[k,k];
s.t. r3{i in 1..n, k in 1..n}: q[i,k] >= sum{j in 1..n, m in 1..n:i < j} ((w[i,j] * c[k,m] + w[j,i] * c[m,k]) * alpha * (z[i,k] + z[j,m] - 1));

# =======================================================
# Autor: Ebery-Skorin : SUB-PROBLEMA 
# =======================================================
/*
var u{i in 1..n, j in 1..n, k in 1..n: i < j};
var v{i in 1..n, j in 1..n, m in 1..n: i < j};
var b{i in 1..n, k in 1..n};

param _z{i in 1..n, k in 1..n};
param _q{i in 1..n, k in 1..n};

maximize fod: sum{i in 1..n, j in 1..n, k in 1..n: i < j}(u[i,j,k] * _z[i,k])
			+ sum{i in 1..n, j in 1..n, m in 1..n: i < j}(v[i,j,m] * _z[j,m])
			+ sum{i in 1..n, k in 1..n}(b[i,k] * _q[i,k]);
			
s.t. rd1{i in 1..n, j in 1..n, k in 1..n, m in 1..n: i < j}: u[i,j,k] + v[i,j,m] + (w[i,j] * c[k,m] + w[j,i] * c[m,k]) * alpha * b[i,k] <= 0;
s.t. rd2{i in 1..n}: sum{j in 1..n, k in 1..n: i < j} u[i,j,k] + sum{j in 1..n, m in 1..n: i < j} v[i,j,m] + sum{k in 1..n} b[i,k] <= 1;
s.t. rd3{i in 1..n}: sum{j in 1..n, k in 1..n: i < j} u[i,j,k] + sum{j in 1..n, m in 1..n: i < j} v[i,j,m] + sum{k in 1..n} b[i,k] >= -1;

solve;
printf "\n\n\n";
printf "u[i,j,k]\n";
for{i in 1..n}{
	printf "\n\n\n";
	for{j in 1..n}{
		for{k in 1..n}{
			printf: (if i < j then  "%d\t" else "0\t"),u[i,j,k];
			#printf: (if pl[u,r] > 0 then "%10s\t%10s\t%10d\n" else ""),u,r,pl[u,r]
		}
		printf "\n";
	}
}
printf "\n\n\n";
printf "v[i,j,k]\n";
for{i in 1..n}{
	printf "\n\n\n";
	for{j in 1..n}{
		for{m in 1..n}{
			printf: (if i < j then "%d\t" else "0\t"),v[i,j,m];
		}
		printf "\n";
	}
}

printf "\n\n\n";
printf "b[i,k]\n";
for{i in 1..n}{
	printf "\n";
	for{k in 1..n}{		
		printf "%d\t",b[i,k];	
	}
}
printf "\n\n\n";
*/
# =======================================================
# Autor: Ernst-Skorin
# =======================================================
/*
# ============= Autor: Ernst =============================
var z{k in 1..n, i in 1..n} binary;
var y{i in 1..n, k in 1..n, m in 1..n} >= 0;
minimize fo: sum{k in 1..n} ex * f[k] * z[k,k] 
           + sum{i in 1..n, k in 1..n} c[i,k] * (o[i] + d[i]) *z[i,k]
           + sum{i in 1..n, k in 1..n, m in 1..n} alpha * c[k,m] * y[i,k,m];

s.t. r1{i in 1..n}: sum{k in 1..n} z[i,k] = 1;
s.t. r2{i in 1..n, k in 1..n: i != k}: z[i,k] <= z[k,k];
s.t. r3{i in 1..n, k in 1..n: i < k}: sum{m in 1..n} y[i,k,m] - sum{m in 1..n} y[i,m,k] = o[i] * z[i,k] - sum{j in 1..n: i != j} w[i,j] * z[j,k];
s.t. r4{i in 1..n, k in 1..n}: sum{m in 1..n} y[i,k,m] = o[i]*z[i,k];
# ============= Autor: Skorin ============================
var x{i in 1..n, j in 1..n, k in 1..n, m in 1..n:i < j}, >= 0;

s.t. r5{i in 1..n, j in 1..n, k in 1..n: i < j}: sum{m in 1..n} x[i,j,k,m] = z[i,k];
s.t. r6{i in 1..n, j in 1..n, m in 1..n: i < j}: sum{k in 1..n} x[i,j,k,m] = z[j,m];
s.t. r7{i in 1..n, k in 1..n, m in 1..n: i < k}: sum{j in 1..n: i < j} w[i,j] * x[i,j,k,m] + sum{j in 1..n: i > j} w[i,j] * x[j,i,m,k] = y[i,k,m];
*/
# =======================================================
# Autor: Ernst-Skorin : PROBLEMA MESTRE
# =======================================================
/*
var z{k in 1..n, i in 1..n} binary;
var y{i in 1..n, k in 1..n, m in 1..n} >= 0;
minimize fo: sum{k in 1..n} ex * f[k] * z[k,k] 
           + sum{i in 1..n, k in 1..n} c[i,k] * (o[i] + d[i]) *z[i,k]
           + sum{i in 1..n, k in 1..n, m in 1..n} alpha * c[k,m] * y[i,k,m];

s.t. corte: sum{i in 1..n, j in 1..n, k in 1..n: i < j}(_u[i,j,k] * z[i,k]) 
		  + sum{i in 1..n, j in 1..n, m in 1..n: i < j}(_v[i,j,m] + z[j,m])
		  + sum{i in 1..n, k in 1..n, m in 1..n}(_b[i,k,m] * y[i,k,m]) <= 0;

s.t. r1{i in 1..n}: sum{k in 1..n} z[i,k] = 1;
s.t. r2{i in 1..n, k in 1..n: i != k}: z[i,k] <= z[k,k];
s.t. r3{i in 1..n, k in 1..n: i < k}: sum{m in 1..n} y[i,k,m] - sum{m in 1..n} y[i,m,k] = o[i] * z[i,k] - sum{j in 1..n: i != j} w[i,j] * z[j,k];
s.t. r4{i in 1..n, k in 1..n}: sum{m in 1..n} y[i,k,m] = o[i]*z[i,k];
*/
# =======================================================
# Autor: Ernst-Skorin : SUB-PROBLEMA 
# =======================================================
/*
var u{i in 1..n, j in 1..n, k in 1..n: i < j};
var v{i in 1..n, j in 1..n, m in 1..n: i < j};
var b{i in 1..n, k in 1..n};

param _z{i in 1..n, k in 1..n};
param _y{i in 1..n, k in 1..n, m in 1..n};

maximize fod: sum{i in 1..n, j in 1..n, k in 1..n: i < j}(u[i,j,k] * _z[i,k])
			+ sum{i in 1..n, j in 1..n, m in 1..n: i < j}(v[i,j,m] * _z[j,m])
			+ sum{i in 1..n, k in 1..n, m in 1..n}(b[i,k,m] * _y[i,k,m]);
			
s.t. rd1{i in 1..n, j in 1..n, k in 1..n, m in 1..n: i < j}: u[i,j,k] + v[i,j,m] + w[i,j] * b[i,k,m] + w[j,i] * b[j,m,k] <= 0;
s.t. rd2{i in 1..n, j in 1..n, k in 1..n: i < j}: u[i,j,k] + v[i,j,m] + sum{i in 1..n, k in 1..n, m in 1..n: i < k} b[i,k,m] <= 1;
s.t. rd3{i in 1..n, j in 1..n, k in 1..n: i < j}: u[i,j,k] + v[i,j,m] + sum{i in 1..n, k in 1..n, m in 1..n: i < k} b[i,k,m] >= -1;
*/
end;

