Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 21 additions & 10 deletions ext/Polyhedra/GeneralDichotomy.jl
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,22 @@ function MOA.minimize_multiobjective!(
# Storage we need for the algorithm.
weights, solutions = Weight[], MOA.SolutionPoint[]
n_obj = MOI.output_dimension(model.f)
# First, minimize the first objective to obtain a primal feasible point.
w = zeros(Float64, n_obj)
w[1] = 1.0
status, solution = MOA._solve_weighted_sum(model, alg, w)
if solution === nothing
# First, search for an initial primal feasible point.
init_sol_idx = 0
status, solution = nothing, nothing
for i in 1:n_obj
w = zeros(Float64, n_obj)
w[i] = 1.0
status, solution = MOA._solve_weighted_sum(model, alg, w)
if solution !== nothing
init_sol_idx = i
push!(solutions, solution)
break
end
end
if length(solutions) == 0
return status, nothing
end
push!(solutions, solution)
# Initialize the weights. There is one weight vector for each objective, and
# the weight is set to 1.0 for each objective. We use the current solution
# obtained by minimizing the 1st objective as the reference.
Expand All @@ -40,7 +48,9 @@ function MOA.minimize_multiobjective!(
w[i] = 1.0
z = w' * solution.y
adj_bnd = Int[-j for j in 1:n_obj if j != i]
push!(weights, Weight(w, z, adj_bnd, [1], i == 1, false))
tested = i <= init_sol_idx
removed = i < init_sol_idx
push!(weights, Weight(w, z, adj_bnd, [1], tested, removed))
end
# Prevent solution duplicates: existing_sol maps an rounded objective vector
# to its index in `solutions::Vector{MOA.SolutionPoint}`.
Expand All @@ -58,11 +68,12 @@ function MOA.minimize_multiobjective!(
continue
end
status, sol = MOA._solve_weighted_sum(model, alg, weight.w)
weight.tested = true
# The weight is skipped if there is no solution. The algortihm can
# continue in case of sub-optimality.
if sol === nothing
# TODO(odow): what to do when this solve fails?
return status, solutions
continue
end
weight.tested = true
if !haskey(existing_sol, _round(sol.y; atol))
push!(solutions, sol)
# Prepare new weight index set for the new solution's adjacency.
Expand Down
1 change: 1 addition & 0 deletions src/algorithms/GeneralDichotomy.jl
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ function _solve_weighted_sum(
optimize_inner!(model)
status = MOI.get(model.inner, MOI.TerminationStatus())
if !_is_scalar_status_optimal(status)
_log_subproblem_solve(model, "subproblem not optimal")
return status, nothing
end
variables = MOI.get(model.inner, MOI.ListOfVariableIndices())
Expand Down
Loading