f(x)=x^2的最小值(详解)

 求[-L,L]范围内 F(x)=x^2的最小值。

  • 生成popSize个[-L,L]内的随机数存在列表oldPop中,并计算通过适值函数计算适应值存在列表oldFit中;
  • 进行maxGen次交叉、变异、选择操作;
  • 交叉方式:中点交叉;
  • 变异: yi’=xi’+N(0,sigma^2);
  • 选择:从P∪P’里面的个体排序,取f(x)=x^2最小的前popsize个,组成新的种群
  • 得到最优解

参数步骤

参数: 种群大小m, sigma,T

pop=[1,…,m]   定义种群

 

step1(种群初始化): P={x1,x2,…,xm}  t=1

f(x)=x^2    x*=0

step2(交叉): [xi’,xj’]=crossover(xi,xj)

         {

        (Xi+-xj)/2  中点交差

        其他方式: 凸组合交差方式  alpha*xi+(1-alphx)*xj  

}

Step 3 (变异): xi’=xi’+N(0,sigma^2)

xj’=xj’+ N(0,sigma^2)

 

step4 (选择): P’={x1’,x2’,…,xm’}

 

从P∪P’里面的个体排序,取f(x)=x^2最小的前popsize个,组成新的种群 

Step5(停止准则):  t=t+1; if  t<T  goto step 2; else 停止


实现代码

  • initialzePop.py
# 随机初始化产生popSize个[-L,+L]之间的实数,列表oldPop
import random


def initialzePop(popSize, L):
    oldPop = []
    for i in range(0, popSize):
        n = random.uniform(-L, L)
        oldPop.append(n)

    # print(oldPop)
    return oldPop
  • fitnessFun.py
 # 对每个个体x=oldPop[i],计算其适应度值oldFit[i]=x^2
def fitnessFun(oldPop):
    oldFit = []
    for i in range(0, len(oldPop)):
        oldFit.append(oldPop[i]**2)
    return oldFit
  • crossover
# i1,i2 在[1,popSize]内,x1= oldPop[i1], x2= oldPop[i2], 随机选择两个个体x1,x2,
# 令y[i]=(x1+x2)/2,重复popSize次,生成新种群,
# 相当于 for i in range(1, popSize):  逐个的得到y[i],   结束后return y
import random
def crossover(oldPop):
   y = []
   popSize = len(oldPop)
   for i in range(0, popSize):
      i1 = random.randint(0, popSize-1)
      i2 = random.randint(0, popSize-1)
      # print(i1)
      # print("5555555555555555555")
      # print(i2)
      x1 = oldPop[i1]
      x2 = oldPop[i2]
      y.append((x1 + x2) / 2)
   return y
  •  mutation.py
# 对交差后的每个个体x, 高斯扰动y[i]=x+N(0,sigma^2), 生成新种群,return y
import random


def mutation(newPop, sigma):
    y = []
    for i in range(0, len(newPop)):
        y.append(newPop[i] + random.gauss(0, sigma))
    return y
  • sel.py
# 将原种群和新种群的并集按适应度值排序,选择前面最好的popSize个作为下代,
# 函数体中直接调用排序函数,课本专门有一章可以有排序api函数调用的  sort
from fitnessFun import fitnessFun

def xx(x):
    a = x**2
    return a

def sel(oldPop, newPop):
    oldPop.extend(newPop)
    oldPop.sort(key=xx, reverse=True)
    a = []
    for i in range(len(newPop)):
        a.append(oldPop[i])
    b = fitnessFun(a)
    return [a, b]
  • main.py
from initialzePop import initialzePop
from fitnessFun import fitnessFun
from crossover import crossover
from mutation import mutation
from sel import sel
# from plot import plot

# 参数值
popSize = 50  # 种群规模
sigma = 1
L = 20
maxGen = 50  # 最大代数

oldPop = initialzePop(popSize, L) 

oldFit = fitnessFun(oldPop)  

for i in range(1, maxGen):  # maxGen 表示进化最大世代数, 比如30,50,
    # 交叉
    newPop = crossover(oldPop)

    # 变异
    newPop = mutation(newPop, sigma)

    # 选择
    newFit = fitnessFun(newPop)

    [oldPop, oldFit] = sel(oldPop, newPop)


# 输出最好的个体和适应度值,即为最优解和最优函数值
bestIndividual = oldPop[0]
bestFitness = oldFit[0]
print("最优解:%s"%bestIndividual)
print("最优函数值:%s"%bestFitness)

# plot(bestIndividual, bestFitness, maxGen)

plot.py(可视化)

import matplotlib.pyplot as plt


def plot(bestIndividual, bestFitness, maxGen):
    plt.legend(loc='upper left', bbox_to_anchor=(1, 1))
    plt.tight_layout(pad=5)
    plt.axis([-0.004, 200, -0.004, 0.006])
    plt.grid()
    plt.plot(maxGen, bestIndividual, )
    plt.title('The bestIndividual changes with generations', fontsize=16)
    plt.xlabel('generation', fontsize=16)
    plt.ylabel('bestIndividual', fontsize=16)
    # plt.savefig('out_14.jpg',bbox_inches='tight')
    plt.show()

    plt.legend(loc='upper left', bbox_to_anchor=(1, 1))
    plt.tight_layout(pad=5)
    plt.axis([-0.004, 200, -0.004, 0.006])
    plt.grid()
    plt.plot(maxGen, bestFitness, )
    plt.title('The bestFitness changes with generations', fontsize=16)
    plt.xlabel('generation', fontsize=16)
    plt.ylabel('bestFitness', fontsize=16)
    # plt.savefig('out_14.jpg',bbox_inches='tight')
    plt.show()

 

posted @   阿Qi早起了吗  阅读(658)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示