粒子群算法 一元函数,二元函数 python

这里是一只要努力进化的python小白的学习记录:
代码是按照一份matlab版代码实现的 参考这个
先放一个一元函数的
效果图:
粒子群算法 一元函数,二元函数 python_第1张图片粒子群算法 一元函数,二元函数 python_第2张图片粒子群算法 一元函数,二元函数 python_第3张图片

#!/usr/bin/python3
import sys
import math
import random
import matplotlib.pyplot as plt
import pylab as pl
import numpy as np
import sympy   # 引入解方程的专业模块sympy
pi=math.acos(-1)
#粒子群算法 所有的粒子在解空间内寻找到最优解的过程。
#利用粒子群算法计算一元函数的最大值
#参数初始化
c1 = 1.49445;
c2 = 1.49445;
maxgen=50 #进化次数
sizepop=10 #种群规模
dimension =1 #一元函数求解维数为1 
#速度的边界
Vmax=0.5
Vmin=-0.5
#种群边界
popmax=2.00
popmin=1.00
#计算惯性权重 
ws=0.9
we=0.4
#给矩阵预分配内存
pop=np.zeros((sizepop,dimension))
V=np.zeros((sizepop,dimension))
fitness=np.zeros((sizepop,1))
yy=np.zeros(maxgen)
w=np.zeros(maxgen)
#xx=np.zeros(maxgen)
def Drawprocess(yy):
    pl.rcParams['savefig.dpi'] =300 #图片像素
    pl.rcParams['figure.dpi'] = 300 #分辨率
    pl.mpl.rcParams['font.sans-serif'] = ['FangSong'] # 指定默认字体
    pl.mpl.rcParams['axes.unicode_minus'] = False # 解决保存图像是负号'-'显示为方块的问题
    pl.title('优化过程') 
    plt.xlim(xmax=maxgen,xmin=0)#坐标上下界
    plt.ylim(ymax=1.0,ymin=-1.0)
    x = range(0,maxgen)  # 横轴的数据 range不能实现小数加,所以只能用np.arange
    y = [ yy[x] for x in range(0,maxgen)]  # 纵轴的数据
    pl.plot(x, y, 'k-', label=u'最优值')  # 加上label参数添加图例 
    #标记起点终点
    pl.xlabel(u"X轴")
    pl.ylabel(u"Y轴")
    pl.legend()  # 让图例生效
    #pl.axis('off')
    #pl.savefig('路径', dpi=300) #指定分辨
    pl.show()  # 显示绘制出的图   
    return 
def DrawPic1():#呈现出一元函数
    pl.rcParams['savefig.dpi'] =300 #图片像素
    pl.rcParams['figure.dpi'] = 300 #分辨率
    pl.mpl.rcParams['font.sans-serif'] = ['FangSong'] # 指定默认字体
    pl.mpl.rcParams['axes.unicode_minus'] = False # 解决保存图像是负号'-'显示为方块的问题
    pl.title('一元函数') 
    plt.xlim(xmax=2.0,xmin=1.0)#坐标上下界
    plt.ylim(ymax=1.0,ymin=-1.0)
    x = np.arange(1.00,2.01,0.01)  # 横轴的数据 range不能实现小数加,所以只能用np.arange
    y = [ math.sin(10*pi*x)/ x for x in np.arange(1.00,2.01,0.01)]  # 纵轴的数据
    pl.plot(x, y, 'k-', label=u'函数值')  # 加上label参数添加图例 
    #标记起点终点
    pl.xlabel(u"X轴")
    pl.ylabel(u"Y轴")
    pl.legend()  # 让图例生效
    #pl.axis('off')
    #pl.savefig('路径', dpi=300) #指定分辨
    pl.show()  # 显示绘制出的图   
    return 
def DrawPic2(tx,ty):#呈现结果
    pl.rcParams['savefig.dpi'] =300 #图片像素
    pl.rcParams['figure.dpi'] = 300 #分辨率
    pl.mpl.rcParams['font.sans-serif'] = ['FangSong'] # 指定默认字体
    pl.mpl.rcParams['axes.unicode_minus'] = False # 解决保存图像是负号'-'显示为方块的问题
    pl.title('一元函数运行结果') 
    plt.xlim(xmax=2.0,xmin=1.0)#坐标上下界
    plt.ylim(ymax=1.0,ymin=-1.0)
    x = np.arange(1.00,2.01,0.01)  # 横轴的数据 range不能实现小数加,所以只能用np.arange
    y = [ math.sin(10*pi*x)/ x for x in np.arange(1.00,2.01,0.01)]  # 纵轴的数据
    pl.plot(x, y, 'k-', label=u'函数值')  # 加上label参数添加图例 
    #标记起点终点
    pl.plot(tx, ty, 'or', label=u'target')
    pl.xlabel(u"X轴")
    pl.ylabel(u"Y轴")
    pl.legend()  # 让图例生效
    #pl.axis('off')
    #pl.savefig('路径', dpi=300) #指定分辨
    pl.show()  # 显示绘制出的图   
    return 
def fun(x):
    y = (np.sin(10 * pi * x) /(1.0* x));
    return y;

DrawPic1()

#产生初始粒子和速度
funcmaxx=-2.0
indexmaxx=0
for i in range(0,sizepop):
    random.seed()
    #pop[i]=((random.random()+1.0)/2.0)+ 1.0#初始种群
    pop[i]=(random.uniform(-1.0,1.0)+1.0)/2.0+1.0 #random 返回一个大于等于0小于1 的数
    V[i]=0.5*random.uniform(-1.0,1.0) #初始化速度
    #计算适应度
    fitness[i]=fun(pop[i].copy())
    #print(pop[i],V[i],fitness[i])
    if(fitness[i]>funcmaxx):
        funcmaxx=fitness[i].copy()
        indexmaxx=i
#print("HH",fun(1.72))    
bestfitness=funcmaxx
#print(bestfitness,indexmaxx)
bestindex=indexmaxx
gbest=pop[bestindex]
pbest=pop.copy()#又是一模一样的错误,,,,,啊啊啊 赋值用copy
fitnesspbest = fitness.copy()                           #个体最佳适应度值
fitnessgbest = bestfitness.copy()                      #全局最佳适应度值

for i in range(0,maxgen):#等价matlab 1:maxgen 因为次数都是maxgen次
     w[i]= ws - (ws - we) * (i*1.0 / maxgen); #让惯性权重随着迭代次数而动态改变,控制搜索精度
     for j in range(0,sizepop):
         #速度更新
         V[j]= w[i]*V[j].copy() + c1*random.random()*(pbest[j].copy() - pop[j].copy()) + c2*random.random()*(gbest - pop[j].copy());
         if V[j]> Vmax:
             V[j] = Vmax
         if V[j] < Vmin:
             V[j] = Vmin
         #种群更新位置更新
         pop[j]= pop[j].copy() + V[j].copy()
         if pop[j] > popmax:        
             pop[j] = popmax
         if pop[j] < popmin:
             pop[j] = popmin         
         fitness[j] = fun(pop[j])
         #print(pop[j],"??")
     for j in range(0,sizepop):
         #个体最优更新
         if fitness[j] > fitnesspbest[j]:#也就是更新自己
             
             pbest[j]= pop[j].copy()
             fitnesspbest[j] = fitness[j].copy()
             #群体最优更新
         if fitness[j]> fitnessgbest:#更新整个群体 
             
             gbest = pop[j].copy()
             fitnessgbest = fitness[j].copy()
     yy[i] = fitnessgbest.copy()
     #xx[i] = gbest
     #print(yy[i],gbest)     

DrawPic2(gbest, fitnessgbest)
Drawprocess(yy)        
    
    

二元函数:
效果图:
粒子群算法 一元函数,二元函数 python_第4张图片
粒子群算法 一元函数,二元函数 python_第5张图片粒子群算法 一元函数,二元函数 python_第6张图片

from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
from matplotlib import cm
from matplotlib.ticker import LinearLocator, FormatStrFormatter
import numpy as np
import sys
import math
import random
import matplotlib.pyplot as plt
import pylab as pl
import sympy   # 引入解方程的专业模块sympy
"""绘制三维图标 绘制目标函数曲线"""
pi=math.acos(-1)
fig = plt.figure()
ax = fig.gca(projection='3d')
 
# Make data.
X = np.arange(-5, 5, 0.1)
Y = np.arange(-5, 5, 0.1)
X, Y = np.meshgrid(X, Y)
Z = X**2 + Y**2 - 10*np.cos(2*pi*X) - 10*np.cos(2*pi*Y) + 20
 
# Plot the surface.
surf = ax.plot_surface(X, Y, Z, cmap=cm.coolwarm,
                       linewidth=0, antialiased=False)
 
# Customize the z axis.
#ax.set_zlim(-1.01, 1.01)
#ax.zaxis.set_major_locator(LinearLocator(10))
#ax.zaxis.set_major_formatter(FormatStrFormatter('%.02f'))
 
# Add a color bar which maps values to colors.
fig.colorbar(surf, shrink=0.5, aspect=5)
 
plt.show()
"""绘制三维图标结束"""
def process(x,y,z):
    fig = plt.figure()
    ax = fig.gca(projection='3d')
 
    # Make data.
    X = np.arange(-5, 5, 0.1)
    Y = np.arange(-5, 5, 0.1)
    X, Y = np.meshgrid(X, Y)
    Z = X**2 + Y**2 - 10*np.cos(2*pi*X) - 10*np.cos(2*pi*Y) + 20
 
    # Plot the surface.
    surf = ax.plot_surface(X, Y, Z, cmap=cm.coolwarm,
                       linewidth=0, antialiased=False)
 
    # Customize the z axis.
    #ax.set_zlim(-1.01, 1.01)
    #ax.zaxis.set_major_locator(LinearLocator(10))
    #ax.zaxis.set_major_formatter(FormatStrFormatter('%.02f'))
 
    # Add a color bar which maps values to colors.
    fig.colorbar(surf, shrink=0.5, aspect=5)
    ax.scatter(x, y, z,c='b',marker='o')
    ax.text(x,y,z,'Target')
    return 
def fun(x):
    y = x[0]**2 + x[1]**2 - 10.0*np.cos(2.0*pi*x[0]) - 10*np.cos(2.0*pi*x[1]) + 20.0
    return y
c1 = 1.49445
c2 = 1.49445
 
maxgen = 1000#种群的进化次数
sizepop = 100 #种群规模                                              
dimension =2 #二元所以列数是2
#速度的边界
Vmax=1.0
Vmin=-1.0
#种群边界
popmax=5
popmin=-5
#计算惯性权重 
ws=0.9
we=0.4
#给矩阵预分配内存
pop=np.zeros((sizepop,dimension))
V=np.zeros((sizepop,dimension))
fitness=np.zeros((sizepop,1))
yy=np.zeros(maxgen)
w=np.zeros(maxgen)
#产生初始粒子和速度
funcmaxx=-2.0
indexmaxx=0
def better(yy):
    
    pl.title('优化过程') 
    plt.xlim(xmax=maxgen,xmin=0)#坐标上下界
    plt.ylim(ymax=82.0,ymin=20.0)
    x = range(0,maxgen)  # 横轴的数据 range不能实现小数加,所以只能用np.arange
    y = [ yy[x] for x in range(0,maxgen)]  # 纵轴的数据
    pl.plot(x, y, 'k-', label=u'最优值')  # 加上label参数添加图例 
    #标记起点终点
    pl.xlabel(u"X轴")
    pl.ylabel(u"Y轴")
    pl.legend()  # 让图例生效
    #pl.axis('off')
    #pl.savefig('路径', dpi=300) #指定分辨
    pl.show()  # 显示绘制出的图   
    return 
    
for i in range(0,sizepop):
    #pop[i]= 5.0*np.random.random((1,2))#初始种群
    #V[i]=np.random.random((1,2))#初始化速度
    pop[i][0]=5.0*random.uniform(-1.0,1.0) 
    pop[i][1]=5.0*random.uniform(-1.0,1.0) 
    V[i][0]=1.0*random.uniform(-1.0,1.0) 
    V[i][1]=1.0*random.uniform(-1.0,1.0) 
    #计算适应度
    fitness[i]=fun(pop[i].copy())
    if(fitness[i]>funcmaxx):
        funcmaxx=fitness[i].copy()
        indexmaxx=i
#print("HHH")
        
bestfitness=funcmaxx
#print(bestfitness,indexmaxx)
bestindex=indexmaxx
gbest=pop[bestindex].copy()
pbest=pop.copy()
fitnesspbest = fitness.copy();                            #个体最佳适应度值
fitnessgbest = bestfitness.copy();                        #全局最佳适应度值

for i in range(0,maxgen):#等价matlab 1:maxgen 因为次数都是maxgen次
     w[i]= ws - (ws - we) * (i*1.0 / maxgen)#让惯性权重随着迭代次数而动态改变,控制搜索精度
     for j in range(0,sizepop):
         
         #速度更新
         V[j]= w[i]*V[j] + c1*np.random.random((1,2))*(pbest[j].copy() - pop[j].copy()) + c2*np.random.random((1,2))*(gbest - pop[j].copy());
         for k in range(0,dimension):
             if V[j][k]> Vmax:
                 V[j][k]= Vmax;
             if V[j][k] < Vmin:
                 V[j][k]= Vmin;
         #种群更新位置更新
         pop[j]= pop[j] + V[j]
         for k in range(0,dimension):
             if pop[j][k] > popmax:
                 pop[j][k]= popmax
             if pop[j][k]< popmin:
                 pop[j][k]= popmin
         fitness[j] = fun(pop[j].copy()) 
     for j in range(0,sizepop):
         #个体最优更新
         if fitness[j] > fitnesspbest[j]:#也就是更新自己
             pbest[j]= pop[j].copy()
             fitnesspbest[j] = fitness[j].copy()
         #群体最优更新
         if fitness[j] > fitnessgbest:#更新整个群体 
             gbest = pop[j].copy()
             fitnessgbest = fitness[j].copy()
     yy[i] = fitnessgbest.copy()
     #print(yy[i])     

print(fitnessgbest ,gbest)
better(yy) #先画二维再画三维,不知道为什么画完二维画三维会乱
process(gbest[0],gbest[1],fitnessgbest[0])
       
    
    

你可能感兴趣的:(模型)