Генетический алгоритм: проблема сходимости

#python #algorithm #genetic-algorithm

Вопрос:

Я пытаюсь найти решение проблемы с одним максимумом с помощью генетического алгоритма, но оно не сходится, вместо этого максимальная пригодность снижается. Я не понимаю, почему это не работает; Я пытался выполнять функции самостоятельно, и они работали, хотя я не уверен в вызове в основном.единственная максимальная проблема заключается в том, что у вас есть популяция N двоичных особей (1/0) длины m, и вы хотите оптимизировать свою популяцию, чтобы создать по крайней мере одну особь, содержащую только 1 (в моем случае 0).

Вот мой код:

 import random  def fitness(individual):  i = 0  for m in individual:  if m == 0:  i  = 1  return i  def selection(pop):  chosen = []  for i in range(len(pop)):  aspirants = []  macs = []  for j in range(3):  aspirants.append(random.choice(pop))  if fitness(aspirants[0]) gt; fitness(aspirants[1]):  if fitness(aspirants[0]) gt; fitness(aspirants[2]):  macs = aspirants[0]  else: macs = aspirants[2]  else:  if fitness(aspirants[1]) gt; fitness(aspirants[2]):  macs = aspirants[1]  else: macs = aspirants[2]  chosen.append(macs)  return chosen  def crossover(offspring):  for child1, child2 in zip(offspring[::2], offspring[1::2]):  if random.random() lt; 0.7:  child1[50:100], child2[50:100]=child2[50:100], child1[50:100]  def mutate(offspring):  for mut in offspring:  if random.random() lt; 0.3:  for i in range(len(mut)):  if random.random() lt; 0.05:  mut[i] = type(mut[i])(not mut[i])  def gen_individ():  ind = []  for s in range(100):  ind.append(random.randint(0, 1))  return ind  def gen_pop():  pop = []   for s in range(300):  pop.append(gen_individ())  return pop  g = 0 popul = gen_pop() print("length of pop = %i "% len(popul)) fits = [] for k in popul:  fits.append(fitness(k))  print("best fitness before = %i"% max(fits)) while(max(fits) lt; 100 and g lt; 100):   g  = 1  offspring = []  offspring = selection(popul)  crossover(offspring)  mutate(offspring)  popul.clear()  popul[:] = offspring  fits.clear()  for k in popul:  fits.append(fitness(k)) print("lenght of pop = %i "% len(popul)) print("best fitness after = %i"% max(fits))  print("generation : %i"%g)  

Комментарии:

1. Что такое «проблема с одним максимумом»?

2. единственная максимальная проблема заключается в том, что у вас есть популяция N двоичных особей (1/0) длины m, и вы хотите оптимизировать свою популяцию, чтобы создать по крайней мере одну особь, содержащую только 1 (в моем случае 0).

3. Пожалуйста, отредактируйте свой вопрос с этой информацией!

Ответ №1:

Проблема, по-видимому, в том, что во всех ваших функциях вы всегда просто изменяете одних и тех же людей вместо создания копий. Например, в selection функции вы неоднократно выбираете лучший из трех (довольно запутанным способом), а затем вставляете в список несколько ссылок на chosen один и тот же список. Позже, когда вы mutate сделаете что-либо из этого, вы измените все ссылки. В конце концов, вы можете даже получить только N ссылки на один и тот же список, и в этот момент, очевидно, больше не может быть фактического выбора.

Вместо этого вам следует создать копии списков. Это может произойти в разных местах: в вашем основном методе, в mutate и recombine или в selection для следующей итерации. Я расскажу об этом selection , главным образом по той причине, что эту функцию можно улучшить и другими способами:

 def selection(pop):  chosen = []  for i in range(len(pop)):  # a lot shorter  aspirants = random.sample(pop, 3)  macs = max(aspirants, key=fitness)  # create COPIES of the individual, not multiple references  chosen.append(macs[:])  return chosen  

При этом вы должны каждый раз получать качество 100.

Комментарии:

1. действительно, как представляется, в этом и заключается проблема, я новичок в python, хотя и не вижу этого ясно.