Code Python pour implémenter un algorithme génétique

黄舟
Libérer: 2017-10-10 10:46:36
original
4588 Les gens l'ont consulté

Cet article présente principalement l'algorithme génétique Python. L'éditeur pense qu'il est plutôt bon, je vais le partager avec vous maintenant et le donner comme référence. Suivons l'éditeur et jetons un coup d'œil.

Écrit avant

Dans l'article précédent, j'ai déjà parlé du processus de base de l'algorithme génétique et je l'ai implémenté avec MATLAB . Cet article s'adresse principalement aux personnes qui ont lu mes articles précédents, je n'entrerai donc pas dans les détails de ce qu'est un algorithme génétique et de son contenu de base. On suppose que tout le monde sait déjà comment j'écris un algorithme génétique.

Fonction principale de l'algorithme génétique de Python

Mon idée est de créer une classe de chromosomes, qui comprend deux variables : le chrome du chromosome et la forme physique. Par conséquent, nous pouvons créer directement des objets en tant qu’individus dans la population.


#染色体的类
class Chrom:
  chrom = []
  fitness = 0
  def showChrom(self):
    print(self.chrom)
  def showFitness(self):
    print(self.fitness)
Copier après la connexion

On commence donc à définir les paramètres de base. J'utilise un dictionnaire pour exprimer la population, ce qui signifie utiliser un dictionnaire pour sauvegarder tous les individus de la population. C'est aussi la méthode que j'ai trouvée pour créer plusieurs objets.

Convertissez l'index du dictionnaire en étiquette individuelle, telle que : chrom1, chrom2, etc. La valeur d'un index de dictionnaire est un objet. Cet objet possède deux attributs, à savoir le chromosome et la fitness.

En fait, à cet égard, je pense que l'idée est supérieure à la programmation matricielle utilisant MATLAB. Parce que cela peut exprimer l'idée d'individus et d'attributs individuels de manière très intuitive, il est logiquement plus facile à accepter qu'un tas de matrices.


#基础参数
N = 200 #种群内个体数目
mut = 0.2 #突变概率
acr = 0.2 #交叉概率

pop = {} #存储染色体的字典
for i in range(N):
  pop['chrom'+str(i)] = Chrom()
chromNodes = 2 #染色体节点数(变量个数)
iterNum = 10000 #迭代次数
chromRange = [[0, 10], [0, 10]] #染色体范围
aveFitnessList = [] #平均适应度
bestFitnessList = [] #最优适应度
Copier après la connexion

Après vient le chromosome initial, qui implique diverses fonctions utilisées pour initialiser la population, calculer la condition physique, trouver l'optimal, etc. Je les ai séparées ici Deux fichiers, à savoir Genetic.py et Fitness.py.

Il y a huit fonctions dans Genetic.py, qui incluent principalement des fonctions qui opèrent sur des populations ou des chromosomes, à savoir :

  1. la fonction findBest, qui est utilisée pour trouver des membres de une population Le chromosome optimal ;

  2. fonction findworse, utilisée pour trouver le pire chromosome de la population

  3. fonction d'initialisation, utilisée pour initialiser le chromosome optimal ; population ;

  4. fonction calAveFitness, utilisée pour calculer la forme physique moyenne de la population

  5. fonction mutChrom, utilisée pour muter les chromosomes ;

  6. fonction inRange, utilisée pour déterminer si la valeur du nœud chromosomique est hors limites

  7. fonction acrChrom, utilisée pour traverser le chromosome

    <; 🎜>

  8. fonction compareChrom, utilisée pour comparer deux chromosomes lequel est le meilleur.
  9. Il existe deux fonctions dans Fitness.py, qui incluent principalement des fonctions pour les opérations de fitness, à savoir :

    fonction calFitness, utilisez Pour itérer chaque individu et calculer la condition physique (calculée à l'aide de la fonction funcFitness
  1. la fonction funcFitness calcule la condition physique d'un seul individu);
  2. Le code d'initialisation peut donc être répertorié comme


L'idée et la logique du processus itératif sont les mêmes que MATLAB
#初始染色体
pop = Genetic.initialize(pop, chromNodes, chromRange)
pop = Fitness.calFitness(pop) #计算适应度
bestChrom = Genetic.findBest(pop) #寻找最优染色体
bestFitnessList.append(bestChrom[1]) #将当前最优适应度压入列表中
aveFitnessList.append(Genetic.calAveFitness(pop, N)) #计算并存储平均适应度
Copier après la connexion


Enfin, créez une image itérative
#开始迭代
for t in range(iterNum):
  #染色体突变
  pop = Genetic.mutChrom(pop, mut, chromNodes, bestChrom, chromRange)
  #染色体交换
  pop = Genetic.acrChrom(pop, acr, chromNodes)
  #寻找最优
  nowBestChrom = Genetic.findBest(pop)
  #比较前一个时间的最优和现在的最优
  bestChrom = Genetic.compareChrom(nowBestChrom, bestChrom)
  #寻找与替换最劣
  worseChrom = Genetic.findWorse(pop)
  pop[worseChrom[0]].chrom = pop[bestChrom[0]].chrom.copy()
  pop[worseChrom[0]].fitness = pop[bestChrom[0]].fitness
  #存储最优与平均
  bestFitnessList.append(bestChrom[1])
  aveFitnessList.append(Genetic.calAveFitness(pop, N))
Copier après la connexion


Enfin, ajoutez diverses images au front La bibliothèque et les fichiers sont prêts à être exécutés.
plt.figure(1)
plt.plot(x, aveFitnessList)
plt.plot(x, bestFitnessList)
plt.show()
Copier après la connexion


import Genetic
import Fitness
import matplotlib.pyplot as plt
import numpy as np
Copier après la connexion
Illumination

On peut dire que l'information la plus importante est la catégorie des chromosomes. En fait, les deux fichiers Genetic.py et Fitness.py peuvent également être directement empaquetés dans des classes, mais dans ce cas, je pense que le fichier principal est trop volumineux, et il serait superflu de les empaqueter dans des classes dans d'autres fichiers après tout. , ce n'est qu'un petit programme, c'est donc ce que j'ai écrit.

Je comprends profondément les avantages de la programmation orientée objet. C'est un vrai plaisir de traiter la logique de programmation. Il suffit de penser aux propriétés de l'objet, éliminant ainsi beaucoup de réflexions compliquées.

Une autre idée consiste à utiliser la méthode du dictionnaire pour créer des objets lors de la création de plusieurs objets. Au début, je ne savais pas non plus comment créer un tableau d'objets similaire à celui du C++. J'ai recherché diverses méthodes sur Internet, mais les résultats étaient tous évasifs (bien sûr, il se peut que ma capacité de recherche soit trop faible). et je ne l'ai pas trouvé), alors après l'avoir essayé, je suis tombé sur cette méthode.

J'expliquerai cette méthode en détail quand j'aurai le temps, mais cette fois je m'arrêterai ici.

Les fonctions restantes sont complétées

La première concerne les huit fonctions de Genetic.py


Ensuite il y a les deux fonctions de Fitness.py
import random

#寻找最优染色体
def findBest(pop):
  best = [&#39;1&#39;, 0.0000001]
  for i in pop:
    if best[1] < pop[i].fitness:
      best = [i, pop[i].fitness]
  return best

#寻找最劣染色体
def findWorse(pop):
  worse = [&#39;1&#39;, 999999]
  for i in pop:
    if worse[1] > pop[i].fitness:
      worse = [i, pop[i].fitness]
  return worse

#赋初始值
def initialize(pop, chromNodes, chromRange):
  for i in pop:
    chromList = []
    for j in range(chromNodes):
      chromList.append(random.uniform(chromRange[j][0], chromRange[j][1]+1))
    pop[i].chrom = chromList.copy()
  return pop

#计算平均适应度
def calAveFitness(pop, N):
  sumFitness = 0
  for i in pop:
    sumFitness = sumFitness + pop[i].fitness
  aveFitness = sumFitness / N
  return aveFitness

#进行突变
def mutChrom(pop, mut, chromNodes, bestChrom, chromRange):
  for i in pop:
    #如果随机数小于变异概率(即可以变异)
    if mut > random.random():
      mutNode = random.randrange(0,chromNodes)
      mutRange = random.random() * (1-pop[i].fitness/bestChrom[1])**2
      pop[i].chrom[mutNode] = pop[i].chrom[mutNode] * (1+mutRange)
      #判断变异后的范围是否在要求范围内
      pop[i].chrom[mutNode] = inRange(pop[i].chrom[mutNode], chromRange[mutNode])
  return pop

#检验便宜范围是否在要求范围内
def inRange(mutNode, chromRange):
  if chromRange[0] < mutNode < chromRange[1]:
    return mutNode
  elif mutNode-chromRange[0] > mutNode-chromRange[1]:
    return chromRange[1]
  else:
    return chromRange[0]

#进行交叉
def acrChrom(pop, acr, chromNodes):
  for i in pop:
    for j in pop:
      if acr > random.random():
        acrNode = random.randrange(0, chromNodes)
        #两个染色体节点进行交换
        pop[i].chrom[acrNode], pop[j].chrom[acrNode] = pop[j].chrom[acrNode], pop[i].chrom[acrNode]
  return pop

#进行比较
def compareChrom(nowbestChrom, bestChrom):
  if bestChrom[1] > nowbestChrom[1]:
    return bestChrom
  else:
    return nowbestChrom
Copier après la connexion


Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal