Advertisement
lencH

genetic rabbits

Mar 8th, 2017
48
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.96 KB | None | 0 0
  1. from random import randint, uniform
  2. from copy import deepcopy
  3.  
  4. GENES = 'LRUD'
  5. LENGTH = 20
  6. DIRECTIONS = {'L': (-1, 0), 'R': (1, 0), 'U':(0, 1), 'D':(0, -1)}
  7. GENERATION_SIZE = 100
  8. FIELD_SIZE = 10
  9. ITERATIONS = 1000
  10.  
  11. def generate():
  12.     """ Returns a new random sequence. """
  13.     sequence = ''
  14.     for _ in range(LENGTH):
  15.         sequence += GENES[randint(0, 3)]
  16.     return sequence
  17.  
  18. def crossover(a, b):
  19.     """ Does crossover between two sequences and returns a new one. """
  20.     sequence = a[:LENGTH//2] + b[LENGTH//2:]
  21.     return sequence
  22.    
  23. def mutation(sequence):
  24.     """ Mutates a sequence. """
  25.     i = randint(0, LENGTH-1)
  26.     sequence = list(sequence)
  27.     sequence[i] = GENES[randint(0, 3)]
  28.     return ''.join(sequence)
  29.  
  30. def evaluate(field, sequence):
  31.     """ Returns the number of flowers the rabbit picks up. """
  32.     f = deepcopy(field)
  33.     flowers = 0
  34.     x = y = FIELD_SIZE // 2
  35.     flowers += f[x][y]
  36.     f[x][y] = 0
  37.     for s in sequence:
  38.         x += DIRECTIONS[s][0]
  39.         y += DIRECTIONS[s][1]
  40.         if x not in range(FIELD_SIZE) or y not in range(FIELD_SIZE):
  41.             # rabbit went out of the field
  42.             continue
  43.         flowers += f[x][y]
  44.         f[x][y] = 0
  45.     return flowers
  46.  
  47. def selection(sequences, weights):
  48.     """ Returns a randomly selected sequence from weighted distribution. """
  49.     total = sum(weights)
  50.     r = uniform(0, total)
  51.     upto = 0
  52.     for s, w in zip(sequences, weights):
  53.         if upto + w >= r:
  54.             return s
  55.         upto += w
  56.  
  57. # random generated field
  58. field = [[randint(0, 5) for _ in range(FIELD_SIZE)] for _ in range(FIELD_SIZE)]
  59.  
  60. # generate random rabbits
  61. population = [generate() for _ in range(GENERATION_SIZE)]
  62.  
  63. # go through iterations
  64. for generation in range(ITERATIONS):
  65.     # evaluate generation
  66.     evaluations = [evaluate(field, rabbit) for rabbit in population]
  67.  
  68.     # sort generation
  69.     combined = list(zip(evaluations, population))
  70.     combined.sort(key=lambda e: e[0], reverse=True)
  71.     evaluations, population = zip(*combined)
  72.     evaluations = list(evaluations)
  73.     population = list(population)
  74.  
  75.     # print best rabbit
  76.     print('generation:{:3d}\t rabbit: {}\t flowers:{:3d}'.format(
  77.                                         generation,
  78.                                         population[0],
  79.                                         evaluate(field, population[0])))
  80.                    
  81.     # now the population is sorted by flowers descending
  82.     new_generation = []
  83.  
  84.     # now we pick two rabbits from the first half of population
  85.     # and we make them have sex
  86.     for _ in range(GENERATION_SIZE):
  87.         weights = [e**2 for e in evaluations]
  88.         dad = selection(population, weights)
  89.         mom = selection(population, weights)
  90.         child = crossover(dad, mom)
  91.         # 50% that child is a mutant
  92.         if randint(0, 1):
  93.             child = mutation(child)
  94.         new_generation.append(child)
  95.  
  96.     population = new_generation
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement