PySCIPOpt  5.1.1
Python Interface for the SCIP Optimization Suite
ssa.py
Go to the documentation of this file.
1 
3 """
4 Approach: use SOS2 constraints for modeling non-linear functions.
5 
6 Copyright (c) by Joao Pedro PEDROSO and Mikio KUBO, 2012
7 """
8 import math
9 import random
10 
11 from pyscipopt import Model, quicksum
12 
13 from piecewise import convex_comb_sos
14 
15 
16 def ssa(n, h, K, f, T):
17  """ssa -- multi-stage (serial) safety stock allocation model
18  Parameters:
19  - n: number of stages
20  - h[i]: inventory cost on stage i
21  - K: number of linear segments
22  - f: (non-linear) cost function
23  - T[i]: production lead time on stage i
24  Returns the model with the piecewise linear relation on added variables x, f, and z.
25  """
26 
27  model = Model("safety stock allocation")
28 
29  # calculate endpoints for linear segments
30  a, b = {}, {}
31  for i in range(1, n + 1):
32  a[i] = [k for k in range(K)]
33  b[i] = [f(i, k) for k in range(K)]
34 
35  # x: net replenishment time for stage i
36  # y: corresponding cost
37  # s: piecewise linear segment of variable x
38  x, y, s = {}, {}, {}
39  L = {} # service time of stage i
40  for i in range(1, n + 1):
41  x[i], y[i], s[i] = convex_comb_sos(model, a[i], b[i])
42  if i == 1:
43  L[i] = model.addVar(ub=0, vtype="C", name="L[%s]" % i)
44  else:
45  L[i] = model.addVar(vtype="C", name="L[%s]" % i)
46  L[n + 1] = model.addVar(ub=0, vtype="C", name="L[%s]" % (n + 1))
47 
48  for i in range(1, n + 1):
49  # net replenishment time for each stage i
50  model.addCons(x[i] + L[i] == T[i] + L[i + 1])
51 
52  model.setObjective(quicksum(h[i] * y[i] for i in range(1, n + 1)), "minimize")
53 
54  model.data = x, s, L
55  return model
56 
57 
58 def make_data():
59  """creates example data set"""
60  n = 30 # number of stages
61  z = 1.65 # for 95% service level
62  sigma = 100 # demand's standard deviation
63  h = {} # inventory cost
64  T = {} # production lead time
65  h[n] = 1
66  for i in range(n - 1, 0, -1):
67  h[i] = h[i + 1] + random.randint(30, 50)
68  K = 0 # number of segments (=sum of processing times)
69  for i in range(1, n + 1):
70  T[i] = random.randint(3, 5) # production lead time at stage i
71  K += T[i]
72  return z, sigma, h, T, K, n
73 
74 
75 if __name__ == "__main__":
76  random.seed(1)
77 
78  z, sigma, h, T, K, n = make_data()
79 
80 
81  def f(i, k):
82  return sigma * z * math.sqrt(k)
83 
84 
85  model = ssa(n, h, K, f, T)
86  model.optimize()
87 
88  # model.write("ssa.lp")
89  x, s, L = model.data
90  for i in range(1, n + 1):
91  for k in range(K):
92  if model.getVal(s[i][k]) >= 0.001:
93  print(s[i][k].name, model.getVal(s[i][k]))
94  print
95  print("%10s%10s%10s%10s" % ("Period", "x", "L", "T"))
96  for i in range(1, n + 1):
97  print("%10s%10s%10s%10s" % (i, model.getVal(x[i]), model.getVal(L[i]), T[i]))
98 
99  print("Objective:", model.getObjVal())
pyscipopt.expr.quicksum
def quicksum(termlist)
Definition: expr.pxi:357
ssa.make_data
def make_data()
Definition: ssa.py:58
piecewise.convex_comb_sos
def convex_comb_sos(model, a, b)
Definition: piecewise.py:50
ssa.ssa
def ssa(n, h, K, f, T)
Definition: ssa.py:16
ssa.f
def f(i, k)
Definition: ssa.py:81
ssa
Definition: ssa.py:1