|
20 | 20 | Base.:(==)(a::SolutionPoint, b::SolutionPoint) = a.y == b.y
|
21 | 21 |
|
22 | 22 | """
|
23 |
| - dominates(sense, a::SolutionPoint, b::SolutionPoint) |
| 23 | + dominates(sense, a::SolutionPoint, b::SolutionPoint; atol::Float64) |
24 | 24 |
|
25 | 25 | Returns `true` if point `a` dominates point `b`.
|
26 | 26 | """
|
27 |
| -function dominates(sense, a::SolutionPoint, b::SolutionPoint) |
28 |
| - if a.y == b.y |
29 |
| - return false |
30 |
| - elseif sense == MOI.MIN_SENSE |
31 |
| - return all(a.y .<= b.y) |
| 27 | +function dominates( |
| 28 | + sense::MOI.OptimizationSense, |
| 29 | + a::SolutionPoint, |
| 30 | + b::SolutionPoint; |
| 31 | + atol::Float64 = 1e-6, |
| 32 | +) |
| 33 | + l, u = extrema(a.y - b.y) |
| 34 | + if sense == MOI.MIN_SENSE |
| 35 | + # At least one element must be strictly better => l < -atol |
| 36 | + # No element can be structly worse => u <= atol |
| 37 | + return l < -atol && u <= atol |
32 | 38 | else
|
33 |
| - return all(a.y .>= b.y) |
| 39 | + # At least one element must be strictly better => u > atol |
| 40 | + # No element can be structly worse => l >= -atol |
| 41 | + return u > atol && l >= -atol |
34 | 42 | end
|
35 | 43 | end
|
36 | 44 |
|
37 | 45 | _sort!(solutions::Vector{SolutionPoint}) = sort!(solutions; by = x -> x.y)
|
38 | 46 |
|
39 |
| -function filter_nondominated(sense, solutions::Vector{SolutionPoint}) |
| 47 | +function filter_nondominated( |
| 48 | + sense, |
| 49 | + solutions::Vector{SolutionPoint}; |
| 50 | + atol::Float64 = 1e-6, |
| 51 | +) |
40 | 52 | _sort!(solutions)
|
41 | 53 | nondominated_solutions = SolutionPoint[]
|
42 | 54 | for candidate in solutions
|
43 |
| - if any(test -> dominates(sense, test, candidate), solutions) |
| 55 | + if any(test -> dominates(sense, test, candidate; atol), solutions) |
44 | 56 | # Point is dominated. Don't add
|
45 |
| - elseif any(test -> test.y ≈ candidate.y, nondominated_solutions) |
| 57 | + elseif any(test -> ≈(test.y, candidate.y; atol), nondominated_solutions) |
46 | 58 | # Point already added to nondominated solutions. Don't add
|
47 | 59 | else
|
48 | 60 | push!(nondominated_solutions, candidate)
|
|
0 commit comments