Genetic Algorithm Premature Convegerence

66 Views Asked by At

Recently, I tried writing a genetic algorithm, but I struggled with premature convergence, and I couldn't overcome (probably) a local optimum. I tried various techniques like performing a global mutation when the algorithm is stuck, increasing the mutation ratio and decreasing the crossover ratio, running multiple populations, and migrating some of the individuals, but without any success. My algorithm was stuck at the same fitness level regardless. I've read about a technique called fitness sharing, in which you lower the fitness of the most common individual so you can promote unique individuals and provide population diversity. Like before, nothing really happened.

here is simplefied Singele Iteration function

    def single_iteration(self):
        new_population = []

        for individual in self.population:
            individual.evaluate(evaluator)

        self.adjust_fitness_for_sharing()

        while len(new_population) < len(self.population):
            fst_parent_index = self.tournament_selection(2)
            snd_parent_index = self.tournament_selection(2)

            children = self.population[fst_parent_index].one_point_crossover(self.population[snd_parent_index], self.crossover_ratio)

            children[0].mutate(self.mutation_ratio, evaluator)
            children[1].mutate(self.mutation_ratio, evaluator)

            new_population.append(children[0])
            new_population.append(children[1])

        self.population = new_population

Here is function for fitness sharing. I use it in tournament selection. The distance is calculated as Hamming distance.

def calculate_sharing_function(self, distance, sigma_share):
        if distance < sigma_share:
            return 1 - math.pow(distance / sigma_share, 0.8)
        else:
            return 0

    def adjust_fitness_for_sharing(self):
        niche_count = [0] * len(self.population)

        for i in range(len(self.population)):
            for j in range(len(self.population)):
                if i != j:
                    distance = self.population[i].calculate_hamming_distance(self.population[j])
                    niche_count[i] += self.calculate_sharing_function(distance, 800)

        for i in range(len(self.population)):
            self.population[i].set_shared_fitness(self.population[i].get_fitness() / niche_count[i])

Could any of you just look over my code and maybe point out some mistakes? I am also open to advice and hints.

0

There are 0 best solutions below