ホームページ  >  記事  >  バックエンド開発  >  遺伝的アルゴリズムを実装するための Python コード

遺伝的アルゴリズムを実装するための Python コード

黄舟
黄舟オリジナル
2017-10-10 10:46:364586ブラウズ

この記事では主に Python の遺伝的アルゴリズムを紹介します。編集者がそれを参考にさせていただきます。エディターをフォローして見てみましょう

前に書きました

前回の記事では、遺伝的アルゴリズムの基本的なプロセスについて説明し、MATLAB で実装しました。この記事は主に私の以前の記事を読んでくださった方を対象としているため、遺伝的アルゴリズムとは何か、その基本的な内容については詳しく説明しません。遺伝的アルゴリズムの書き方は皆さんすでにご存知だと思います。

Python の遺伝的アルゴリズムのメイン関数

私のアイデアは、染色体 chrom とフィットネスという 2 つの変数を含む染色体クラスを作成することです。したがって、私たちは集団内の個人としてオブジェクトを直接作成できます。


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

それでは、基本的なパラメーターの設定を開始します。母集団を表現するために辞書を使用します。これは、母集団内のすべての個体を保存するために辞書を使用することを意味します。これは、複数のオブジェクトを作成するために私が思いついた方法でもあります。

辞書インデックスを chrom1、chrom2 などの個別のラベルに変換します。辞書インデックスの値はオブジェクトです。このオブジェクトには、染色体とフィットネスという 2 つの属性があります。

実際、この点では、このアイデアは 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 という 2 つのファイルを分離しました。

Genetic.py には 8 つの関数が含まれており、主に母集団または染色体を操作する関数が含まれます。母集団内の最悪の染色体を見つける

  1. initialize 関数、母集団の平均適応度を計算するために使用されます。

  2. mutChrom 関数、 ;

  3. inRange 関数は、染色体ノード値が範囲外であるかどうかを判断するために使用されます。

  4. acrChrom 関数は、2 つの染色体の優位性を比較するために使用されます。

  5. Fitness.py には、主にフィットネス操作のための関数が含まれる 2 つの関数が含まれています。つまり、

  6. calFitness 関数。各個人を反復処理し、フィットネス (funcFitness 関数を使用して計算) を計算するために使用されます。

    funcFitness 関数は、1 人の個人のフィットネスを計算します。
  7. したがって、初期化コードは次のようにリストできます
  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)) #计算并存储平均适应度
  9. 反復プロセスの考え方とロジックはMATLABと同じです

    #开始迭代
    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))
  1. 最後に、反復イメージを実行しましょう

  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

啓発

最も重要な洞察は染色体のカテゴリーであると言えます。実際、Genetic.py と Fitness.py の 2 つのファイルをクラスに直接パッケージ化することもできますが、この場合、メイン ファイルが肥大化しすぎるため、結局のところ、これらを他のファイルのクラスにパッケージ化するのは不必要だと思います。 、これはほんの小さなプログラムなので、私が書いたものです。

オブジェクト指向プログラミングの利点を深く理解しました。オブジェクトのプロパティについて考えるだけで済むので、複雑な思考が不要になります。

もう 1 つの洞察は、複数のオブジェクトを作成するときに、辞書メソッドを使用してオブジェクトを作成することです。私も最初は 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 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。