# source:coopr.pysp/trunk/examples/pysp/lotsizing/models/ReferenceModel.py@2460

Last change on this file since 2460 was 2460, checked in by jwatson, 9 years ago

Various tweaks to the lot sizing model.

File size: 3.3 KB
Line
1#
2# A lot-sizing problem, taken from Haugen, Lokketangen, and Woodruff (2001).
3# European Journal of Operational Reserach, Volume 132, pp. 116-122.
4#
5
6from coopr.pyomo import *
7
8#
9# Model
10#
11
12model = Model()
13
14#
15# Parameters
16#
17
18# the number of stages.
19model.NumStages = Param(within=PositiveIntegers)
20
21# derived set.
22def stages_set_rule(model):
23   return set(range(1, model.NumStages()+1))
24model.Stages = Set(rule=stages_set_rule)
25
26# the initial inventory, at time stage 0.
27model.InitialInventory = Param(within=NonNegativeReals)
28
29# the production setup cost in each time period.
30model.SetupCost = Param(model.Stages, within=NonNegativeReals)
31
32# the holding cost for inventory in each time period.
33model.HoldingCost = Param(model.Stages, within=NonNegativeReals)
34
35# the shortage cost for inventory in each time period.
36model.ShortageCost = Param(model.Stages, within=NonNegativeReals)
37
38# the demand for inventory in each time period.
39model.Demand = Param(model.Stages, within=NonNegativeReals)
40
41# the big M coefficient used to compute the production binary.
42# production is trivially bounded by the sum of demand across
43# stages minus the initial inventory.
44def compute_m_rule(model):
45   result = sum([model.Demand[t] for t in model.Stages]) - model.InitialInventory
46   return result()
47model.M = Param(within=NonNegativeReals, rule=compute_m_rule)
48
49#
50# Variables
51#
52
53# does production occur in time period t?
54model.Produce = Var(model.Stages, within=Binary)
55
56# TBD - upper bounds can be computed for each amount produced, inventory,
57#       backlog variable - introduce bounds rule.
58
59# the amount of product to be produced in time period t.
60model.AmountProduced = Var(model.Stages, within=NonNegativeReals)
61
62# the excess inventory at the end of time period t.
63model.Inventory = Var(model.Stages, within=NonNegativeReals)
64
65# the inventory backlog at the end of time period t.
66model.Backlog = Var(model.Stages, within=NonNegativeReals)
67
68# the cost variables for the stages.
69model.StageCost = Var(model.Stages)
70
71#
72# Constraints
73#
74
75# can't produce unless production is enabled!
76def limit_production_rule(t, model):
77   return (None, model.AmountProduced[t] - model.M * model.Produce[t], 0.0)
78model.LimitProduction = Constraint(model.Stages, rule=limit_production_rule)
79
80# enforce inventory balance for each time period.
81def inventory_balance_rule(t, model):
82   expr = None
83   if (t == 1):
84      # there is no initial backlog.
85      expr = model.AmountProduced[t] + model.InitialInventory + model.Backlog[t] - \
86             model.Inventory[t] - model.Demand[t]
87   else:
88      expr = model.AmountProduced[t] + model.Inventory[t-1] + model.Backlog[t] - \
89             model.Inventory[t] - model.Backlog[t-1] - model.Demand[t]
90   return (expr == 0.0)
91model.InventoryBalance = Constraint(model.Stages, rule=inventory_balance_rule)
92
93#
94# Stage-specific cost computations
95#
96
97def compute_stage_cost_rule(t, model):
98   cost = sum([model.SetupCost[t] * model.Produce[t] + \
99               model.HoldingCost[t] * model.Inventory[t] + \
100               model.ShortageCost[t] * model.Backlog[t]])
101
102   return (model.StageCost[t] - cost) == 0.0
103
104model.ComputeStageCost = Constraint(model.Stages, rule=compute_stage_cost_rule)
105
106#
107# Objective
108#
109
110def total_cost_rule(model):
111    return sum([model.StageCost[t] for t in model.Stages])
112
113model.Total_Cost_Objective = Objective(rule=total_cost_rule, sense=minimize)
Note: See TracBrowser for help on using the repository browser.