2015-12-06 6 views
0

Я сделал генетический алгоритм с целью получить у позиции «организм» сверху 20. Проблема заключается в части под классом:питона - генетический алгоритм не работает

import random as r 

class Organism(object): 
    def __init__(self, genes,ID): 
     self.genes = genes 
     self.position = [0,0] 
     self.thisTime=str() 
     self.geneTranslation = [] 
     self.ID=ID 

    def move(self,d): 
     if d == "f" or d == "forward": 
      self.position[1] += 1 
     elif d == "b" or d == "back": 
      self.position[1] -= 1 
     elif d == "r" or d == "right": 
      self.position[0] += 1 
     elif d == "l" or d == "left": 
      self.position[0] -= 1 

     print(self.position) 


    def isInContactWith(self,point): 
     point = list(point) 
     if self.position == point: 
      return True 
     else: 
      return False 


    def run(self): 
     for i in range(0,4): 
      if i == 0: 
       self.geneTranslation.extend(["f"] * self.genes[0]) 
      elif i == 1: 
       self.geneTranslation.extend(["b"] * self.genes[1]) 
      elif i == 2: 
       self.geneTranslation.extend(["r"] * self.genes[2]) 
      elif i == 3: 
       self.geneTranslation.extend(["l"] * self.genes[3]) 
     r.shuffle(self.geneTranslation) 
     for x in range(1,20): 
      try: 
       self.thisTime = r.choice(self.geneTranslation) 
       self.move(self.thisTime) 
      except: 
       pass 


population = [] 
yValues={} 

running = True 
BestOrganism=Organism([25,25,25,25],0) 
for count in range(50): 
    for x in range(100): 
     a = lambda: r.randint(-3, 3) 

     b = BestOrganism.genes[:] 
     anOrganism = Organism(b[:],x) 
     for count in range(len(anOrganism.genes[:])): 
      anOrganism.genes[count] += int(a()) 
     population.append(anOrganism) 

    for j in range(len(population)): 
     print("Organism " + str(population[j].ID) + str(population[j].genes)) 
     population[j].run() 
     yValues[population[j].ID]=population[j].position[1] 
     if population[j].position[1]>=20: 
      print(population[j].genes) 
      running = False 
      break 

    BestOrganism=max(yValues) 

    for k in range(len(population[:])): 
     if population[k].ID==BestOrganism: 
      BestOrganism=population[k] 
    print(yValues[max(yValues)]) 
    print(BestOrganism.genes[:]) 
    population=[] 
    yValues={} 

Как вы можете видеть, гены определяют вероятность выхода организма в определенном направлении. Гены, которые производят более низкие значения y, отбираются, а новое поколение сделано из BestOrganism, немного мутировавшего. Похоже, что это должно привести к появлению большего количества организмов, у которых есть гены с более высоким процентным шансом идти вперед, но это не так. Есть ли другой фактор, который я не принимаю во внимание?

+1

Функция 'run' кажется слишком сложной; по крайней мере, для i в диапазоне (0,4): 'раздел можно удалить (просто вызовите функции, которые вы включаете, и, вероятно, не нужно« перетасовывать »). Кроме того, что при копировании списков вокруг 'b = BestOrganism.genes [:]' это немного трудно читать. – tutuDajuju

+0

Что значит «функции включения»? – Vityou

+0

Я имею в виду [этот рефакторинг] (https://gist.github.com/asfaltboy/734d42d4a14171e5a5cc). Кроме того, существует «мутация», которая должна произойти в цикле 'для x в диапазоне (100):'? Вы предполагаете, что 'geneTranslation' является статической переменной? – tutuDajuju

ответ

2

Основная проблема заключается в том, что вы неправильно используете max: вы обнаруживаете организм с самым большим ключом (ID), а не с наибольшим значением Y. Попробуйте max(yValues, key=yValues.get).

Вы также можете попробовать увеличить число move шагов от 20 к чему-то значительно большему.

Наконец, очистка кода немного поможет сделать все более понятным.

+0

Это не сработало. Все те же результаты. – Vityou

+2

Ой, подождите, да, это так, спасибо. – Vityou

Смежные вопросы