Skip to content

Commit 90b109c

Browse files
committed
Add support for interrupting during the solve loops
1 parent f793c76 commit 90b109c

File tree

9 files changed

+50
-7
lines changed

9 files changed

+50
-7
lines changed

src/MultiObjectiveAlgorithms.jl

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -644,7 +644,24 @@ function optimize_multiobjective!(
644644
return minimize_multiobjective!(algorithm, model)
645645
end
646646

647+
function _check_interrupt()
648+
try
649+
reenable_sigint(() -> nothing)
650+
catch ex
651+
if ex isa InterruptException
652+
return true
653+
end
654+
rethrow(ex)
655+
end
656+
return false
657+
end
658+
647659
function MOI.optimize!(model::Optimizer)
660+
disable_sigint(() -> _optimize!(model))
661+
return
662+
end
663+
664+
function _optimize!(model::Optimizer)
648665
start_time = time()
649666
empty!(model.solutions)
650667
model.termination_status = MOI.OPTIMIZE_NOT_CALLED

src/algorithms/Chalmet.jl

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ function minimize_multiobjective!(algorithm::Chalmet, model::Optimizer)
5757
optimize_inner!(model)
5858
status = MOI.get(model.inner, MOI.TerminationStatus())
5959
if !_is_scalar_status_optimal(status)
60-
return status, nothing
60+
return status, solutions
6161
end
6262
_, y1[2] = _compute_point(model, variables, f2)
6363
MOI.set(model.inner, MOI.ObjectiveFunction{typeof(f1)}(), f1)
@@ -69,7 +69,7 @@ function minimize_multiobjective!(algorithm::Chalmet, model::Optimizer)
6969
optimize_inner!(model)
7070
status = MOI.get(model.inner, MOI.TerminationStatus())
7171
if !_is_scalar_status_optimal(status)
72-
return status, nothing
72+
return status, solutions
7373
end
7474
x1, y1[1] = _compute_point(model, variables, f1)
7575
MOI.delete(model.inner, y1_constraint)
@@ -78,7 +78,7 @@ function minimize_multiobjective!(algorithm::Chalmet, model::Optimizer)
7878
optimize_inner!(model)
7979
status = MOI.get(model.inner, MOI.TerminationStatus())
8080
if !_is_scalar_status_optimal(status)
81-
return status, nothing
81+
return status, solutions
8282
end
8383
_, y2[1] = _compute_point(model, variables, f1)
8484
if y2[1] solutions[1].y[1]
@@ -93,7 +93,7 @@ function minimize_multiobjective!(algorithm::Chalmet, model::Optimizer)
9393
optimize_inner!(model)
9494
status = MOI.get(model.inner, MOI.TerminationStatus())
9595
if !_is_scalar_status_optimal(status)
96-
return status, nothing
96+
return status, solutions
9797
end
9898
x2, y2[2] = _compute_point(model, variables, f2)
9999
MOI.delete(model.inner, y2_constraint)
@@ -103,6 +103,8 @@ function minimize_multiobjective!(algorithm::Chalmet, model::Optimizer)
103103
while !isempty(Q)
104104
if _time_limit_exceeded(model, start_time)
105105
return MOI.TIME_LIMIT, solutions
106+
elseif _check_interrupt()
107+
return MOI.INTERRUPTED, solutions
106108
end
107109
r, s = pop!(Q)
108110
yr, ys = solutions[r].y, solutions[s].y

src/algorithms/Dichotomy.jl

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ function optimize_multiobjective!(algorithm::Dichotomy, model::Optimizer)
7979
if MOI.output_dimension(model.f) == 1
8080
if _time_limit_exceeded(model, start_time)
8181
return MOI.TIME_LIMIT, nothing
82+
elseif _check_interrupt()
83+
return MOI.INTERRUPTED, nothing
8284
end
8385
status, solution = _solve_weighted_sum(model, algorithm, [1.0])
8486
return status, [solution]
@@ -87,6 +89,8 @@ function optimize_multiobjective!(algorithm::Dichotomy, model::Optimizer)
8789
for (i, w) in (1 => 1.0, 2 => 0.0)
8890
if _time_limit_exceeded(model, start_time)
8991
return MOI.TIME_LIMIT, nothing
92+
elseif _check_interrupt()
93+
return MOI.INTERRUPTED, nothing
9094
end
9195
status, solution = _solve_weighted_sum(model, algorithm, [w, 1.0 - w])
9296
if !_is_scalar_status_optimal(status)
@@ -106,14 +110,16 @@ function optimize_multiobjective!(algorithm::Dichotomy, model::Optimizer)
106110
if _time_limit_exceeded(model, start_time)
107111
status = MOI.TIME_LIMIT
108112
break
113+
elseif _check_interrupt()
114+
status = MOI.INTERRUPTED
115+
break
109116
end
110117
(a, b) = popfirst!(queue)
111118
y_d = solutions[a].y .- solutions[b].y
112119
w = y_d[2] / (y_d[2] - y_d[1])
113120
status, solution = _solve_weighted_sum(model, algorithm, [w, 1.0 - w])
114121
if !_is_scalar_status_optimal(status)
115-
# Exit the solve with some error.
116-
return status, nothing
122+
break # Exit the solve with some error.
117123
elseif solution solutions[a] || solution solutions[b]
118124
# We have found an existing solution. We're free to prune (a, b)
119125
# from the search space.

src/algorithms/DominguezRios.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,9 @@ function minimize_multiobjective!(algorithm::DominguezRios, model::Optimizer)
186186
if _time_limit_exceeded(model, start_time)
187187
status = MOI.TIME_LIMIT
188188
break
189+
elseif _check_interrupt()
190+
status = MOI.INTERRUPTED
191+
break
189192
end
190193
i, k = _select_next_box(L, k)
191194
B = L[k][i]

src/algorithms/EpsilonConstraint.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,9 @@ function minimize_multiobjective!(
114114
if _time_limit_exceeded(model, start_time)
115115
status = MOI.TIME_LIMIT
116116
break
117+
elseif _check_interrupt()
118+
status = MOI.INTERRUPTED
119+
break
117120
end
118121
MOI.set(model, MOI.ConstraintSet(), ci, MOI.LessThan{Float64}(bound))
119122
optimize_inner!(model)

src/algorithms/KirlikSayin.jl

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,11 @@ function minimize_multiobjective!(algorithm::KirlikSayin, model::Optimizer)
118118
status = MOI.OPTIMAL
119119
while !isempty(L)
120120
if _time_limit_exceeded(model, start_time)
121-
return MOI.TIME_LIMIT, solutions
121+
status = MOI.TIME_LIMIT
122+
break
123+
elseif _check_interrupt()
124+
status = MOI.INTERRUPTED
125+
break
122126
end
123127
max_volume_index = argmax([_volume(Rᵢ, _project(yI, k)) for Rᵢ in L])
124128
uᵢ = L[max_volume_index].u

src/algorithms/Lexicographic.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,9 @@ function _solve_in_sequence(
127127
if _time_limit_exceeded(model, start_time)
128128
status = MOI.TIME_LIMIT
129129
break
130+
elseif _check_interrupt()
131+
status = MOI.INTERRUPTED
132+
break
130133
end
131134
f = scalars[i]
132135
MOI.set(model.inner, MOI.ObjectiveFunction{typeof(f)}(), f)

src/algorithms/RandomWeighting.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ function optimize_multiobjective!(algorithm::RandomWeighting, model::Optimizer)
6262
while length(solutions) < MOI.get(algorithm, SolutionLimit())
6363
if _time_limit_exceeded(model, start_time)
6464
return MOI.TIME_LIMIT, filter_nondominated(sense, solutions)
65+
elseif _check_interrupt()
66+
return MOI.INTERRUPTED, filter_nondominated(sense, solutions)
6567
end
6668
weights = rand(P)
6769
f = _scalarise(model.f, weights)

src/algorithms/TambyVanderpooten.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,9 @@ function minimize_multiobjective!(
126126
if _time_limit_exceeded(model, start_time)
127127
status = MOI.TIME_LIMIT
128128
break
129+
elseif _check_interrupt()
130+
status = MOI.INTERRUPTED
131+
break
129132
end
130133
k, u = _select_search_zone(U_N, yI, yN)
131134
MOI.set(

0 commit comments

Comments
 (0)