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