Closed gfag31 closed 9 months ago
Hi, thanks for the question.
Yes, this is the expected behavior. This was added back when developing the Borg MOEA, when we wanted detect when an algorithm stagnates and is no longer making significant improvements.
The not_same_box
condition essentially says that the new solution must differ by more than some threshold $\epsilon$ from the solution it's dominating. If your $\epsilon$ is small enough, it could certainly evaluate to true
most of the time.
More details can be found in Section 3.2 $\epsilon$-progress in http://www.mitpressjournals.org/doi/abs/10.1162/EVCO_a_00075
You can also see this test code that shows the expected behavior - https://github.com/Project-Platypus/Platypus/blob/1a0e8cb9ea469e7e07a90c3d3974cea9fbed8336/platypus/tests/test_core.py#L280-L293
The six solutions only register two improvements given $\epsilon$ = 0.1.
(0.25, 0.25)
increments by 1, as it's the first solution added to the archive(0.1, 0.1)
dominates (0.25, 0.25
) and greater than $\epsilon$ - improvements increased by 1(0.245, 0.245)
is dominated by (0.1, 0.1)
, no change(0.1, 0.5)
is non-dominated, no change(0.5, 0.5)
is dominated by (0.1, 0.1)
, no change(0.0, 0.0)
dominates (0.1, 0.1)
but is <= $\epsilon$, no changeThanks for leaving the topic open and giving me a chance to reply. Sorry to insist, but if I do that simple test code (below), I don't get the same behavior as you describe :
from platypus import *
def createSolution(*args):
problem = Problem(0, len(args))
solution = Solution(problem)
solution.objectives[:] = [float(x) for x in args]
return solution
solutions = [createSolution(0.25, 0.25), #s1
createSolution(0.1, 0.1), #s2
createSolution(0.245, 0.245), #s3
createSolution(0.1, 0.5), #s4
createSolution(0.5, 0.5), #s5
createSolution(0.05, 0.05), #s6
createSolution(0.04, 0.04), #s7
createSolution(0.03, 0.03), #s8
createSolution(0.02, 0.02), #s9
]
archive = EpsilonBoxArchive([0.1])
print(archive.improvements)
for s in solutions:
res = archive.add(s)
print(res, archive.improvements)
And I get:
0
None 0
None 1
False 1
False 1
False 1
None 2
None 3
None 4
None 5
As you can see, s6 to s9 are within epsilon, but are still seen as improvements. IMHO this is because in the line I pointed out, the boolean evaluation of an array is always True if not empty.
In my example I also included the returned value of the archive.add method. Just to point out that its evaluation will be always False => This is for borg.py line 95 (angel)
Please let me know again what are your view and thanks again.
Ah! I see what you mean. Working on a fix...
I pushed another update to change the logic a bit...
This matches how this calculation works in my other library, the MOEA Framework, in the EpsilonBoxDominanceArchive.
If there are any concerns with this change, please let me know! Also thank you for responding with an example showing the code was producing unexpected results!
Thank you for the fix. I agree that it makes sense that way. Great update !
In the EpsilonBoxArchive class, the "improvements" attributes is (almost) always increamented :
/platypus/core.py line 990:
As long as the Archive is not empty, that the added solution is not dominated, the improvement will be increased. Is it the expected behavior ?