-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix distance calcuation in NSGA-II #86
Conversation
…pdated test to be more robust to shuffled input
@@ -59,20 +59,24 @@ def fast_non_dominated_sort(candidates: list): | |||
|
|||
def calculate_crowding_distance(front): | |||
""" | |||
Calculate crowding distance of each candidate in front. | |||
Set crowding distance of each candidate in front. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change from creating a list of distances to setting the distances ourselves.
distances[i] += (front[i+1].metrics[m] - front[i-1].metrics[m]) / (obj_max - obj_min) | ||
|
||
return distances | ||
sorted_front = sorted(front, key=lambda candidate: candidate.metrics[m]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No longer sort in-place so we don't mess anything up outside this function
for i in range(1, len(sorted_front) - 1): | ||
if obj_max != obj_min: | ||
dist = sorted_front[i+1].metrics[m] - sorted_front[i-1].metrics[m] | ||
sorted_front[i].distance += dist / (obj_max - obj_min) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Set distance rather than creating distance list so that we ensure we are setting the correct distance to the correct value
crowding_distance = nsga2_utils.calculate_crowding_distance(front) | ||
for candidate, distance in zip(front, crowding_distance): | ||
candidate.distance = distance | ||
nsga2_utils.calculate_crowding_distance(front) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change from manually setting distances outside function to changing them inplace
nsga2_utils.calculate_crowding_distance(shuffled_front) | ||
for candidate, tgt in zip(shuffled_front, shuffled_tgts): | ||
self.assertAlmostEqual(candidate.distance, tgt) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tests a simple example. Makes sure the front is shuffled so that we can see the behavior works in a real scenario
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm
Distance calculation was being done wrong before! Was being done randomly since we weren't sorting the distance list. Copied distance calculation from merging experiment to work properly. We were still getting a good pareto because we had so many candidates and generations, but now we may do better than before or converge much faster.