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にクローズされました