# 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 GUB;
param CAP{p in Prod, b in Compat[p], 1..T};

param C1;
param C2;
param C3;
param C4;

param hUB;
param gUB;

param Demand {Prod, 1..T};	# million pieces (for each month)
param FirstInv {Prod} default 0;	# million pieces
param LastInv {Prod} default 0;		# million pieces


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;
var g{Prod,0..T} >= 0;
var hA{p in Prod,0..T} >= 0, <= hUB;
var gA{Prod,0..T} >= 0, <= gUB;


# material conservation
subject to InitialStock{p in Prod}:
  h[p,0] = FirstInv[p];
subject to InitialBacklog{p in Prod}:
  g[p,0] = 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]  =  
	Demand[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 HA { p in Prod, t in 1..T }:
  h[p,t] >= hA[p,t];

subject to BA { p in Prod, t in 1..T }:
  g[p,t] >= gA[p,t];

subject to GlobUB { t in 1..T }:
  sum {p in Prod, b in Compat[p]} y[p,b,t] <= GUB;

#
# objective
#
minimize TCost:
    sum{p in Prod, t in 1..T} (	C1 * h[p,t] - C2 * hA[p,t] + C3 * g[p,t] - C4 * gA[p,t] );

end;
