Advertisement
Guest User

Untitled

a guest
Apr 26th, 2017
139
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.41 KB | None | 0 0
  1. from random import random
  2. from collections import Counter
  3.  
  4. class Creature:
  5.  
  6.     RECESSIVE = "a"
  7.     DOMINANT  = "A"
  8.  
  9.     def __init__(self, g1, g2, parent1 = None, parent2 = None):
  10.         self.gene1 = g1
  11.         self.gene2 = g2
  12.         self.parent1 = parent1
  13.         self.parent2 = parent2
  14.  
  15.     def breedWith(self, other):
  16.         return (self.__class__)(self.randomGene(), other.randomGene(), self, other)
  17.  
  18.     def randomGene(self):
  19.         if random() > 0.5:
  20.             return self.gene2
  21.         else:
  22.             return self.gene1
  23.  
  24.     def genomeAsString(self):
  25.         return self.gene1 + self.gene2
  26.  
  27.     def phenotype(self):
  28.         if self.gene1 == self.RECESSIVE and self.gene2 == self.RECESSIVE:
  29.             return self.RECESSIVE
  30.         else:
  31.             return self.DOMINANT
  32.  
  33. class AvoidSiblingsCreature(Creature):
  34.  
  35.     def chooseMate(self, population):
  36.         mate = None
  37.         n = 1.0
  38.         for x in population:
  39.             if not self.isSibling(x):
  40.                 if random() <= 1/n:
  41.                     mate = x
  42.                     n += 1
  43.         return mate
  44.  
  45.     def isSibling(self, other):
  46.         if other.parent1 == self.parent1 != None:
  47.             return True
  48.         if other.parent1 == self.parent2 != None:
  49.             return True
  50.         if other.parent2 == self.parent1 != None:
  51.             return True
  52.         if other.parent2 == self.parent2 != None:
  53.             return True
  54.         return False
  55.  
  56. class SeekSiblingsCreature(Creature):
  57.  
  58.     # Uniformly picks a sibling, but uniformly picks anyone if that's not possible
  59.     def chooseMate(self, population):
  60.         mate = None
  61.         secondChoice = None
  62.         n = 1.0
  63.         k = 1.0
  64.         for x in population:
  65.             if self.isSibling(x):
  66.                 if random() <= 1/n:
  67.                     mate = x
  68.                     n += 1
  69.             else:
  70.                 if random() <= 1/k:
  71.                     secondChoice = x
  72.                     k += 1
  73.         if mate != None:
  74.             return mate
  75.         else:
  76.             return secondChoice
  77.  
  78.     def isHalfSibling(self, other):
  79.         if other.parent1 == self.parent1 != None:
  80.             return True
  81.         if other.parent1 == self.parent2 != None:
  82.             return True
  83.         if other.parent2 == self.parent1 != None:
  84.             return True
  85.         if other.parent2 == self.parent2 != None:
  86.             return True
  87.         return False
  88.  
  89.     def isSibling(self, other):
  90.         if other.parent1 == self.parent1 != None:
  91.             if other.parent2 == self.parent2 != None:
  92.                 return True
  93.         if other.parent1 == self.parent2 != None:
  94.             if other.parent2 == self.parent1 != None:
  95.                 return True
  96.         return False
  97.  
  98. class Population:
  99.  
  100.     DEATH_RATE_a = 0.1
  101.     DEATH_RATE_A = 0.05
  102.    
  103.     BIRTH_RATE = 0.068/3
  104.     CHILDREN_PER_COUPLE = 3
  105.  
  106.     def __init__(self, population):
  107.         self.population = population
  108.  
  109.     def breed(self):
  110.         # Death
  111.         toKill = []
  112.         for x in self.population:
  113.             if x.phenotype() == Creature.DOMINANT:
  114.                 if random() < self.DEATH_RATE_A:
  115.                     toKill.append(x)
  116.             else:
  117.                 if random() < self.DEATH_RATE_a:
  118.                     toKill.append(x)
  119.         for x in toKill:
  120.             self.population.remove(x)
  121.  
  122.         # Birth
  123.         newborns = []
  124.         for x in self.population:
  125.             if random() < self.BIRTH_RATE:
  126.                 y = x.chooseMate(self.population)
  127.                 n = 0
  128.                 while n < self.CHILDREN_PER_COUPLE:
  129.                     newborns.append(x.breedWith(y))
  130.                     n += 1
  131.         self.population = self.population + newborns
  132.  
  133.     def stats(self):
  134.         return Counter(map(lambda x: x.genomeAsString(), self.population))
  135.  
  136.     def size(self):
  137.         return len(self.population)
  138.  
  139. def randomGene(p = 0.5):
  140.     if random() < p:
  141.         return Creature.DOMINANT
  142.     else:
  143.         return Creature.RECESSIVE
  144.  
  145. N = 100
  146. initialPopulation = []
  147. while len(initialPopulation) < N:
  148.     g1 = randomGene()
  149.     g2 = randomGene()
  150.     x = SeekSiblingsCreature(g1, g2)
  151.     initialPopulation.append(x)
  152.  
  153. P = Population(initialPopulation)
  154. maxGenerations = 100
  155. for n in range(maxGenerations):
  156.     print P.size(), P.stats()
  157.     P.breed()
  158.  
  159. print "Final frequency of recessive phenotype: %f" % (P.stats()["aa"]/float(P.size()))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement