Updates population according to crossover and fitness criteria.

def _update_pop(self, pop_size):
        """Updates population according to crossover and fitness criteria."""
        offspring = list(map(self.toolbox.clone, self.population))
        for _ in range(pop_size // 2):
            if random.random() < self.cxpb:
                child1, child2 = self.toolbox.select(self.population, 2, 6)
                temp1 = self.toolbox.clone(child1)
                temp2 = self.toolbox.clone(child2)
                self.toolbox.mate(temp1, temp2)
                del temp1.fitness.values
                del temp2.fitness.values
                offspring.append(temp1)
                offspring.append(temp2)
        for mutant in offspring:
            if random.random() < self.mutpb:
                self.toolbox.mutate(mutant)
                del mutant.fitness.values
        # simple bound checking
        for i in range(len(offspring)):
            for j in range(len(offspring[i])):
                if offspring[i][j] > 1:
                    offspring[i][j] = 1
                if offspring[i][j] < -1:
                    offspring[i][j] = -1
        self._model_count += len(
            [ind for ind in offspring if not ind.fitness.values])
        self.assign_fitnesses(
            [ind for ind in offspring if not ind.fitness.valid])
        offspring.sort(reverse=True, key=lambda x: x.fitness)
        if len(self.halloffame) != 0:
            # elitism- if none beat best so far it is reinserted
            if offspring[0].fitness < self.halloffame[0].fitness:
                offspring.insert(0, self.halloffame[0])
        self.population[:] = offspring[:pop_size]
        return