数理最適化モジュール mypulp

混合整数問題をモデル化するためのモジュール pulp を商用パッケージGurobiと同じ文法で記述するためのラッパーモジュール

インポート

GRB(定数)クラス


source

GRB

 GRB ()

Initialize self. See help(type(self)) for accurate signature.

区分的線形関数


source

gray

 gray (i)

source

convex_comb_agg_log

 convex_comb_agg_log (model, var_list=[])

add piecewise relation with a logarithmic number of binary variables

using the convex combination formulation – non-disaggregated. Parameters: - model: a model where to include the SOS type 2 - vars : list of variables that declare the SOS type 2


source

mult_selection

 mult_selection (model, x, a, b)

mult_selection – add piecewise relation with multiple selection formulation Parameters: - model: a model where to include the piecewise linear relation - a[k]: x-coordinate of the k-th point in the piecewise linear relation - b[k]: y-coordinate of the k-th point in the piecewise linear relation Returns the model with the piecewise linear relation on added variables x, f, and z.

multidict関数

multidict関数は,辞書を引数として入力すると, 第1の返値としてキーのリスト,2番目以降の返値として辞書を返す.


source

multidict

 multidict (dic)
I,d = multidict({1:80, 2:270, 3:250 , 4:160, 5:180})
J,M,N = multidict({1:[500,600], 2:[800,500], 3:[500,100]})
print(I,d)
print(J,M,N)
[1, 2, 3, 4, 5] {1: 80, 2: 270, 3: 250, 4: 160, 5: 180}
[1, 2, 3] {1: 500, 2: 800, 3: 500} {1: 600, 2: 500, 3: 100}

tuplelistクラス

tuplelistは,名前の通りタプル(組)を要素としたリストである.

tuplelistには,引数によって指定した条件を満たす要素を取り出すselectメソッドが 準備されている.


source

tuplelist

 tuplelist (iterable=())

Tuplelist class for mypulp.py It works like Gurobi’s tuplelist

cost = {(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
        } 
arcs = tuplelist([(i,j) for (i,j) in cost])
print( arcs.select(2,"*") )
[(2, 1), (2, 2), (2, 3)]

線形表現クラス


source

LinExpr

 LinExpr (coeff=[], var=[])

Linear Expresstion Class

変数クラス


source

Variable

 Variable (name='', lowBound=0.0, upBound=1e+100, cat='Continuous')

Variable Class

CBC options

Coin Branch and Cutを用いて最適化する際に,以下のオプションを付加することができる.

class pulp.apis.PULP_CBC_CMD(mip=True, msg=True, timeLimit=None, fracGap=None, maxSeconds=None, gapRel=None, gapAbs=None, presolve=None, cuts=None, strong=None, options=None, warmStart=False, keepFiles=False, path=None, threads=None, logPath=None, mip_start=False)
Bases: pulp.apis.coin_api.COIN_CMD

This solver uses a precompiled version of cbc provided with the package

Parameters

  • mip (bool) – if False, assume LP even if integer variables

  • msg (bool) – if False, no log is shown

  • timeLimit (float) – maximum time for solver (in seconds)

  • gapRel (float) – relative gap tolerance for the solver to stop (in fraction)

  • gapAbs (float) – absolute gap tolerance for the solver to stop

  • threads (int) – sets the maximum number of threads

  • options (list) – list of additional options to pass to solver

  • warmStart (bool) – if True, the solver will use the current value of variables as a start

  • keepFiles (bool) – if True, files are saved in the current directory and not deleted after solving

  • path (str) – path to the solver binary

  • logPath (str) – path to the log file

  • presolve (bool) – if True, adds presolve on

  • cuts (bool) – if True, adds gomory on knapsack on probing on

  • strong (bool) – if True, adds strong

モデルクラスの最適化メソッド optimize の引数 solverで, PULP_CBC_CMDのインスタンスを渡す.

 optimize(self, solver=PULP_CBC_CMD(timeLimit=max_cpu, presolve=True)) 

モデルクラス


source

Model

 Model (name='')

Model Class

例題

TEST=False
if TEST:
    model = Model("lo1")

    J, v = multidict({1: 16, 2: 19, 3: 23, 4: 28})

    # x1 = model.addVar(vtype="C", name="x1")
    # x2 = model.addVar(vtype="I", name="x2")
    # x3 = model.addVar(lb=0, ub=30, vtype="B", name="x3")

    x1 = model.addVar(vtype=GRB.CONTINUOUS, name="x1")
    # x1 = model.addVar(vtype="N", lb=10.5, ub=50,name="x1")
    x2 = model.addVar(vtype="C", name="x2")
    x3 = model.addVar(lb=0, ub=30, vtype="C", name="x3")

    model.update()
    #model.addSOS(2, [x1, x2, x3])
    #L1 = LinExpr([2, 1, 1], [x1, x2, x3])
    # L1=LinExpr()
    # L1.addTerms(2,x1)
    # L1.addTerms(1,x2)
    # L1.addTerms(1,x3)

    #model.addConstr(lhs=L1,sense="<=",rhs=60,name="C0")
    model.addConstr(x1 + 2*x2 + x3 <= 60, name="C1")

    #c1 = model.addConstr(lhs=L1, sense="<=", rhs=60)
    model.addConstr(x1 + 2 * x2 + x3 <= 60)

    model.setObjective(15 * x1 + 18 * x2 + 30 * x3, GRB.MAXIMIZE)

    #model.write("mypulp1.mps")
    #model.write("mypulp1.lp")
    
    #SCIPを使用する場合
    #solver = pulp.SCIP(timeLimit=1)
    #model.optimize(solver=solver)
    
    #model.optimize()

    if model.Status == GRB.Status.OPTIMAL:
        model.write("answer.sol")
        print("Opt. Value=", model.ObjVal)
        # for v in model.getVars():
        #    print(v.VarName,v.X,v.RC)
        for v in model.getVars():
            print(v.VarName, v.X)
        for c in model.getConstrs():
            print(c.ConstrName, c.Pi)
    # m=Model()
    # x=m.addVar( name="x", vtype="I" , lb=1)
    # y=m.addVar( name="y", vtype="I" , lb=1)
    # z=m.addVar( name="z", vtype="I" , lb=1)
    # m.update()
    # m.addConstr(2*x+ y ==11)
    # m.addConstr(y+ 3*z ==14)
    # # m.setObjective(0,GRB.MINIMIZE)
    # m.optimize()
    # print(x.X,y.X,z.X)
Opt. Value= 1350.0
x1 30.0
x2 0.0
x3 30.0
C1 None
c_1 None
if TEST:
    m=Model()

    x = [0,2,3,1]
    y = [1,0,3,3]

    n=len(x)

    X=m.addVar(ub=3.0, name="X")
    Y=m.addVar(ub=3.0, name ="Y")

    Z=m.addVar(name ="Z")

    a,b={},{}
    for i in range(n):
        a[i] =m.addVar(name="a({0})".format(i))
        b[i] =m.addVar(name="b({0})".format(i))
        m.update()

    for i in range(n):
        m.addConstr( a[i] >= x[i] -X )
        m.addConstr( a[i] >= X-x[i] )
        m.addConstr( b[i] >= y[i] -Y )
        m.addConstr( b[i] >= Y-y[i] )

        m.addConstr(Z>=a[i]+b[i])

    m.setObjective(Z, GRB.MINIMIZE)
    # m.setObjective( quicksum( 1*a[i] for i in range(n))
    #                + quicksum( 1*b[i] for i in range(n)), GRB.MINIMIZE )


    m.optimize()

    print(X.X,Y.X)
    print(m.ObjVal)
    for i in range(n):
        print(a[i].X,b[i].X)
Welcome to the CBC MILP Solver 
Version: 2.10.3 
Build Date: Dec 15 2019 

command line - /Users/mikiokubo/Library/Caches/pypoetry/virtualenvs/scmopt-KVX_UVCf-py3.8/lib/python3.8/site-packages/pulp/apis/../solverdir/cbc/osx/64/cbc /var/folders/69/5y96sdc94jxf6khgc8mlmxrr0000gn/T/a9600581b8304017ab19ab021b6e0065-pulp.mps branch printingOptions all solution /var/folders/69/5y96sdc94jxf6khgc8mlmxrr0000gn/T/a9600581b8304017ab19ab021b6e0065-pulp.sol (default strategy 1)
At line 2 NAME          MODEL
At line 3 ROWS
At line 25 COLUMNS
At line 71 RHS
At line 92 BOUNDS
At line 104 ENDATA
Problem MODEL has 20 rows, 11 columns and 44 elements
Coin0008I MODEL read with 0 errors
Presolve 10 (-10) rows, 6 (-5) columns and 26 (-18) elements
0  Obj 0 Primal inf 12.999995 (5)
6  Obj 2.5
Optimal - objective value 2.5
After Postsolve, objective 2.5, infeasibilities - dual 0 (0), primal 0 (0)
Optimal objective 2.5 - 6 iterations time 0.002, Presolve 0.00
Option for printingOptions changed from normal to all
Total time (CPU seconds):       0.00   (Wallclock seconds):       0.01

1.5 2.0
2.5
1.5 1.0
0.5 2.0
1.5 1.0
1.5 1.0
if TEST:
    model = Model("lo1")

    x = model.addVar(name='tonkoke')
    y = model.addVar(name='kokenton')
    z = model.addVar(name='mix')

    model.setObjective(15*x + 18*y + 30*z, GRB.MAXIMIZE)
    model.addConstr(2*x +   y + z <= 60, name='pork')
    model.addConstr(  x + 2*y + z <= 60, name='chicken')
    model.addConstr(            z <= 30, name='beef')

    model.optimize()
    print( model.ObjVal )
    for i in model.getVars():
        print(i.VarName, i.X)
Welcome to the CBC MILP Solver 
Version: 2.10.3 
Build Date: Dec 15 2019 

command line - /Users/mikiokubo/Library/Caches/pypoetry/virtualenvs/scmopt-KVX_UVCf-py3.8/lib/python3.8/site-packages/pulp/apis/../solverdir/cbc/osx/64/cbc /var/folders/69/5y96sdc94jxf6khgc8mlmxrr0000gn/T/3175126010324092b3a9adfcf59ef2f7-pulp.mps max branch printingOptions all solution /var/folders/69/5y96sdc94jxf6khgc8mlmxrr0000gn/T/3175126010324092b3a9adfcf59ef2f7-pulp.sol (default strategy 1)
At line 2 NAME          MODEL
At line 3 ROWS
At line 8 COLUMNS
At line 19 RHS
At line 23 BOUNDS
At line 27 ENDATA
Problem MODEL has 3 rows, 3 columns and 7 elements
Coin0008I MODEL read with 0 errors
Presolve 2 (-1) rows, 3 (0) columns and 6 (-1) elements
0  Obj -0 Dual inf 62.999997 (3)
2  Obj 1230
Optimal - objective value 1230
After Postsolve, objective 1230, infeasibilities - dual 0 (0), primal 0 (0)
Optimal objective 1230 - 2 iterations time 0.002, Presolve 0.00
Option for printingOptions changed from normal to all
Total time (CPU seconds):       0.00   (Wallclock seconds):       0.00

1230.0
kokenton 10.0
mix 30.0
tonkoke 10.0