Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- from random import randint, uniform
- from copy import deepcopy
- GENES = 'LRUD'
- LENGTH = 20
- DIRECTIONS = {'L': (-1, 0), 'R': (1, 0), 'U':(0, 1), 'D':(0, -1)}
- GENERATION_SIZE = 100
- FIELD_SIZE = 10
- ITERATIONS = 1000
- def generate():
- """ Returns a new random sequence. """
- sequence = ''
- for _ in range(LENGTH):
- sequence += GENES[randint(0, 3)]
- return sequence
- def crossover(a, b):
- """ Does crossover between two sequences and returns a new one. """
- sequence = a[:LENGTH//2] + b[LENGTH//2:]
- return sequence
- def mutation(sequence):
- """ Mutates a sequence. """
- i = randint(0, LENGTH-1)
- sequence = list(sequence)
- sequence[i] = GENES[randint(0, 3)]
- return ''.join(sequence)
- def evaluate(field, sequence):
- """ Returns the number of flowers the rabbit picks up. """
- f = deepcopy(field)
- flowers = 0
- x = y = FIELD_SIZE // 2
- flowers += f[x][y]
- f[x][y] = 0
- for s in sequence:
- x += DIRECTIONS[s][0]
- y += DIRECTIONS[s][1]
- if x not in range(FIELD_SIZE) or y not in range(FIELD_SIZE):
- # rabbit went out of the field
- continue
- flowers += f[x][y]
- f[x][y] = 0
- return flowers
- def selection(sequences, weights):
- """ Returns a randomly selected sequence from weighted distribution. """
- total = sum(weights)
- r = uniform(0, total)
- upto = 0
- for s, w in zip(sequences, weights):
- if upto + w >= r:
- return s
- upto += w
- # random generated field
- field = [[randint(0, 5) for _ in range(FIELD_SIZE)] for _ in range(FIELD_SIZE)]
- # generate random rabbits
- population = [generate() for _ in range(GENERATION_SIZE)]
- # go through iterations
- for generation in range(ITERATIONS):
- # evaluate generation
- evaluations = [evaluate(field, rabbit) for rabbit in population]
- # sort generation
- combined = list(zip(evaluations, population))
- combined.sort(key=lambda e: e[0], reverse=True)
- evaluations, population = zip(*combined)
- evaluations = list(evaluations)
- population = list(population)
- # print best rabbit
- print('generation:{:3d}\t rabbit: {}\t flowers:{:3d}'.format(
- generation,
- population[0],
- evaluate(field, population[0])))
- # now the population is sorted by flowers descending
- new_generation = []
- # now we pick two rabbits from the first half of population
- # and we make them have sex
- for _ in range(GENERATION_SIZE):
- weights = [e**2 for e in evaluations]
- dad = selection(population, weights)
- mom = selection(population, weights)
- child = crossover(dad, mom)
- # 50% that child is a mutant
- if randint(0, 1):
- child = mutation(child)
- new_generation.append(child)
- population = new_generation
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement