>백엔드 개발 >파이썬 튜토리얼 >유전자 알고리즘을 구현하는 Python 코드

유전자 알고리즘을 구현하는 Python 코드

黄舟
黄舟원래의
2017-10-10 10:46:364624검색

이 글은 Python 유전 알고리즘을 주로 소개하고 있는데, 편집자님이 꽤 좋다고 생각하셔서 지금부터 참고용으로 올려드리겠습니다. 에디터를 따라가서 살펴보겠습니다

Written before

이전 글에서는 이미 유전 알고리즘의 기본 과정에 대해 이야기하고 이를 MATLAB으로 구현해봤습니다. 이 기사는 주로 내 이전 기사를 읽은 사람들을 위한 것이므로 유전 알고리즘이 무엇인지, 그 기본 내용에 대해 자세히 설명하지 않겠습니다. 유전 알고리즘을 작성하는 방법은 모두가 이미 알고 있다고 가정합니다.

Python의 유전 알고리즘 주요 기능

제 아이디어는 염색체 크롬과 피트니스라는 두 가지 변수를 포함하는 염색체 클래스를 만드는 것입니다. 따라서 우리는 모집단의 개인으로서 객체를 직접 생성할 수 있습니다.


#染色体的类
class Chrom:
  chrom = []
  fitness = 0
  def showChrom(self):
    print(self.chrom)
  def showFitness(self):
    print(self.fitness)

이제 기본 매개변수 설정을 시작합니다. 인구를 표현하기 위해 사전을 사용하는데, 이는 인구 내의 모든 개체를 사전을 사용하여 여러 개체를 생성하는 방법이기도 합니다.

사전 색인을 chrom1, chrom2 등과 같은 개별 라벨로 변환하세요. 사전 색인의 값은 객체입니다. 이 개체에는 염색체와 적합성이라는 두 가지 속성이 있습니다.

사실 이런 점에서는 MATLAB을 이용한 행렬 프로그래밍보다 아이디어가 더 좋다고 생각합니다. 이는 개인의 생각과 개인의 속성을 매우 직관적으로 표현할 수 있기 때문에, 행렬 묶음보다 논리적으로 수용하기가 더 쉽습니다.


#基础参数
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 = [] #最优适应度

다음에는 모집단 초기화, 적합도 계산, 최적값 찾기 등에 사용되는 다양한 기능이 포함된 초기 염색체가 나옵니다. 여기에서는 Genetic.py와 Fitness py라는 두 개의 파일을 분리했습니다.

Genetic.py에는 주로 인구 또는 염색체에 작동하는 기능을 포함하는 8가지 기능이 포함되어 있습니다.

  1. findBest 기능은 인구에서 최적의 염색체를 찾는 데 사용됩니다. 모집단에서 최악의 염색체를 찾습니다.

  2. calAveFitness 함수, 모집단의 평균 체력을 계산하는 데 사용됩니다. 염색체 돌연변이를 수행하는 데 사용됩니다. ;

  3. inRange 함수, 염색체 노드 값이 범위를 벗어났는지 확인하는 데 사용됨

  4. acrChrom 함수, 염색체 교차에 사용됨

  5. compareChrom 함수, 두 염색체의 우월성을 비교하는 데 사용됨.

  6. Fitness.py에는 주로 피트니스 작업을 위한 기능을 포함하는 두 가지 함수가 포함되어 있습니다. 즉,

  7. calFitness 함수는 각 개인을 반복하고 피트니스(funcFitness 함수를 사용하여 계산됨)를 계산하는 데 사용됩니다.

    funcFitness 함수는 한 개인의 체력을 계산합니다.
  8. 그래서 초기화 코드는

#初始染色体
pop = Genetic.initialize(pop, chromNodes, chromRange)
pop = Fitness.calFitness(pop) #计算适应度
bestChrom = Genetic.findBest(pop) #寻找最优染色体
bestFitnessList.append(bestChrom[1]) #将当前最优适应度压入列表中
aveFitnessList.append(Genetic.calAveFitness(pop, N)) #计算并存储平均适应度
    로 나열될 수 있습니다. 반복 프로세스의 아이디어와 논리는 MATLAB
  1. #开始迭代
    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))
  2. 마지막으로 반복 이미지를 만들어 보겠습니다

plt.figure(1)
plt.plot(x, aveFitnessList)
plt.plot(x, bestFitnessList)
plt.show()

마지막으로, 전면에 다양한 라이브러리와 파일을 추가하여 실행할 수 있습니다.


import Genetic
import Fitness
import matplotlib.pyplot as plt
import numpy as np

Enlightenment


가장 중요한 통찰력은 염색체의 범주라고 할 수 있습니다. 실제로 Genetic.py와 Fitness.py 두 파일을 클래스로 직접 패키징할 수도 있는데, 이 경우에는 메인 파일이 너무 커져서 결국 다른 파일의 클래스로 패키징하는 것이 불필요할 것 같습니다. , 이것은 단지 작은 프로그램이므로 제가 작성한 것입니다.

객체 지향 프로그래밍의 장점을 깊이 이해하고 있습니다. 프로그래밍 논리를 다루는 것은 많은 복잡한 생각을 없애고 객체의 속성만 생각하면 됩니다.


또 다른 통찰력은 여러 개체를 만들 때 사전 방법을 사용하여 개체를 만드는 것입니다. 저도 처음에는 어떻게 C++에서와 비슷한 객체배열을 만드는지 헷갈렸어요. 인터넷에서 여러가지 방법을 찾아봤지만 결과는 다 엉터리였습니다(물론 제 검색능력이 너무 떨어지는 것일 수도 있습니다) 찾을 수 없었습니다) 그래서 시도해 본 결과 이 ​​방법을 발견했습니다.

이 방법은 시간이 나면 자세히 설명하겠지만, 이번에는 여기까지 하겠습니다.


나머지 함수는 보완

먼저 Genetic.py에 있는 8가지 함수

import random

#寻找最优染色体
def findBest(pop):
  best = ['1', 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

다음으로 Fitness.py에 2가지 함수가 있습니다

import math

def calFitness(pop):
  
  for i in pop:
    #计算每个染色体的适应度
    pop[i].fitness = funcFitness(pop[i].chrom)

  return pop

def funcFitness(chrom):
  #适应度函数
  fitness = math.sin(chrom[0])+math.cos(chrom[1])+0.1*(chrom[0]+chrom[1])

위 내용은 유전자 알고리즘을 구현하는 Python 코드의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.