0

I am working shakespeare monkey experiment using genetic algorithm in python . I understood the core concept of this experiment, where an entity randomly types letter, which should finally converege with the selected target text. But when put into code, its not working, Please review the code and correct it if possible. Thank you.

# creating the shakespeare monkey experiement one last time to test my understanging about genetic algorithm

import random

text = 'Andromeda'
population_size = 501
mutation_rate = 0.02


class DNA :

    genes = []
    fitness_val = 0

    def __init__(self,length):
        for i in range(length):
            self.genes.append(chr(random.randint(0,150)))

    def fitness(self,target):
        score = 0
        self.target = target
        self.fitness_val = 0
        for i in range(len(target)):

            if self.genes[i] == self.target[i]:
                score += 1

        self.fitness_val = score / len(self.target)

    def crossover(self,parent):
        child = DNA(0)
        midpoint = random.randint(0, len(text)-1 )
        child[0:midpoint] = self.genes[0:midpoint]
        child[midpoint:] = parent.genes[midpoint:]
        return child

    def mutate(self,mutationRate):
        self.mutationRate = mutationRate
        for i in range(0,len(self.genes)):
            self.child.genes[i] = chr(random.randint(0,150))

    def get_phrase(self):
        return ''.jon(self.genes)

# creation of framework is done, now its the implementatin of this framework


class Population:
    population = []
    matingpool = []

    def __init__(self,target,population_size,mutation_rate):
        self.target = target
        self.mutation_rate = mutation_rate
        self.population_size = population_size
        for i in range(population_size):
            self.population.append(DNA(len(self.target)))
        self.calculateFitness()

    def calculateFitness(self):
        for individual in self.population:
            individual.fitness(self.target)

    def selection(self):
        self.matingpool.clear()
        for individual in self.population:
            n = int(individual.fitness_val * 100)
            for i in range(n):
                self.matingpool.append(i)

    def generation(self):
        # parents = random.choices(self.matingpool,k=2)
        # child = parents[0].crossover(parents[1])
        # child.mutate(mutation_rate)
        # for i in range(len(self.population)):
        #     #s
        #     self.population[i] = child
        for i in range(len(self.population)):
            parents = random.choices(self.matingpool,k = 2)
            #print(parents)
            child = parents[0].crossover(parents[1])
            #print(child)
            child.mutate(mutation_rate)
            self.population[i] = child
        return child

    def select_best(self):
        threshold = 0
        index = 0
        for i in range(len(self.population)):
             if self.population[i].fit > threshold:
                 threshold = self.population[i].fit
                 index = i

pop = Population(text,population_size,mutation_rate)
converged = True

while converged:
    pop.selection()
    pop.generation()
    pop.calculateFitness()

    if pop.get_phrase() == text:
        converged = False

enter image description here This is the result I am getting. It says there is an index error.

James
  • 32,991
  • 4
  • 47
  • 70

1 Answers1

0

In methode def selection() the value n is 0 at first run, because fitness_val is zero

n = int(individual.fitness_val * 100)

that means self.matingpool is not filled and is empty at line 107.

The call of random.choices(self.matingpool,k = 2) with an empty list cause this error.

Marco F.
  • 432
  • 1
  • 10