Skip to content

[GeneralDichotomy] handle no solution case#207

Open
smbct wants to merge 4 commits into
jump-dev:masterfrom
smbct:general_dichotomy_203
Open

[GeneralDichotomy] handle no solution case#207
smbct wants to merge 4 commits into
jump-dev:masterfrom
smbct:general_dichotomy_203

Conversation

@smbct

@smbct smbct commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

In reply to #203:

I replaced the initial scalarization by w=(1, .., 1). The missing solution case can be detected at the beginning by solving a simple sum of the objectives:

  • if one of the objective is unbounded, any sum with non zero coefficients should be also unbounded
  • if the problem is infeasible, any linear scalarization should be infeasible as well

Then, if any sub-problem is infeasible, this must be due to numerical issues, hence returning MOI.NUMERICAL_ERROR in the main loop.

(PS sorry for the duplicate PR)

@smbct smbct changed the title handle no solution case [GeneralDichotomy] handle no solution case Jul 1, 2026
@codecov

codecov Bot commented Jul 1, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 90.47619% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 99.51%. Comparing base (b71397a) to head (8990d1f).

Files with missing lines Patch % Lines
ext/Polyhedra/GeneralDichotomy.jl 90.47% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #207      +/-   ##
==========================================
- Coverage   99.64%   99.51%   -0.14%     
==========================================
  Files          15       15              
  Lines        1421     1434      +13     
==========================================
+ Hits         1416     1427      +11     
- Misses          5        7       +2     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@odow

odow commented Jul 1, 2026

Copy link
Copy Markdown
Member

if one of the objective is unbounded, any sum with non zero coefficients should be also unbounded

counter example: min [x, -x] with x free. The (0.5, 0.5) vector has a bounded objective.

Comment thread ext/Polyhedra/GeneralDichotomy.jl Outdated
w = zeros(Float64, n_obj)
w[1] = 1.0
# First, minimize the combined objectives to obtain a primal feasible point.
w = ones(Float64, n_obj)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
w = ones(Float64, n_obj)
w = fill(1 / n_obj, n_obj)

Does it matter?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At this stage, this weight is not kept to be part of the "decomposition", so its range does not matter here. (1,..,1) is unlikely to ba an "extreme weight" since extreme weights verify w dot y^1 = w dot y^2 = ... (usually there is equality for d solutions if there are d objectives). This is really the same as the dichotomy method.

In the main loop, all extreme weights are obtained from the Polyhedron vertices enumerations, so they verify both the range and the equality. (and initial weights e.g. (1,0,..,0) verify this as well when there is one recorded solution)

@odow

odow commented Jul 2, 2026

Copy link
Copy Markdown
Member

I think we need to first check the ideal point, and then go for it. I'd also suggest that if we run into issues we just prune the weight and keep exploring other weights. There might be more solutions that we can find, even if one solve fails.

@odow

odow commented Jul 2, 2026

Copy link
Copy Markdown
Member

This is what we do in KS:

if !_is_scalar_status_optimal(model)
_log_subproblem_solve(model, "subproblem not optimal")
# If this fails, it likely means that the solver experienced a
# numerical error with this box. Just skip it.
MOI.delete.(model, ε_constraints)
MOI.delete(model, zₖ_constraint)
_remove_rectangle(L, _Rectangle(_project(yI, k), uᵢ))
continue

@smbct

smbct commented Jul 2, 2026

Copy link
Copy Markdown
Contributor Author

counter example: min [x, -x] with x free. The (0.5, 0.5) vector has a bounded objective.

Correct. I had not considered cancelling objectives.

I think we need to first check the ideal point, and then go for it.

Alright, I will then make changes to process all initial weights before starting the main loop.

This is what we do in KS:

In the dichotomy, it is fine to process a solution (to compute weights) even if it is not optimal. The search is stopped if the weighted sum comparison fails but there should be no issue in the weight update. We can hence simply add the log message.

if solution !== nothing
if !MOA._is_scalar_status_optimal(model)
_log_subproblem_solve(model, "subproblem not optimal")
end

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the place to put this logging is in

status = MOI.get(model.inner, MOI.TerminationStatus())
if !_is_scalar_status_optimal(status)
return status, nothing
end

Comment thread ext/Polyhedra/GeneralDichotomy.jl Outdated
Comment thread ext/Polyhedra/GeneralDichotomy.jl Outdated
end
if !MOA._is_scalar_status_optimal(model)
_log_subproblem_solve(model, "subproblem not optimal")
end

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this logging in favor of one in _solve_weighted_sum

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants