Skip to content

Commit 10f384a

Browse files
odowkofgokhan
andauthored
Various fixes to TambyVanderpooten (#110)
Co-authored-by: Gökhan Kof <kofgokhan@gmail.com>
1 parent be91d02 commit 10f384a

File tree

2 files changed

+59
-18
lines changed

2 files changed

+59
-18
lines changed

src/algorithms/TambyVanderpooten.jl

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -30,19 +30,20 @@ function _update_search_region(
3030
y::Vector{Float64},
3131
yN::Vector{Float64},
3232
)
33-
bounds_to_remove = Vector{Float64}[]
3433
p = length(y)
34+
bounds_to_remove = Vector{Float64}[]
35+
bounds_to_add = Dict{Vector{Float64},Vector{Vector{Vector{Float64}}}}()
3536
for u in keys(U_N)
3637
if all(y .< u)
3738
push!(bounds_to_remove, u)
3839
for l in 1:p
3940
u_l = _get_child(u, y, l)
4041
N = [
41-
k != l ? [yi for yi in U_N[u][k] if yi[l] < y[l]] : [y]
42+
k == l ? [y] : [yi for yi in U_N[u][k] if yi[l] < y[l]]
4243
for k in 1:p
4344
]
44-
if all(!isempty(N[k]) for k in 1:p if u_l[k] yN[k])
45-
U_N[u_l] = N
45+
if all(!isempty(N[k]) for k in 1:p if k != l && u_l[k] != yN[k])
46+
bounds_to_add[u_l] = N
4647
end
4748
end
4849
else
@@ -53,27 +54,31 @@ function _update_search_region(
5354
end
5455
end
5556
end
56-
for bound_to_remove in bounds_to_remove
57-
delete!(U_N, bound_to_remove)
57+
for u in bounds_to_remove
58+
delete!(U_N, u)
5859
end
60+
merge!(U_N, bounds_to_add)
5961
return
6062
end
6163

6264
function _get_child(u::Vector{Float64}, y::Vector{Float64}, k::Int)
6365
@assert length(u) == length(y)
64-
return vcat(u[1:k-1], y[k], u[k+1:length(y)])
66+
return vcat(u[1:(k-1)], y[k], u[(k+1):length(y)])
6567
end
6668

6769
function _select_search_zone(
6870
U_N::Dict{Vector{Float64},Vector{Vector{Vector{Float64}}}},
6971
yI::Vector{Float64},
72+
yN::Vector{Float64},
7073
)
71-
i, j =
72-
argmax([
73-
prod(_project(u, k) - _project(yI, k)) for k in 1:length(yI),
74-
u in keys(U_N)
75-
]).I
76-
return i, collect(keys(U_N))[j]
74+
upper_bounds = collect(keys(U_N))
75+
p = length(yI)
76+
hvs = [
77+
u[k] == yN[k] ? 0.0 : prod(_project(u, k) .- _project(yI, k)) for
78+
k in 1:p, u in upper_bounds
79+
]
80+
k_star, j_star = argmax(hvs).I
81+
return k_star, upper_bounds[j_star]
7782
end
7883

7984
function optimize_multiobjective!(
@@ -100,7 +105,6 @@ function optimize_multiobjective!(
100105
warm_start_supported = true
101106
end
102107
solutions = Dict{Vector{Float64},Dict{MOI.VariableIndex,Float64}}()
103-
YN = Vector{Float64}[]
104108
variables = MOI.get(model.inner, MOI.ListOfVariableIndices())
105109
n = MOI.output_dimension(model.f)
106110
yI, yN = zeros(n), zeros(n)
@@ -114,7 +118,7 @@ function optimize_multiobjective!(
114118
return status, nothing
115119
end
116120
_, Y = _compute_point(model, variables, f_i)
117-
yI[i] = Y + 1
121+
yI[i] = Y
118122
model.ideal_point[i] = Y
119123
MOI.set(model.inner, MOI.ObjectiveSense(), MOI.MAX_SENSE)
120124
MOI.optimize!(model.inner)
@@ -124,7 +128,7 @@ function optimize_multiobjective!(
124128
return status, nothing
125129
end
126130
_, Y = _compute_point(model, variables, f_i)
127-
yN[i] = Y
131+
yN[i] = Y + 1
128132
end
129133
MOI.set(model.inner, MOI.ObjectiveSense(), MOI.MIN_SENSE)
130134
U_N = Dict{Vector{Float64},Vector{Vector{Vector{Float64}}}}()
@@ -136,7 +140,7 @@ function optimize_multiobjective!(
136140
status = MOI.TIME_LIMIT
137141
break
138142
end
139-
k, u = _select_search_zone(U_N, yI)
143+
k, u = _select_search_zone(U_N, yI, yN)
140144
MOI.set(
141145
model.inner,
142146
MOI.ObjectiveFunction{typeof(scalars[k])}(),

test/algorithms/TambyVanderpooten.jl

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -621,7 +621,44 @@ function test_vector_of_variables_objective()
621621
MOI.set(model, MOI.ObjectiveFunction{typeof(f)}(), f)
622622
MOI.add_constraint(model, sum(1.0 * xi for xi in x), MOI.GreaterThan(1.0))
623623
MOI.optimize!(model)
624-
MOI.get(model, MOI.TerminationStatus()) == MOI.OPTIMAL
624+
@test MOI.get(model, MOI.TerminationStatus()) == MOI.OPTIMAL
625+
return
626+
end
627+
628+
function test_issue_105()
629+
cost = [100.0, 120.0, 150.0, 110.0, 200.0, 170.0]
630+
time = [8.0, 3.0, 4.0, 2.0, 5.0, 4.0]
631+
capacity = [10.0, 8.0]
632+
demand = [5.0, 8.0, 5.0]
633+
m, n = 2, 3
634+
model = MOI.instantiate(; with_bridge_type = Float64) do
635+
return MOA.Optimizer(HiGHS.Optimizer)
636+
end
637+
MOI.set(model, MOA.Algorithm(), MOA.TambyVanderpooten())
638+
MOI.set(model, MOI.Silent(), true)
639+
x = MOI.add_variables(model, m * n)
640+
MOI.add_constraint.(model, x, MOI.GreaterThan(0.0))
641+
MOI.add_constraint.(model, x, MOI.Integer())
642+
X = reshape(x, m, n)
643+
for i in 1:m
644+
f_i = MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.(1.0, X[i, :]), 0.0)
645+
MOI.add_constraint(model, f_i, MOI.LessThan(capacity[i]))
646+
end
647+
for j in 1:n
648+
f_j = MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.(1.0, X[:, j]), 0.0)
649+
MOI.add_constraint(model, f_j, MOI.EqualTo(demand[j]))
650+
end
651+
f = MOI.Utilities.operate(
652+
vcat,
653+
Float64,
654+
MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.(cost, x), 0.0),
655+
MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.(time, x), 0.0),
656+
MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.(1.0, x), 0.0),
657+
)
658+
MOI.set(model, MOI.ObjectiveSense(), MOI.MIN_SENSE)
659+
MOI.set(model, MOI.ObjectiveFunction{typeof(f)}(), f)
660+
MOI.optimize!(model)
661+
@test MOI.get(model, MOI.ResultCount()) == 6
625662
return
626663
end
627664

0 commit comments

Comments
 (0)