Skip to content

Commit 78e84cb

Browse files
authored
Add logarithmic IB branching formulation for SOS2 (instead of embedding) (#9)
1 parent 59cd010 commit 78e84cb

File tree

2 files changed

+38
-12
lines changed

2 files changed

+38
-12
lines changed

src/jump.jl

+36-10
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ function piecewiselinear(m::JuMP.Model, x::JuMP.Variable, pwl::UnivariatePWLFunc
6262
JuMP.@constraint(m, sum(λ[i]*fd[i] for i in 1:n) == z)
6363
if method == :Logarithmic
6464
sos2_logarthmic_formulation!(m, λ)
65+
elseif method == :LogarithmicIB
66+
sos2_logarthmic_IB_formulation!(m, λ)
6567
elseif method == :CC
6668
sos2_cc_formulation!(m, λ)
6769
elseif method == :ZigZag
@@ -117,6 +119,25 @@ function sos2_logarthmic_formulation!(m::JuMP.Model, λ)
117119
nothing
118120
end
119121

122+
function sos2_logarthmic_IB_formulation!(m::JuMP.Model, λ)
123+
counter = m.ext[:PWL].counter
124+
n = length(λ)-1
125+
k = ceil(Int,log2(n))
126+
y = JuMP.@variable(m, [1:k], Bin, basename="y_$counter")
127+
_H = reflected_gray_codes(k)
128+
d = length(_H)
129+
H = Dict(i => _H[i] for i in 1:d)
130+
H[0] = H[1]
131+
H[d+1] = H[d]
132+
for j in 1:k
133+
JuMP.@constraints(m, begin
134+
sum(λ[i] for i in 1:(n+1) if H[i-1][j] == H[i][j] == 1) y[j]
135+
sum(λ[i] for i in 1:(n+1) if H[i-1][j] == H[i][j] == 0) 1 - y[j]
136+
end)
137+
end
138+
nothing
139+
end
140+
120141
function sos2_zigzag_formulation!(m::JuMP.Model, λ)
121142
counter = m.ext[:PWL].counter
122143
n = length(λ)-1
@@ -470,21 +491,26 @@ function piecewiselinear(m::JuMP.Model, x₁::JuMP.Variable, x₂::JuMP.Variable
470491
elseif method == :Incremental
471492
error()
472493
else # formulations with SOS2 along each dimension
494+
Tx = [sum(λ[tˣ,tʸ] forin 1:nˣ) forin 1:nʸ]
495+
Ty = [sum(λ[tˣ,tʸ] forin 1:nʸ) forin 1:nˣ]
473496
if method == :Logarithmic
474-
sos2_logarthmic_formulation!(m, [sum(λ[tˣ,tʸ] forin 1:nˣ) forin 1:nʸ])
475-
sos2_logarthmic_formulation!(m, [sum(λ[tˣ,tʸ] forin 1:nʸ) forin 1:nˣ])
497+
sos2_logarthmic_formulation!(m, Tx)
498+
sos2_logarthmic_formulation!(m, Ty)
499+
elseif method == :LogarithmicIB
500+
sos2_logarthmic_IB_formulation!(m, Tx)
501+
sos2_logarthmic_IB_formulation!(m, Ty)
476502
elseif method == :ZigZag
477-
sos2_zigzag_formulation!(m, [sum(λ[tˣ,tʸ] forin 1:nˣ) forin 1:nʸ])
478-
sos2_zigzag_formulation!(m, [sum(λ[tˣ,tʸ] forin 1:nʸ) forin 1:nˣ])
503+
sos2_zigzag_formulation!(m, Tx)
504+
sos2_zigzag_formulation!(m, Ty)
479505
elseif method == :ZigZagInteger
480-
sos2_zigzag_general_integer_formulation!(m, [sum(λ[tˣ,tʸ] forin 1:nˣ) forin 1:nʸ])
481-
sos2_zigzag_general_integer_formulation!(m, [sum(λ[tˣ,tʸ] forin 1:nʸ) forin 1:nˣ])
506+
sos2_zigzag_general_integer_formulation!(m, Tx)
507+
sos2_zigzag_general_integer_formulation!(m, Ty)
482508
elseif method == :GeneralizedCelaya
483-
sos2_generalized_celaya_formulation!(m, [sum(λ[tˣ,tʸ] forin 1:nˣ) forin 1:nʸ])
484-
sos2_generalized_celaya_formulation!(m, [sum(λ[tˣ,tʸ] forin 1:nʸ) forin 1:nˣ])
509+
sos2_generalized_celaya_formulation!(m, Tx)
510+
sos2_generalized_celaya_formulation!(m, Ty)
485511
elseif method == :SymmetricCelaya
486-
sos2_symmetric_celaya_formulation!(m, [sum(λ[tˣ,tʸ] forin 1:nˣ) forin 1:nʸ])
487-
sos2_symmetric_celaya_formulation!(m, [sum(λ[tˣ,tʸ] forin 1:nʸ) forin 1:nˣ])
512+
sos2_symmetric_celaya_formulation!(m, Tx)
513+
sos2_symmetric_celaya_formulation!(m, Ty)
488514
elseif method == :SOS2
489515
γˣ = JuMP.@variable(m, [1:nˣ], lowerbound=0, upperbound=1, basename="γˣ_$counter")
490516
γʸ = JuMP.@variable(m, [1:nʸ], lowerbound=0, upperbound=1, basename="γʸ_$counter")

test/runtests.jl

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ using Base.Test
44
using JuMP, Cbc
55

66
const solver = CbcSolver()
7-
methods_1D = (:CC,:MC,:Logarithmic,:ZigZag,:ZigZagInteger,:SOS2,:GeneralizedCelaya,:SymmetricCelaya,:Incremental)
8-
methods_2D = (:CC,:MC,:Logarithmic,:ZigZag,:ZigZagInteger,:SOS2,:GeneralizedCelaya,:SymmetricCelaya)
7+
methods_1D = (:CC,:MC,:Logarithmic,:LogarithmicIB,:ZigZag,:ZigZagInteger,:SOS2,:GeneralizedCelaya,:SymmetricCelaya,:Incremental)
8+
methods_2D = (:CC,:MC,:Logarithmic,:LogarithmicIB,:ZigZag,:ZigZagInteger,:SOS2,:GeneralizedCelaya,:SymmetricCelaya)
99

1010
let d = linspace(1,2π,8), f = sin
1111
for method in methods_1D

0 commit comments

Comments
 (0)