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

インポート

GRB(定数)クラス

class GRB[source]

GRB()

区分的線形関数

gray[source]

gray(i)

convex_comb_agg_log[source]

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

mult_selection[source]

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番目以降の返値として辞書を返す.

multidict[source]

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メソッドが 準備されている.

class tuplelist[source]

tuplelist(iterable=()) :: list

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)]

線形表現クラス

class LinExpr[source]

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

Linear Expresstion Class

変数クラス

class Variable[source]

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

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))

モデルクラス

class Model[source]

Model(name='') :: LpProblem

Model Class

例題

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)

    # relax=model.relax()
    # model.sos1= { 1:{x1:1,x2:2} }
    model.write("mypulp1.mps")
    model.write("mypulp1.lp")
    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)
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)
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)