# adapted from LOTSIZELIB's vpm2a instance
# (C) Joao Pedro PEDROSO
#

param T;	# number of periods (months)
param NProd;
param NBlck;
set Prod := {1..NProd};	# products
set Blck := {1..NBlck};	# machines (blocks)
set Compat {p in Prod} within {Blck} default {Blck};	# machines that can be used to produce p

param DEM {Prod, 1..T};
param C {b in Blck, 1..T};
param RHO {p in Prod, b in Compat[p]};
param ST {p in Prod, b in Compat[p]};
param F {p in Prod};
param H {p in Prod};
param CAP {p in Prod, b in Compat[p], t in 1..T} := C[b,t] - ST[p,b];


var y{p in Prod, b in Compat[p], 1..T} binary; 	# 1 if p is produced in b on period t, 0 oth.
var x{p in Prod, b in Compat[p], 1..T} >=0;	# quantity of p produced on block b, period t
var h{p in Prod,0..T} >= 0;	# inventory, million pieces
var g{Prod,0..T} >= 0;	# backlog, million pieces


# material conservation
subject to InitialStock{p in Prod}:
  h[p,0] = 0;

subject to InitialBacklog{p in Prod}:
  g[p,0] = 0;
# subject to FinalBacklog{p in Prod}:
#  g[p,T] = 0;

subject to FlowConservation{p in Prod,t in 1..T}:
  (h[p,t-1] - g[p,t-1]) + sum{b in Compat[p]} x[p,b,t]  =  
	DEM[p,t] + (h[p,t] - g[p,t])
;


#
# machine setup
#
subject to ProductionSetupConnect{ p in Prod, b in Compat[p], t in 1..T }:
  x[p,b,t] <= CAP[p,b,t] * y[p,b,t];

subject to ResourceUpperBound {b in Blck, t in 1..T}:
  sum {p in Prod : b in Compat[p]} x[p,b,t] <= 
       C[b,t] - sum {p in Prod : b in Compat[p]} (ST[p,b] * y[p,b,t]) ;

#
# objective
#
minimize TCost:
    sum{p in Prod, b in Compat[p], t in 1..T} F[p] * y[p,b,t] +
	sum{p in Prod, t in 1..T} H[p] * h[p,t] +
	sum{p in Prod, t in 1..T} 99999 * g[p,t]
	;

end;
