Advertisement
atm-irbis

Simple genetic algorithm

May 18th, 2013
592
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.89 KB | None | 0 0
  1. # -*- coding: utf-8 -*-
  2. """
  3. Created on Sat May 18 00:47:03 2013
  4.  
  5. @author: snowcat
  6. @description : Решение Диофантова Уравнения a + 2*b + 3*c +4*d = 30
  7.               с помощью генетического алгоритма.
  8.  
  9.  
  10. """
  11.  
  12. from random import randint
  13.  
  14. class Genetic:
  15.     def __init__(self,gen=None,id=None):
  16.         '''
  17.        Инициализация отдельной особи.
  18.        self.gen - генотип особи
  19.        self.id - уникальный идентификатор для кроссовера
  20.        '''
  21.         if gen != None:
  22.             self.gen = gen
  23.         else:
  24.             self.gen = [randint(1,30) for i in range(1,5)]
  25.            
  26.         if id != None:
  27.             self.id = gen
  28.         else:
  29.             self.id = randint(0,2)
  30.            
  31.     def fitness(self):
  32.         '''
  33.        Функция приспособленности.
  34.        '''
  35.         a,b,c,d = self.gen
  36.         return (a+2*b+3*c+4*d)-30
  37.    
  38.     def crossover(self,f):
  39.         '''
  40.        Кроссовер.
  41.        Перемешивание генотипов.        
  42.        '''
  43.        
  44.         # гены исходной особи
  45.         a,b,c,d = self.gen
  46.         mid = self.id
  47.        
  48.         # гены некоторой другой особи
  49.         aa,bb,cc,dd = f.genotype()
  50.         fid = f.show()
  51.        
  52.         if mid == 0:
  53.             if mid == fid:
  54.                 return Genetic([a,bb,cc,dd])
  55.             else:
  56.                 return Genetic([aa,b,c,d])
  57.         elif mid == 1:
  58.             if mid == fid:
  59.                 return Genetic([a,b,cc,dd])
  60.             else:
  61.                 return Genetic([aa,bb,c,d])
  62.         else:
  63.             if mid == fid:
  64.                 return Genetic([a,b,c,dd])
  65.             else:
  66.                 return Genetic([aa,bb,cc,d])
  67.                    
  68.     def genotype(self):
  69.         '''
  70.        Генотип особи.
  71.        '''
  72.         return self.gen
  73.  
  74.     def show(self):
  75.         '''
  76.        Идентификатор кроссовера.
  77.        '''
  78.         return self.id
  79.        
  80.        
  81. class Population:
  82.     def __init__(self,num=10):
  83.         '''
  84.        Создаем популяцию из num экземпляров.
  85.        По умолчанию - 10 особей.
  86.        '''
  87.         self.p = [Genetic() for i in xrange(1,num+1)]
  88.        
  89.     def cross(self):
  90.         '''
  91.        Кроссовер внутри популяции.
  92.        '''
  93.         from random import sample
  94.         l = len(self.p)
  95.         # создаем две перемешанных копии популяции
  96.         # для выполнения кроссовера
  97.         f = sample(self.p,l)
  98.         m = sample(self.p,l)
  99.         z = []
  100.         # сам кроссовер
  101.         for i in xrange(0,len(f)):
  102.             z.append(f[i].crossover(m[i]))
  103.            
  104.         # промежуточная функция для выполнения
  105.         # "естественного отбора"
  106.         def check(a,b):
  107.             if a.fitness() < b.fitness():
  108.                 return a
  109.             else:
  110.                 return b
  111.         # популяция после отбора
  112.         self.p = map(check,self.p,z)
  113.        
  114.     def mutate(self):
  115.         '''
  116.        Генератор мутаций внутри популяции.
  117.        '''
  118.         l = len(self.p)
  119.         num = int(l*0.4213)+1 # количество мутаций
  120.        
  121.         for i in xrange(1,num):
  122.             v = randint(0,l-1) # элемент популяции нужный для мутации
  123.             p = self.p.pop(v) # запоминаем этот элемент и удаляем его из популяции
  124.             ex = p.genotype() # выясняем его генотип
  125.             ind = randint(0,3) # выбираем элемент генотипа для мутации
  126.             ex.pop(ind)   # удаляем его
  127.             ex.insert(ind,randint(1,30)) # вставляем мутацию
  128.             self.p.append(Genetic(ex)) # вставляем мутированную особь
  129.        
  130.     @property
  131.     def view(self):
  132.         '''
  133.        Все особи популяции.
  134.        '''
  135.         return self.p
  136.  
  137. # популяция из 50 особей                
  138. x = Population(150)
  139.  
  140. # запускаем развитие в течение 15 поколений.
  141. for i in range(1,15):
  142.     x.cross()
  143.     x.mutate()
  144.    
  145. # отсеиваем особей с генотипами, соответствующими решениям
  146. # диофантова уравнения    
  147. k = [i for i in x.view if i.fitness() == 0]
  148.  
  149. if len(k) == 0:
  150.     print u'Решений не обнаружено ! Попробуйте еще раз :)'
  151. else:
  152.     for i in k:
  153.         print i.genotype()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement