Skip to content

Commit ec09399

Browse files
committed
Update
1 parent 610d7a6 commit ec09399

File tree

12 files changed

+135
-111
lines changed

12 files changed

+135
-111
lines changed

src/MultiObjectiveAlgorithms.jl

Lines changed: 78 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -667,53 +667,6 @@ function optimize_inner!(model::Optimizer)
667667
return
668668
end
669669

670-
"""
671-
_log_solution(model::Optimizer, variables::Vector{MOI.VariableIndex})
672-
673-
Log the solution. We don't have a pre-computed point, so compute one from the
674-
variable values.
675-
"""
676-
function _log_solution(model::Optimizer, variables::Vector{MOI.VariableIndex})
677-
if !model.silent
678-
_, Y = _compute_point(model, variables, model.f)
679-
_log_solution(model, Y)
680-
end
681-
return
682-
end
683-
684-
"""
685-
_log_solution(model::Optimizer, variables::Vector{MOI.VariableIndex})
686-
687-
Log the solution. We have a pre-computed point.
688-
"""
689-
function _log_solution(model::Optimizer, Y)
690-
if !model.silent
691-
print(_format(model.subproblem_count), " ")
692-
for y in Y
693-
print(" ", _format(y))
694-
end
695-
println(" ", _format(time() - model.start_time))
696-
end
697-
return
698-
end
699-
"""
700-
_log_solution(model::Optimizer, msg::String)
701-
702-
Log the solution. Assume the subproblem failed to solve.
703-
"""
704-
function _log_solution(model::Optimizer, msg::String)
705-
if !model.silent
706-
print(_format(model.subproblem_count), " ")
707-
print(rpad(msg, 13 * MOI.output_dimension(model.f)))
708-
println(" ", _format(time() - model.start_time))
709-
end
710-
return
711-
end
712-
713-
_format(x::Int) = Printf.@sprintf("%5d", x)
714-
_format(x::Float64) = Printf.@sprintf("% .5e", x)
715-
_format(::Nothing) = " "
716-
717670
function _compute_ideal_point(model::Optimizer)
718671
for (i, f) in enumerate(MOI.Utilities.eachscalar(model.f))
719672
if _check_premature_termination(model) !== nothing
@@ -822,6 +775,82 @@ function MOI.optimize!(model::Optimizer)
822775
return
823776
end
824777

778+
function _print_header(io::IO, model::Optimizer)
779+
rule = "-"^(7 + 13 * (MOI.output_dimension(model.f) + 1))
780+
println(io, rule)
781+
println(io, " MultiObjectiveAlgorithms.jl")
782+
println(io, rule)
783+
println(
784+
io,
785+
"Algorithm: ",
786+
replace(
787+
string(typeof(model.algorithm)),
788+
"MultiObjectiveAlgorithms." => "",
789+
),
790+
)
791+
println(io, rule)
792+
print(io, "solve #")
793+
for i in 1:MOI.output_dimension(model.f)
794+
print(io, lpad("Obj. $i ", 13))
795+
end
796+
println(io, " Time ")
797+
println(io, rule)
798+
return
799+
end
800+
801+
function _print_footer(io::IO, model::Optimizer)
802+
rule = "-"^(7 + 13 * (MOI.output_dimension(model.f) + 1))
803+
println(io, rule)
804+
println(io, "TerminationStatus: ", model.termination_status)
805+
println(io, "ResultCount: ", length(model.solutions))
806+
println(io, rule)
807+
return
808+
end
809+
810+
"""
811+
_log_subproblem_solve(model::Optimizer, variables::Vector{MOI.VariableIndex})
812+
813+
Log the solution. We don't have a pre-computed point, so compute one from the
814+
variable values.
815+
"""
816+
function _log_subproblem_solve(model::Optimizer, arg)
817+
if !model.silent
818+
_log_subproblem_inner(model, arg)
819+
end
820+
return
821+
end
822+
823+
# Variables; compute the associated Y
824+
function _log_subproblem_inner(model::Optimizer, x::Vector{MOI.VariableIndex})
825+
_, Y = _compute_point(model, x, model.f)
826+
_log_subproblem_solve(model, Y)
827+
return
828+
end
829+
830+
# We have a pre-computed point.
831+
function _log_subproblem_inner(model::Optimizer, Y::Vector)
832+
print(_format(model.subproblem_count), " ")
833+
for y in Y
834+
print(" ", _format(y))
835+
end
836+
println(" ", _format(time() - model.start_time))
837+
return
838+
end
839+
840+
# Assume the subproblem failed to solve.
841+
function _log_subproblem_inner(model::Optimizer, msg::String)
842+
print(_format(model.subproblem_count), " ")
843+
print(rpad(msg, 13 * MOI.output_dimension(model.f)))
844+
println(" ", _format(time() - model.start_time))
845+
return
846+
end
847+
848+
_format(x::Int) = Printf.@sprintf("%5d", x)
849+
850+
_format(x::Float64) = Printf.@sprintf("% .5e", x)
851+
852+
_format(::Nothing) = " "
853+
825854
function _optimize!(model::Optimizer)
826855
model.start_time = time()
827856
empty!(model.solutions)
@@ -833,18 +862,7 @@ function _optimize!(model::Optimizer)
833862
return
834863
end
835864
if !model.silent
836-
rule = "-"^(7 + 13 * (MOI.output_dimension(model.f) + 1))
837-
println(rule)
838-
println(" MultiObjectiveAlgorithms.jl")
839-
println(rule)
840-
println("Algorithm: ", _describe(model.algorithm))
841-
println(rule)
842-
print("solve #")
843-
for i in 1:MOI.output_dimension(model.f)
844-
print(lpad("Obj. $i ", 13))
845-
end
846-
println(" Time ")
847-
println(rule)
865+
_print_header(stdout, model)
848866
end
849867
# We need to clear the ideal point prior to starting the solve. Algorithms
850868
# may update this during the solve, otherwise we will update it at the end.
@@ -857,10 +875,7 @@ function _optimize!(model::Optimizer)
857875
_sort!(model.solutions, MOI.get(model, MOI.ObjectiveSense()))
858876
end
859877
if !model.silent
860-
println(rule)
861-
println("Terminating with status: ", status)
862-
println("Number of non-dominated solutions: ", length(model.solutions))
863-
println(rule)
878+
_print_footer(stdout, model)
864879
end
865880
if MOI.get(model, ComputeIdealPoint())
866881
_compute_ideal_point(model)

src/algorithms/Chalmet.jl

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,6 @@ This algorithm is restricted to problems with:
2525
"""
2626
struct Chalmet <: AbstractAlgorithm end
2727

28-
_describe(::Chalmet) = "Chalmet()"
29-
3028
function _solve_constrained_model(
3129
model::Optimizer,
3230
::Chalmet,
@@ -40,13 +38,13 @@ function _solve_constrained_model(
4038
optimize_inner!(model)
4139
status = MOI.get(model.inner, MOI.TerminationStatus())
4240
if !_is_scalar_status_optimal(status)
43-
_log_solution(model, "subproblem not optimal")
41+
_log_subproblem_solve(model, "subproblem not optimal")
4442
MOI.delete.(model, c)
4543
return status, nothing
4644
end
4745
variables = MOI.get(model.inner, MOI.ListOfVariableIndices())
4846
X, Y = _compute_point(model, variables, model.f)
49-
_log_solution(model, Y)
47+
_log_subproblem_solve(model, Y)
5048
MOI.delete.(model, c)
5149
return status, SolutionPoint(X, Y)
5250
end
@@ -69,7 +67,7 @@ function minimize_multiobjective!(algorithm::Chalmet, model::Optimizer)
6967
return status, solutions
7068
end
7169
_, y1[2] = _compute_point(model, variables, f2)
72-
_log_solution(model, variables)
70+
_log_subproblem_solve(model, variables)
7371
MOI.set(model.inner, MOI.ObjectiveFunction{typeof(f1)}(), f1)
7472
y1_constraint = MOI.Utilities.normalize_and_add_constraint(
7573
model.inner,
@@ -82,7 +80,7 @@ function minimize_multiobjective!(algorithm::Chalmet, model::Optimizer)
8280
return status, solutions
8381
end
8482
x1, y1[1] = _compute_point(model, variables, f1)
85-
_log_solution(model, y1)
83+
_log_subproblem_solve(model, y1)
8684
MOI.delete(model.inner, y1_constraint)
8785
push!(solutions, SolutionPoint(x1, y1))
8886
MOI.set(model.inner, MOI.ObjectiveFunction{typeof(f1)}(), f1)
@@ -92,7 +90,7 @@ function minimize_multiobjective!(algorithm::Chalmet, model::Optimizer)
9290
return status, solutions
9391
end
9492
_, y2[1] = _compute_point(model, variables, f1)
95-
_log_solution(model, variables)
93+
_log_subproblem_solve(model, variables)
9694
if y2[1] solutions[1].y[1]
9795
return MOI.OPTIMAL, solutions
9896
end
@@ -108,7 +106,7 @@ function minimize_multiobjective!(algorithm::Chalmet, model::Optimizer)
108106
return status, solutions
109107
end
110108
x2, y2[2] = _compute_point(model, variables, f2)
111-
_log_solution(model, y2)
109+
_log_subproblem_solve(model, y2)
112110
MOI.delete(model.inner, y2_constraint)
113111
push!(solutions, SolutionPoint(x2, y2))
114112
push!(Q, (1, 2))

src/algorithms/Dichotomy.jl

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,6 @@ mutable struct Dichotomy <: AbstractAlgorithm
3030
Dichotomy() = new(nothing)
3131
end
3232

33-
_describe(::Dichotomy) = "Dichotomy()"
34-
3533
"""
3634
NISE()
3735
@@ -76,7 +74,7 @@ function _solve_weighted_sum(
7674
end
7775
variables = MOI.get(model.inner, MOI.ListOfVariableIndices())
7876
X, Y = _compute_point(model, variables, model.f)
79-
_log_solution(model, Y)
77+
_log_subproblem_solve(model, Y)
8078
return status, SolutionPoint(X, Y)
8179
end
8280

src/algorithms/DominguezRios.jl

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,6 @@ This algorithm is restricted to problems with:
2626
"""
2727
struct DominguezRios <: AbstractAlgorithm end
2828

29-
_describe(::DominguezRios) = "DominguezRios()"
30-
3129
mutable struct _DominguezRiosBox
3230
l::Vector{Float64}
3331
u::Vector{Float64}
@@ -66,8 +64,8 @@ function _p_partition(
6664
= max.(z, B.l)
6765
ret = _DominguezRiosBox[]
6866
for i in 1:length(z)
69-
new_l = vcat(B.l[1:i], ẑ[i+1:end])
70-
new_u = vcat(B.u[1:i-1], ẑ[i], B.u[i+1:end])
67+
new_l = vcat(B.l[1:i], ẑ[(i+1):end])
68+
new_u = vcat(B.u[1:(i-1)], ẑ[i], B.u[(i+1):end])
7169
new_priority = _reduced_scaled_priority(new_l, new_u, i, ẑ, yI, yN)
7270
push!(ret, _DominguezRiosBox(new_l, new_u, new_priority))
7371
end
@@ -167,7 +165,7 @@ function minimize_multiobjective!(algorithm::DominguezRios, model::Optimizer)
167165
return status, nothing
168166
end
169167
_, Y = _compute_point(model, variables, f_i)
170-
_log_solution(model, variables)
168+
_log_subproblem_solve(model, variables)
171169
yI[i] = Y
172170
model.ideal_point[i] = Y
173171
MOI.set(model.inner, MOI.ObjectiveSense(), MOI.MAX_SENSE)
@@ -178,7 +176,7 @@ function minimize_multiobjective!(algorithm::DominguezRios, model::Optimizer)
178176
return status, nothing
179177
end
180178
_, Y = _compute_point(model, variables, f_i)
181-
_log_solution(model, variables)
179+
_log_subproblem_solve(model, variables)
182180
yN[i] = Y + 1
183181
end
184182
MOI.set(model.inner, MOI.ObjectiveSense(), MOI.MIN_SENSE)
@@ -219,7 +217,7 @@ function minimize_multiobjective!(algorithm::DominguezRios, model::Optimizer)
219217
optimize_inner!(model)
220218
if _is_scalar_status_optimal(model)
221219
X, Y = _compute_point(model, variables, model.f)
222-
_log_solution(model, Y)
220+
_log_subproblem_solve(model, Y)
223221
obj = MOI.get(model.inner, MOI.ObjectiveValue())
224222
# We need to undo the scaling of the scalar objective. There's no
225223
# need to unscale `Y` because we have evaluated this explicitly from
@@ -237,7 +235,7 @@ function minimize_multiobjective!(algorithm::DominguezRios, model::Optimizer)
237235
# fail and return something like OTHER_ERROR (e.g., because the
238236
# numerics are challenging). Rather than error completely, let's
239237
# just skip this box.
240-
_log_solution(model, "subproblem not optimal")
238+
_log_subproblem_solve(model, "subproblem not optimal")
241239
deleteat!(L[k], i)
242240
end
243241
MOI.delete.(model.inner, constraints)

src/algorithms/EpsilonConstraint.jl

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,6 @@ mutable struct EpsilonConstraint <: AbstractAlgorithm
3636
EpsilonConstraint() = new(nothing, nothing)
3737
end
3838

39-
_describe(::EpsilonConstraint) = "EpsilonConstraint()"
40-
4139
MOI.supports(::EpsilonConstraint, ::SolutionLimit) = true
4240

4341
function MOI.set(alg::EpsilonConstraint, ::SolutionLimit, value)
@@ -128,7 +126,7 @@ function minimize_multiobjective!(
128126
break
129127
end
130128
X, Y = _compute_point(model, variables, model.f)
131-
_log_solution(model, Y)
129+
_log_subproblem_solve(model, Y)
132130
if isempty(solutions) || !(Y solutions[end].y)
133131
push!(solutions, SolutionPoint(X, Y))
134132
end

src/algorithms/Hierarchical.jl

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,6 @@ mutable struct Hierarchical <: AbstractAlgorithm
3737
Hierarchical() = new(Int[], Float64[], Float64[])
3838
end
3939

40-
_describe(::Hierarchical) = "Hierarchical()"
41-
4240
MOI.supports(::Hierarchical, ::ObjectivePriority) = true
4341

4442
function MOI.get(alg::Hierarchical, attr::ObjectivePriority)
@@ -116,7 +114,7 @@ function minimize_multiobjective!(algorithm::Hierarchical, model::Optimizer)
116114
end
117115
if !model.silent
118116
X, Y = _compute_point(model, variables, model.f)
119-
_log_solution(model, Y)
117+
_log_subproblem_solve(model, Y)
120118
end
121119
# Add tolerance constraints
122120
X, Y = _compute_point(model, variables, new_vector_f)
@@ -128,7 +126,7 @@ function minimize_multiobjective!(algorithm::Hierarchical, model::Optimizer)
128126
end
129127
end
130128
X, Y = _compute_point(model, variables, model.f)
131-
_log_solution(model, Y)
129+
_log_subproblem_solve(model, Y)
132130
# Remove tolerance constraints
133131
for c in constraints
134132
MOI.delete(model, c)

0 commit comments

Comments
 (0)