def generate(self, ind_init): """Generate a population of :math:`\lambda` individuals of type *ind_init* from the current strategy. :param ind_init: A function object that is able to initialize an individual from a list. :returns: A list of individuals with a private attribute :attr:`_ps`. This last attribute is essential to the update function, it indicates that the individual is an offspring and the index of its parent. """ arz = numpy.random.randn(self.lambda_, self.dim) individuals = list() # Make sure every parent has a parent tag and index for i, p in enumerate(self.parents): p._ps = "p", i # Each parent produce an offspring if self.lambda_ == self.mu: for i in range(self.lambda_): # print "Z", list(arz[i]) individuals.append(ind_init(self.parents[i] + self.sigmas[i] * numpy.dot(self.A[i], arz[i]))) individuals[-1]._ps = "o", i # Parents producing an offspring are chosen at random from the first front else: ndom = tools.sortLogNondominated(self.parents, len(self.parents), first_front_only=True) for i in range(self.lambda_): j = numpy.random.randint(0, len(ndom)) _, p_idx = ndom[j]._ps individuals.append(ind_init(self.parents[p_idx] + self.sigmas[p_idx] * numpy.dot(self.A[p_idx], arz[i]))) individuals[-1]._ps = "o", p_idx return individuals
def _select(self, candidates): if len(candidates) <= self.mu: return candidates, [] pareto_fronts = tools.sortLogNondominated(candidates, len(candidates)) chosen = list() mid_front = None not_chosen = list() # Fill the next population (chosen) with the fronts until there is not enouch space # When an entire front does not fit in the space left we rely on the hypervolume # for this front # The remaining fronts are explicitely not chosen full = False for front in pareto_fronts: if len(chosen) + len(front) <= self.mu and not full: chosen += front elif mid_front is None and len(chosen) < self.mu: mid_front = front # With this front, we selected enough individuals full = True else: not_chosen += front # Separate the mid front to accept only k individuals k = self.mu - len(chosen) if k > 0: # reference point is chosen in the complete population # as the worst in each dimension +1 ref = numpy.array([ind.fitness.wvalues for ind in candidates]) * -1 ref = numpy.max(ref, axis=0) + 1 for i in range(len(mid_front) - k): idx = self.indicator(mid_front, ref=ref) not_chosen.append(mid_front.pop(idx)) chosen += mid_front return chosen, not_chosen