In [1]:
#線形最適化問題
from gurobipy import *

In [21]:
#モデルを作成
model = Model("k")

In [22]:
#modelに変数を追加 addVar
x1 = model.addVar(ub =5, lb=0 ,name="x1")
x2 = model.addVar(ub =6 ,lb=0, name="x2")
x3 = model.addVar(ub = 4, lb=0,name="x3")
model.update()

In [23]:
#制約の追加 addConstr
model.addConstr(x1 + x2 + x3 == 7)


Out[23]:
<gurobi.Constr *Awaiting Model Update*>

In [24]:
#目的関数の設定 setObjective
model.setObjective(121- x1 - 3*x2 - 4*x3)

In [25]:
#目的関数の方向を設定 ModelSense = -1で最大化 1で最小化 規定値は1
model.ModelSense =1

In [26]:
#解の出力 ObjVal
from __future__ import division
model.optimize()
print "Opt. Value= " ,model.ObjVal


Optimize a model with 1 rows, 3 columns and 3 nonzeros
Coefficient statistics:
  Matrix range    [1e+00, 1e+00]
  Objective range [1e+00, 4e+00]
  Bounds range    [4e+00, 6e+00]
  RHS range       [7e+00, 7e+00]
Presolve time: 0.00s
Presolved: 1 rows, 3 columns, 3 nonzeros

Iteration    Objective       Primal Inf.    Dual Inf.      Time
       0    9.3000000e+01   3.000000e+00   0.000000e+00      0s
       1    9.6000000e+01   0.000000e+00   0.000000e+00      0s

Solved in 1 iterations and 0.01 seconds
Optimal objective  9.600000000e+01
Opt. Value=  96.0

In [27]:
#会の出力その2 getVarsは変数オブジェクトのリストを返す VarNameとX
for v in model.getVars():
    print v.VarName, v.X


x1 0.0
x2 3.0
x3 4.0

In [24]:
#これでも最適解を出力可能
print "(x1, x2 ,x3)=" , x1.X, x2.X, x3.X


(x1, x2 ,x3)= 10.0 10.0 30.0

In [25]:
#整数最適化問題 ほとんど上と同じ vtypeをIにするだけ
model = Model("turukame")
x = model.addVar(vtype = "I")
y = model.addVar(vtype = "I")
z = model.addVar(vtype = "I")
model.update()
model.addConstr(x + y+ z == 32)
model.addConstr(2*x + 4*y +8*z == 80)
model.setObjective(y + z )
model.optimize()
print "Opt. Value =" ,model.ObjVal
print "(x,y,z)=" , x.X ,y.X ,z.X


Optimize a model with 2 rows, 3 columns and 6 nonzeros
Coefficient statistics:
  Matrix range    [1e+00, 8e+00]
  Objective range [1e+00, 1e+00]
  Bounds range    [0e+00, 0e+00]
  RHS range       [3e+01, 8e+01]
Presolve removed 2 rows and 3 columns
Presolve time: 0.00s

Explored 0 nodes (0 simplex iterations) in 0.00 seconds
Thread count was 1 (of 4 available processors)

Optimal solution found (tolerance 1.00e-04)
Best objective 4.000000000000e+00, best bound 4.000000000000e+00, gap 0.0%
Opt. Value = 4.0
(x,y,z)= 28.0 2.0 2.0

In [72]:
#輸送問題
model = Model()

In [73]:
#顧客リストと需用量辞書、工場リストと供給量リストの同時出力 multidict
I,d = multidict({1:80, 2:270 ,3:250 ,4:160 ,5:180})
J,M = multidict({1:500 ,2:500 ,3:500})

In [35]:
I


Out[35]:
[1, 2, 3, 4, 5]

In [37]:
J


Out[37]:
[1, 2, 3]

In [38]:
d


Out[38]:
{1: 80, 2: 270, 3: 250, 4: 160, 5: 180}

In [39]:
M


Out[39]:
{1: 500, 2: 500, 3: 500}

In [74]:
#輸送費用の設定 タプルで顧客と工場の関係を表示 タプルをキーとする辞書型
c = {(1,1):4, (1,2):6, (1,3):9, (2,1):5, (2,2):4, (2,3):7, (3,1):6, (3,2):3, (3,3):4, (4,1):8, (4,2):5, (4,3):3, (5,1):10, (5,2):8, (5,3):4}

In [40]:
c


Out[40]:
{(1, 1): 4,
 (1, 2): 6,
 (1, 3): 9,
 (2, 1): 5,
 (2, 2): 4,
 (2, 3): 7,
 (3, 1): 6,
 (3, 2): 3,
 (3, 3): 4,
 (4, 1): 8,
 (4, 2): 5,
 (4, 3): 3,
 (5, 1): 10,
 (5, 2): 8,
 (5, 3): 4}

In [75]:
#変数の作成
x = {}
for i in I:
    for j in J:
        x[i,j] = model.addVar(vtype = "C", name = "x(%s,%s)" %(i,j))
model.update()

In [21]:
x


Out[21]:
{(1, 1): <gurobi.Var x(1,1)>,
 (1, 2): <gurobi.Var x(1,2)>,
 (1, 3): <gurobi.Var x(1,3)>,
 (2, 1): <gurobi.Var x(2,1)>,
 (2, 2): <gurobi.Var x(2,2)>,
 (2, 3): <gurobi.Var x(2,3)>,
 (3, 1): <gurobi.Var x(3,1)>,
 (3, 2): <gurobi.Var x(3,2)>,
 (3, 3): <gurobi.Var x(3,3)>,
 (4, 1): <gurobi.Var x(4,1)>,
 (4, 2): <gurobi.Var x(4,2)>,
 (4, 3): <gurobi.Var x(4,3)>,
 (5, 1): <gurobi.Var x(5,1)>,
 (5, 2): <gurobi.Var x(5,2)>,
 (5, 3): <gurobi.Var x(5,3)>}

In [76]:
#制約の追加  オプションで制約にも名前をつけていることに注意 ここではそれぞれDeman(i)という制約にしている。
for i in I:
    model.addConstr(quicksum(x[i,j] for j in J) == d[i], name = "Demand(%s)" % i)

In [77]:
for j in J:
    model.addConstr(quicksum(x[i,j] for i in I ) <= M[j] ,name = "Capacity(%s)"% j )

In [29]:
#次の二つはどちらでも良い
c[(1,2)]


Out[29]:
6

In [30]:
c[1,2]


Out[30]:
6

In [78]:
#目的関数の設定
model.setObjective(quicksum(c[i,j]*x[i,j] for (i,j) in x) ,GRB.MINIMIZE)

In [79]:
model.optimize()


Optimize a model with 8 rows, 15 columns and 30 nonzeros
Coefficient statistics:
  Matrix range    [1e+00, 1e+00]
  Objective range [3e+00, 1e+01]
  Bounds range    [0e+00, 0e+00]
  RHS range       [8e+01, 5e+02]
Presolve time: 0.00s
Presolved: 8 rows, 15 columns, 30 nonzeros

Iteration    Objective       Primal Inf.    Dual Inf.      Time
       0    3.3500000e+03   2.000000e+01   0.000000e+00      0s
       1    3.3700000e+03   0.000000e+00   0.000000e+00      0s

Solved in 1 iterations and 0.01 seconds
Optimal objective  3.370000000e+03

In [81]:
#結果の表示
print "optimal value:" , model.ObjVal
EPS = 1.e-6 #0以下の結果を表示しないために
for (i,j) in x:
    if x[i,j].X > EPS:
        print "sending quantity %10s from %3s to customer %3s" %(x[i,j].X,j,i) #Xで値だけ呼ばないと、編すの持つ全ての要素が呼び出される。


optimal value: 3370.0
sending quantity      230.0 from   2 to customer   3
sending quantity       20.0 from   3 to customer   3
sending quantity      160.0 from   3 to customer   4
sending quantity      270.0 from   2 to customer   2
sending quantity       80.0 from   1 to customer   1
sending quantity      180.0 from   3 to customer   5

In [83]:
#双対問題
print "Const. Name : Slack ,Dual"
for c in model.getConstrs():
    print "%s : %s, %s" %(c.ConstrName , c.Slack, c.pi)


Const. Name : Slack ,Dual
Demand(1) : 0.0, 4.0
Demand(2) : 0.0, 5.0
Demand(3) : 0.0, 4.0
Demand(4) : 0.0, 3.0
Demand(5) : 0.0, 4.0
Capacity(1) : 420.0, 0.0
Capacity(2) : 0.0, -1.0
Capacity(3) : 140.0, 0.0

In [84]:
#混合問題
#各原料が含む成分の割合
a = {(1,1):.25 ,(1,2):.15 ,(1,3):.3, (2,1):.3 ,(2,2):.3 ,(2,3):.1 ,(3,1):.15 ,(3,2):.65 ,(3,3):.05 ,(4,1):.1 ,(4,2):.05 ,(4,3):.85}

In [88]:
#各種データ
I,p = multidict({1:5, 2:6 ,3:8 ,4:20})
K,LB,UB = multidict({1:[.1,.2], 2:[.0,.35], 3:[.45,1.0]})

In [90]:
model = Model("product_mix")
x ={}
for i in I:
    x[i] = model.addVar()
model.update()
model.addConstr(quicksum(x[i] for i in I) == 1)
for k in K:
    model.addConstr(quicksum(a[i,k] * x[i] for i in I ) <= UB[k])
    model.addConstr(quicksum(a[i,k] * x[i] for i in I ) >= LB[k])
model.setObjective(quicksum(p[i] * x[i] for i in I))
model.optimize()
for i in I:
    print i, x[i].X


Optimize a model with 7 rows, 4 columns and 28 nonzeros
Coefficient statistics:
  Matrix range    [5e-02, 1e+00]
  Objective range [5e+00, 2e+01]
  Bounds range    [0e+00, 0e+00]
  RHS range       [1e-01, 1e+00]
Presolve removed 3 rows and 0 columns
Presolve time: 0.00s
Presolved: 4 rows, 6 columns, 18 nonzeros

Iteration    Objective       Primal Inf.    Dual Inf.      Time
       0    7.0372443e+00   7.173123e-01   0.000000e+00      0s
       2    9.6216216e+00   0.000000e+00   0.000000e+00      0s

Solved in 2 iterations and 0.01 seconds
Optimal objective  9.621621622e+00
1 0.648648648649
2 0.0
3 0.0540540540541
4 0.297297297297

In [2]:
#分数最適化 目的関数を制約に取り込んで二分探索法
LB, UB, EPS = 0.0 ,1.0 ,0.01
while 1:
    theta = (UB+LB)/2
    model = Model("tako")
    x = model.addVar(vtype = "I")
    y = model.addVar(vtype = "I")
    z = model.addVar(vtype = "I")
    model.update()
    model.addConstr(x+y+z ==32)
    model.addConstr(2*x +4*y +8*z == 80)
    model.addConstr((2*theta-1)*x +(4*theta-1)*y >=0)
    model.setObjective(x+y+z)
    model.optimize()
    if model.Status == GRB.OPTIMAL:
        UB = theta
        if UB - LB <= EPS:
            break
    else:
        LB = theta
print "(x,y,z)=" , x.X ,y.X ,z.X


Optimize a model with 3 rows, 3 columns and 7 nonzeros
Coefficient statistics:
  Matrix range    [1e+00, 8e+00]
  Objective range [1e+00, 1e+00]
  Bounds range    [0e+00, 0e+00]
  RHS range       [3e+01, 8e+01]
Presolve removed 3 rows and 3 columns
Presolve time: 0.00s

Explored 0 nodes (0 simplex iterations) in 0.01 seconds
Thread count was 1 (of 4 available processors)

Optimal solution found (tolerance 1.00e-04)
Best objective 3.200000000000e+01, best bound 3.200000000000e+01, gap 0.0%
Optimize a model with 3 rows, 3 columns and 7 nonzeros
Coefficient statistics:
  Matrix range    [5e-01, 8e+00]
  Objective range [1e+00, 1e+00]
  Bounds range    [0e+00, 0e+00]
  RHS range       [3e+01, 8e+01]
Presolve removed 1 rows and 1 columns
Presolve time: 0.00s

Explored 0 nodes (0 simplex iterations) in 0.00 seconds
Thread count was 1 (of 4 available processors)

Model is infeasible
Best objective -, best bound -, gap -
Optimize a model with 3 rows, 3 columns and 8 nonzeros
Coefficient statistics:
  Matrix range    [2e-01, 8e+00]
  Objective range [1e+00, 1e+00]
  Bounds range    [0e+00, 0e+00]
  RHS range       [3e+01, 8e+01]
Presolve time: 0.00s

Explored 0 nodes (0 simplex iterations) in 0.01 seconds
Thread count was 1 (of 4 available processors)

Model is infeasible
Best objective -, best bound -, gap -
Optimize a model with 3 rows, 3 columns and 8 nonzeros
Coefficient statistics:
  Matrix range    [1e-01, 8e+00]
  Objective range [1e+00, 1e+00]
  Bounds range    [0e+00, 0e+00]
  RHS range       [3e+01, 8e+01]
Presolve removed 3 rows and 3 columns
Presolve time: 0.00s

Explored 0 nodes (0 simplex iterations) in 0.01 seconds
Thread count was 1 (of 4 available processors)

Optimal solution found (tolerance 1.00e-04)
Best objective 3.200000000000e+01, best bound 3.200000000000e+01, gap 0.0%
Optimize a model with 3 rows, 3 columns and 8 nonzeros
Coefficient statistics:
  Matrix range    [2e-01, 8e+00]
  Objective range [1e+00, 1e+00]
  Bounds range    [0e+00, 0e+00]
  RHS range       [3e+01, 8e+01]
Presolve removed 3 rows and 3 columns
Presolve time: 0.00s

Explored 0 nodes (0 simplex iterations) in 0.01 seconds
Thread count was 1 (of 4 available processors)

Optimal solution found (tolerance 1.00e-04)
Best objective 3.200000000000e+01, best bound 3.200000000000e+01, gap 0.0%
Optimize a model with 3 rows, 3 columns and 8 nonzeros
Coefficient statistics:
  Matrix range    [2e-01, 8e+00]
  Objective range [1e+00, 1e+00]
  Bounds range    [0e+00, 0e+00]
  RHS range       [3e+01, 8e+01]
Presolve time: 0.00s

Explored 0 nodes (0 simplex iterations) in 0.02 seconds
Thread count was 1 (of 4 available processors)

Model is infeasible
Best objective -, best bound -, gap -
Optimize a model with 3 rows, 3 columns and 8 nonzeros
Coefficient statistics:
  Matrix range    [2e-01, 8e+00]
  Objective range [1e+00, 1e+00]
  Bounds range    [0e+00, 0e+00]
  RHS range       [3e+01, 8e+01]
Presolve time: 0.00s

Explored 0 nodes (0 simplex iterations) in 0.01 seconds
Thread count was 1 (of 4 available processors)

Model is infeasible
Best objective -, best bound -, gap -
Optimize a model with 3 rows, 3 columns and 8 nonzeros
Coefficient statistics:
  Matrix range    [2e-01, 8e+00]
  Objective range [1e+00, 1e+00]
  Bounds range    [0e+00, 0e+00]
  RHS range       [3e+01, 8e+01]
Presolve removed 3 rows and 3 columns
Presolve time: 0.00s

Explored 0 nodes (0 simplex iterations) in 0.01 seconds
Thread count was 1 (of 4 available processors)

Optimal solution found (tolerance 1.00e-04)
Best objective 3.200000000000e+01, best bound 3.200000000000e+01, gap 0.0%
(x,y,z)= 24.0 8.0 0.0

In [3]:
#多制約0-1ナップザック問題
#まず問題の定式化と必要なデータ型の準備をする
def example():
    J,v = multidict({1:16,2:19,3:23,4:28})
    a = {(1,1):2 ,(1,2):3 ,(1,3):4 ,(1,4):5 ,(2,1):3000 ,(2,2):3500 ,(2,3):5100 ,(2,4):7200}
    I,b = multidict({1:7, 2:10000})
    return I ,J ,v ,a,b

In [4]:
def mkp(I ,J ,v ,a ,b):
    model = Model("nap")
    x ={}
    for j in J:
        x[j] = model.addVar(vtype ="B" ,name ="x(%d)"%j) #%dは符号付整数 ブール型
    model.update()
    for i in I:
        model.addConstr(quicksum(a[i,j]*x[j] for j in J) <= b[i])
    model.setObjective(quicksum(v[j] * x[j] for j in J), GRB.MAXIMIZE)
    model.update()
    return model

In [5]:
#最適化本番
if __name__ == "__main__": #最適化本番に入る際のおまじない
    I ,J ,v ,a ,b = example()
    model = mkp(I ,J ,v ,a ,b)

In [6]:
#定式化のデバック(ただし、デバック画面を見れない)
model.update()
model.write("mkp.lp")

In [8]:
#最適化
model.optimize()


Optimize a model with 2 rows, 4 columns and 8 nonzeros
Coefficient statistics:
  Matrix range    [2e+00, 7e+03]
  Objective range [2e+01, 3e+01]
  Bounds range    [1e+00, 1e+00]
  RHS range       [7e+00, 1e+04]
Found heuristic solution: objective 35
Presolve removed 2 rows and 4 columns
Presolve time: 0.00s

Explored 0 nodes (0 simplex iterations) in 0.01 seconds
Thread count was 1 (of 4 available processors)

Optimal solution found (tolerance 1.00e-04)
Best objective 4.200000000000e+01, best bound 4.200000000000e+01, gap 0.0%


In [9]:
print "Optimum .Value=" ,model.ObjVal
EPS = 1.e-6
for v in model.getVars():
    if v.X > EPS:
        print v.VarName ,v.X


Optimum .Value= 42.0
x(2) 1.0
x(3) 1.0

In [21]:
#栄養問題
model = Model("nutrients")
F =["c", "b", "d"]
x ={}
for j in F:
    x[j] = model.addVar(vtype ="I" ,name="x(%s)" %j) #%sは文字列への変換だから納得
model.update()

In [24]:
#規約不整合部分系 computeIIS
#逸脱最適化 feasRelaxS
F,c,d = multidict({"CQPounder":  [ 360, {"Cal":556, "Carbo":39, "Protein":30,"VitA":147,"VitC": 10, "Calc":221, "Iron":2.4}],
        "Big Mac"  :  [ 320, {"Cal":556, "Carbo":46, "Protein":26,
                              "VitA":97, "VitC":  9, "Calc":142, "Iron":2.4}],
        "FFilet"   :  [ 270, {"Cal":356, "Carbo":42, "Protein":14,
                              "VitA":28, "VitC":  1, "Calc": 76, "Iron":0.7}],
        "Chicken"  :  [ 290, {"Cal":431, "Carbo":45, "Protein":20,
                              "VitA": 9, "VitC":  2, "Calc": 37, "Iron":0.9}],
        "Fries"    :  [ 190, {"Cal":249, "Carbo":30, "Protein": 3,
                              "VitA": 0, "VitC":  5, "Calc":  7, "Iron":0.6}],
        "Milk"     :  [ 170, {"Cal":138, "Carbo":10, "Protein": 7,
                              "VitA":80, "VitC":  2, "Calc":227, "Iron": 0}],
        "VegJuice" :  [ 100, {"Cal": 69, "Carbo":17, "Protein": 1,
                              "VitA":750,"VitC":  2, "Calc":18,  "Iron": 0}],})

N,a,b = multidict({ 
        "Cal"     : [ 2000,  3000],
        "Carbo"   : [  300,  375 ],
        "Protein" : [   50,   60 ],
        "VitA"    : [  500,  750 ],
        "VitC"    : [   85,  100 ],
        "Calc"    : [  660,  900 ],
        "Iron"    : [  6.0,  7.5 ],
     })

In [26]:
d


Out[26]:
{'Big Mac': {'Cal': 556,
  'Calc': 142,
  'Carbo': 46,
  'Iron': 2.4,
  'Protein': 26,
  'VitA': 97,
  'VitC': 9},
 'CQPounder': {'Cal': 556,
  'Calc': 221,
  'Carbo': 39,
  'Iron': 2.4,
  'Protein': 30,
  'VitA': 147,
  'VitC': 10},
 'Chicken': {'Cal': 431,
  'Calc': 37,
  'Carbo': 45,
  'Iron': 0.9,
  'Protein': 20,
  'VitA': 9,
  'VitC': 2},
 'FFilet': {'Cal': 356,
  'Calc': 76,
  'Carbo': 42,
  'Iron': 0.7,
  'Protein': 14,
  'VitA': 28,
  'VitC': 1},
 'Fries': {'Cal': 249,
  'Calc': 7,
  'Carbo': 30,
  'Iron': 0.6,
  'Protein': 3,
  'VitA': 0,
  'VitC': 5},
 'Milk': {'Cal': 138,
  'Calc': 227,
  'Carbo': 10,
  'Iron': 0,
  'Protein': 7,
  'VitA': 80,
  'VitC': 2},
 'VegJuice': {'Cal': 69,
  'Calc': 18,
  'Carbo': 17,
  'Iron': 0,
  'Protein': 1,
  'VitA': 750,
  'VitC': 2}}

In [6]:
#なぜかinfeasible
model2 =Model("diet")
x ={}
for j in F:
    x[j] = model2.addVar(vtype="I" ,name = "x(%s)" %j)
model2.update()
for i in N:
    model2.addConstr(quicksum(d[j][i]*x[j]  for j in F) >= a[i] ,name ="NutrLB(%s)"%i)
    model2.addConstr(quicksum(d[j][i]*x[j]  for j in F) <= b[i] ,name = "NutrUB(%s)"%i)
model2.setObjective(quicksum(c[j] *x[j]  for j in F))
model2.optimize()


Optimize a model with 14 rows, 7 columns and 92 nonzeros
Coefficient statistics:
  Matrix range    [6e-01, 8e+02]
  Objective range [1e+02, 4e+02]
  Bounds range    [0e+00, 0e+00]
  RHS range       [6e+00, 3e+03]
Presolve removed 1 rows and 0 columns
Presolve time: 0.00s

Explored 0 nodes (0 simplex iterations) in 0.00 seconds
Thread count was 1 (of 4 available processors)

Model is infeasible
Best objective -, best bound -, gap -

In [ ]: