Closed3

数理最適化, JuMP

たきろぐたきろぐ

Ume本の分枝限定法の計算をワザとJuMPでやってみる

using JuMP
using Cbc
using MathOptInterface

# 初期の緩和問題
m = Model(with_optimizer(Cbc.Optimizer))
set_optimizer_attribute(m, "logLevel", 0)
c = [3, 4, 1, 2]
A = [2 3 1 3]
b = [4]
@variable(m, 0 <= x[1:4] <= 1)
@objective(m, Max, sum(c[i] * x[i] for i in 1:4))
for i in 1:size(A)[1]
    @constraint(m, sum(A[i, j] * x[j] for j in 1:4) <= b[i])
end
optimize!(m)

# 解
println(termination_status(m))
if termination_status(m) == MathOptInterface.OPTIMAL
    obj0 = objective_value(m);
    X0 = value.(x);
    println(obj0, " ", X0)
    for i in 1:4
        xif, xic = floor(Int, X0[i]), ceil(Int, X0[i])
        (xif != xic) && println("$i $xif $xic")
    end
end

これに制約を加えながら解いていくと,infeasibleなP6以外の解が以下のように得られる

println("$obj1 $X1")
println("$obj2 $X2")
println("$obj3 $X3")
println("$obj4 $X4")
println("$obj5 $X5")
# println("$obj6 $X6")

> 4.666666666666666 [1.0, 0.0, 1.0, 0.33333333333333326]
> 5.5 [0.5, 1.0, 0.0, 0.0]
> 3.5 [0.5, 0.0, 0.0, 1.0]
> 4.0 [1.0, 0.0, 1.0, 0.0]
> 5.0 [0.0, 1.0, 1.0, 0.0]

よってX5の解が,変数が全て整数 (0 or 1)で目的関数が最大になる.

たきろぐたきろぐ

ベタ書きのJuMPモデルを関数にした

function problem(; constraints=Dict(), best_obj_ever=0.0)
    # 問題
    m = Model(with_optimizer(Cbc.Optimizer))
    set_optimizer_attribute(m, "logLevel", 0)
    
    # 例題 (page 250)
    N = 4
    c = [3, 4, 1, 2]
    A = [2 3 1 3]
    b = [4]
    @variable(m, 0 <= x[1:N] <= 1)
    @objective(m, Max, sum(c[i] * x[i] for i in 1:N))
    for i in 1:size(A)[1]
        @constraint(m, sum(A[i, j] * x[j] for j in 1:N) <= b[i])
    end
    for (k, v) in constraints
        @constraint(m, x[k] == v)
    end
    optimize!(m)
    
    # 実行可能なら解析
    if termination_status(m) == MathOptInterface.OPTIMAL
        obj = objective_value(m)
        flag = obj > best_obj_ever
        X = value.(x)
        non_integer = false
        non_integer_list = Int[]
        for i in 1:N
            xif, xic = floor(Int, X[i]), ceil(Int, X[i])
            if (xif != xic)
                non_integer = true
                push!(non_integer_list, i)
            end
        end
        return flag, obj, X, non_integer_list
    else
        return false, nothing, nothing, nothing, nothing
    end
end
たきろぐたきろぐ

BnBのモック実装のために必要なもの

  • 上の関数の返り値をstructにしてまとめる
  • 木探索構造をLightGraphs.jl, MetaGraphs.jlで作る (or, 自作の木構造, Dictなどで作る)
  • 丸めてbranchする分岐,最適値を見てboundする操作を実装する
このスクラップは2021/02/25にクローズされました