# Big Bucket Lot Sizing Problem
# (C) Joao Pedro PEDROSO, Mikio KUBO, Logopt

param T;	# number of periods (months)
set Prod;	# products
set Blck;	# machines (blocks)

param SetUpCost {Prod, Blck, 1..T};	# Yen*10^6/setup
param SetUpTime {Prod, Blck, 1..T};	# hours/setup
param VariableCost {Prod, Blck, 1..T};	# Yen/piece
param HoldingCost {Prod, 1..T};		# Yen/piece on stock at the end of the month
param BacklogCost {Prod, 1..T};		# Yen/piece not served

param Demand {Prod, 1..T} default 0;	# million pieces (for each month)
param MaxRate {Prod, Blck}>=0;		# maximum production rate, million pieces/hour
param WorkHours {Blck, 1..T}>=0;	# hours/month
param FirstInv {Prod} default 0;	# million pieces
param LastInv {Prod} default 0;		# million pieces

set Compat {p in Prod} within {Blck};	# machines that can be used to produce p

# cuts from CP model
param CUT {Blck, 1..T} default 0.;		# CUT: capacity update

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{Prod,0..T} >=0;	# inventory, million pieces
var g{Prod,0..T} >=0;	# backlog, million pieces

var fcost;	# fixed, setup cost
var vcost;	# variable cost
var hcost;	# holding cost
var gcost;	# backlog cost

#
# objective
#
minimize TCost:
  fcost + vcost + hcost + gcost;

subject to FCost:
  fcost = sum{p in Prod, b in Compat[p], t in 1..T} SetUpCost[p,b,t]*y[p,b,t] ;
subject to VCost:
  vcost = sum{p in Prod, b in Compat[p], t in 1..T}  VariableCost[p,b,t]*x[p,b,t];
subject to HCost:
  hcost = sum{p in Prod, t in 1..T} HoldingCost[p,t]*h[p,t];
subject to GCost:
  gcost = sum{p in Prod, t in 1..T} BacklogCost[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] <= WorkHours[b,t] * MaxRate[p,b] * 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]/MaxRate[p,b] + SetUpTime[p,b,t]*y[p,b,t]) 
	<= WorkHours[b,t] - CUT[b,t];


# material conservation
subject to InitialStock{p in Prod}:
  h[p,0] = FirstInv[p];
subject to FinalStock{p in Prod}:
  h[p,T] = LastInv[p];
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]  =  
	Demand[p,t] + (h[p,t] - g[p,t])
;


### #
### # MIP-CP cuts
### #
### subject to LiscosCapAdjust {t in 1..T}:
###   sum{p in Prod, b in Compat[p]} x[p,b,t] <= I[t];
### 
### subject to LiscosNoGood {t in 1..T}:
###   sum{p in Prod, b in Compat[p]} y[p,b,t] <= Y[t];
### 

end;
