Skip to content

Commit 79e4402

Browse files
committed
Update
1 parent 9dc9ed7 commit 79e4402

3 files changed

Lines changed: 20 additions & 24 deletions

File tree

ext/Polyhedra/GeneralDichotomy.jl

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -24,37 +24,30 @@ function MOA.minimize_multiobjective!(
2424
# Storage we need for the algorithm.
2525
weights, solutions = Weight[], MOA.SolutionPoint[]
2626
n_obj = MOI.output_dimension(model.f)
27+
existing_sol = Dict{Vector{Int},Int}()
2728
# First, search for an initial primal feasible point.
28-
init_sol_idx = 0
29-
status, solution = nothing, nothing
3029
for i in 1:n_obj
3130
w = zeros(Float64, n_obj)
3231
w[i] = 1.0
3332
status, solution = MOA._solve_weighted_sum(model, alg, w)
34-
if solution !== nothing
35-
init_sol_idx = i
36-
push!(solutions, solution)
37-
break
33+
if solution === nothing
34+
# One of the subproblems failed to solve. This means something went
35+
# really wrong. A common reason is that the problem is unbounded.
36+
return status, nothing
3837
end
38+
push!(solutions, solution)
39+
model.ideal_point[i] = solution.y[i]
3940
end
40-
if length(solutions) == 0
41-
return status, nothing
42-
end
43-
# Initialize the weights. There is one weight vector for each objective, and
44-
# the weight is set to 1.0 for each objective. We use the current solution
45-
# obtained by minimizing the 1st objective as the reference.
41+
solution = solutions[1]
42+
existing_sol[_round(solution.y; atol)] = 1
4643
for i in 1:n_obj
4744
w = zeros(Float64, n_obj)
4845
w[i] = 1.0
4946
z = w' * solution.y
5047
adj_bnd = Int[-j for j in 1:n_obj if j != i]
51-
tested = i <= init_sol_idx
52-
removed = i < init_sol_idx
53-
push!(weights, Weight(w, z, adj_bnd, [1], tested, removed))
48+
push!(weights, Weight(w, z, adj_bnd, [1], i == 1, false))
5449
end
55-
# Prevent solution duplicates: existing_sol maps an rounded objective vector
56-
# to its index in `solutions::Vector{MOA.SolutionPoint}`.
57-
existing_sol = Dict(_round(solution.y; atol) => 1)
50+
status = MOI.OPTIMAL
5851
n_removed = 0
5952
while length(solutions) < MOI.get(alg, MOA.SolutionLimit())
6053
if (ret = MOA._check_premature_termination(model)) !== nothing

src/algorithms/GeneralDichotomy.jl

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,18 +59,21 @@ function _solve_weighted_sum(
5959
f = _scalarise(model.f, weight)
6060
MOI.set(model.inner, MOI.ObjectiveFunction{typeof(f)}(), f)
6161
optimize_inner!(model)
62+
term_status = MOI.get(model.inner, MOI.TerminationStatus())
6263
primal_status = MOI.get(model.inner, MOI.PrimalStatus())
6364
if !_is_scalar_status_feasible_point(primal_status)
6465
_log_subproblem_solve(model, "subproblem failed to solve")
65-
return status, nothing
66+
return term_status, nothing
67+
elseif term_status == MOI.DUAL_INFEASIBLE
68+
_log_subproblem_solve(model, "subproblem is unbounded")
69+
return term_status, nothing
6670
end
67-
status = MOI.get(model.inner, MOI.TerminationStatus())
6871
variables = MOI.get(model.inner, MOI.ListOfVariableIndices())
6972
X, Y = _compute_point(model, variables, model.f)
70-
if !_is_scalar_status_optimal(status)
73+
if !_is_scalar_status_optimal(term_status)
7174
_log_subproblem_solve(model, "subproblem not optimal")
7275
else
7376
_log_subproblem_solve(model, Y)
7477
end
75-
return status, SolutionPoint(X, Y)
78+
return term_status, SolutionPoint(X, Y)
7679
end

test/algorithms/test_GeneralDichotomy.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -456,7 +456,7 @@ function test_quadratic()
456456
MOI.set(model, MOI.ObjectiveSense(), MOI.MIN_SENSE)
457457
MOI.set(model, MOI.ObjectiveFunction{typeof(f)}(), f)
458458
MOI.optimize!(model)
459-
@test MOI.get(model, MOI.ResultCount()) == 10
459+
@test 9 <= MOI.get(model, MOI.ResultCount()) <= 10
460460
for i in 1:MOI.get(model, MOI.ResultCount())
461461
w_sol = MOI.get(model, MOI.VariablePrimal(i), w)
462462
y = MOI.get(model, MOI.ObjectiveValue(i))
@@ -507,7 +507,7 @@ function test_solve_failures()
507507
end
508508
MOI.optimize!(model)
509509
@test MOI.get(model, MOI.TerminationStatus()) == MOI.NUMERICAL_ERROR
510-
fails = [0, 1, 2, 3]
510+
fails = [0, 0, 2, 2]
511511
@test MOI.get(model, MOI.ResultCount()) == fails[fail_after+1]
512512
end
513513
return

0 commit comments

Comments
 (0)