4 Approach: use SOS2 constraints for modeling non-linear functions.
6 Copyright (c) by Joao Pedro PEDROSO and Mikio KUBO, 2012
11 from pyscipopt
import Model, quicksum
13 from piecewise
import convex_comb_sos
16 def ssa(n, h, K, f, T):
17 """ssa -- multi-stage (serial) safety stock allocation model
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.
27 model = Model(
"safety stock allocation")
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)]
40 for i
in range(1, n + 1):
43 L[i] = model.addVar(ub=0, vtype=
"C", name=
"L[%s]" % i)
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))
48 for i
in range(1, n + 1):
50 model.addCons(x[i] + L[i] == T[i] + L[i + 1])
52 model.setObjective(
quicksum(h[i] * y[i]
for i
in range(1, n + 1)),
"minimize")
59 """creates example data set"""
66 for i
in range(n - 1, 0, -1):
67 h[i] = h[i + 1] + random.randint(30, 50)
69 for i
in range(1, n + 1):
70 T[i] = random.randint(3, 5)
72 return z, sigma, h, T, K, n
75 if __name__ ==
"__main__":
82 return sigma * z * math.sqrt(k)
85 model =
ssa(n, h, K, f, T)
90 for i
in range(1, n + 1):
92 if model.getVal(s[i][k]) >= 0.001:
93 print(s[i][k].name, model.getVal(s[i][k]))
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]))
99 print(
"Objective:", model.getObjVal())