/** * Prunes the population to the specified size. This is similar to {@link #truncate(int)}, except * the crowding distance is recalculated each time a solution is removed. * * @param size the target population size after pruning */ public void prune(int size) { if (modified) { update(); } sort(new RankComparator()); // collect all solutions in the front which must be pruned // note the use of super to prevent repeatedly triggering update() int maxRank = (Integer) super.get(size - 1).getAttribute(RANK_ATTRIBUTE); Population front = new Population(); for (int i = size() - 1; i >= 0; i--) { Solution solution = super.get(i); int rank = (Integer) solution.getAttribute(RANK_ATTRIBUTE); if (rank >= maxRank) { super.remove(i); if (rank == maxRank) { front.add(solution); } } } // prune front until correct size while (size() + front.size() > size) { nondominatedSorting.updateCrowdingDistance(front); front.truncate(front.size() - 1, new CrowdingComparator()); } addAll(front); }
/** * Updates the rank and crowding distance of all solutions in this population. This method will in * general be called automatically when the population is modified. However, only changes made to * this population can be tracked; changes made directly to the contained solutions will not be * detected. Therefore, it may be necessary to invoke {@link #update()} manually. */ public void update() { modified = false; nondominatedSorting.evaluate(this); }