python遺傳算法之單/多目標(biāo)規(guī)劃問題
在上一篇博客中,我們學(xué)習(xí)了python遺傳算法包geatpy。并用它展示了一個(gè)不帶約束的單目標(biāo)規(guī)劃問題,對(duì)往期內(nèi)容感興趣的同學(xué)可以參考??:
鏈接: python遺傳算法之geatpy學(xué)習(xí).
在上一期的介紹中,我們用遺傳算法求解時(shí),采用的是類似matlab式的非面向?qū)ο缶幊?,?dǎo)致每一步寫的都很繁瑣,今天我們采用面向?qū)ο缶幊痰姆绞絹砗?jiǎn)化求解過程。
1. 運(yùn)行環(huán)境
這里先介紹一下運(yùn)行環(huán)境
- 系統(tǒng):Windows10
- 配置:i7-6700 16G
- python版本:3.10
- geatpy版本:2.7.0
2. 面向?qū)ο蟮脑?/h2>
前面的章節(jié)中,我們介紹了遺傳算法主要分為算法模板類 (Algorithm)、種群類 (Population)、多染色體混合編碼種群類 (PsyPopulation) 以及問題類 (Problem)。其中 Population 類和 PsyPopulation 類是可以直接被實(shí)例化成對(duì)象去來使用的類;Algorithm 類和 Problem 類是父類,需要實(shí)例化其子類來使用。下面我們通過案例來演示一下用法。
3. 帶約束的單目標(biāo)優(yōu)化問題

3.1 繼承 Problem 問題類完成對(duì)問題模型的描述
在這一步中,主要是將我們的問題按照模板描述清楚,包括目標(biāo)函數(shù)和約束條件。
import numpy as np
import geatpy as ea
class MyProblem(ea.Problem): # 繼承Problem父類
def __init__(self):
name = 'MyProblem' # 初始化name(函數(shù)名稱,可以隨意設(shè)置)
M = 1 # 初始化M(目標(biāo)維數(shù))
maxormins = [-1] # 初始化目標(biāo)最小最大化標(biāo)記列表,1:min;-1:max
Dim = 3 # 初始化Dim(決策變量維數(shù))
varTypes = [0] * Dim # 初始化決策變量類型,0:連續(xù);1:離散
lb = [0, 0, 0] # 決策變量下界
ub = [1, 1, 2] # 決策變量上界
lbin = [1, 1, 0] # 決策變量下邊界
ubin = [1, 1, 0] # 決策變量上邊界
# 調(diào)用父類構(gòu)造方法完成實(shí)例化
ea.Problem.__init__(self, name, M, maxormins, Dim, varTypes, lb,
ub, lbin, ubin)
def aimFunc(self, pop): # 目標(biāo)函數(shù),pop為傳入的種群對(duì)象
Vars = pop.Phen # 得到?jīng)Q策變量矩陣
x1 = Vars[:, [0]] # 取出第一列得到所有個(gè)體的x1組成的列向量
x2 = Vars[:, [1]] # 取出第二列得到所有個(gè)體的x2組成的列向量
x3 = Vars[:, [2]] # 取出第三列得到所有個(gè)體的x3組成的列向量 # 計(jì)算目標(biāo)函數(shù)值,賦值給pop種群對(duì)象的ObjV屬性
pop.ObjV = 4 * x1 + 2 * x2 + x3
# 采用可行性法則處理約束,生成種群個(gè)體違反約束程度矩陣
pop.CV = np.hstack([2 * x1 + x2 - 1, # 第一個(gè)約束
x1 + 2 * x3 - 2, # 第二個(gè)約束
np.abs(x1 + x2 + x3 - 1)]) # 第三個(gè)約束
3.2 調(diào)用算法模板進(jìn)行求解
在第二步中,我們主要編寫的是算法模板對(duì)第一步中問題的定義進(jìn)行求解,這里需要依次設(shè)置種群、算法參數(shù)、種群進(jìn)化、結(jié)果的輸出。
"""main_solve.py"""
import geatpy as ea # import geatpy
from myaim import MyProblem # 導(dǎo)入自定義問題接口
"""============================實(shí)例化問題對(duì)象========================"""
problem = MyProblem() # 實(shí)例化問題對(duì)象
"""==============================種群設(shè)置==========================="""
Encoding = 'RI' # 編碼方式
NIND = 50 # 種群規(guī)模
Field = ea.crtfld(Encoding, problem.varTypes, problem.ranges,problem.borders) # 創(chuàng)建區(qū)域描述器
population = ea.Population(Encoding, Field, NIND) # 實(shí)例化種群對(duì)象(此時(shí)種群還沒被真正初始化,僅僅是生成一個(gè)種群對(duì)象)
"""===========================算法參數(shù)設(shè)置=========================="""
myAlgorithm = ea.soea_DE_best_1_L_templet(problem, population) # 實(shí)例化一個(gè)算法模板對(duì)象
myAlgorithm.MAXGEN = 1000 # 最大進(jìn)化代數(shù)
myAlgorithm.mutOper.F = 0.5 # 差分進(jìn)化中的參數(shù)F
myAlgorithm.recOper.XOVR = 0.7 # 設(shè)置交叉概率
myAlgorithm.logTras = 1 # 設(shè)置每隔多少代記錄日志,若設(shè)置成0則表示不記錄日志
myAlgorithm.verbose = True # 設(shè)置是否打印輸出日志信息
myAlgorithm.drawing = 1 # 設(shè)置繪圖方式(0:不繪圖;1:繪制結(jié)果圖;2:繪制目標(biāo)空間過程動(dòng)畫;3:繪制決策空間過程動(dòng)畫)
"""==========================調(diào)用算法模板進(jìn)行種群進(jìn)化==============="""
[BestIndi, population] = myAlgorithm.run() # 執(zhí)行算法模板,得到最優(yōu)個(gè)體以及最后一代種群
BestIndi.save() # 把最優(yōu)個(gè)體的信息保存到文件中
"""=================================輸出結(jié)果======================="""
print('評(píng)價(jià)次數(shù):%s' % myAlgorithm.evalsNum)
print('時(shí)間花費(fèi) %s 秒' % myAlgorithm.passTime)
if BestIndi.sizes != 0:
print('最優(yōu)的目標(biāo)函數(shù)值為:%s' % BestIndi.ObjV[0][0])
print('最優(yōu)的控制變量值為:')
for i in range(BestIndi.Phen.shape[1]):
print(BestIndi.Phen[0, i])
else:
print('此次未找到可行解。')
3.3 結(jié)果
種群進(jìn)化的結(jié)果為:

最終的結(jié)果為:

4. 帶約束的多目標(biāo)優(yōu)化問題

4.1 繼承 Problem 問題類完成對(duì)問題模型的描述
對(duì)于多目標(biāo)的問題,依舊是先編寫目標(biāo)規(guī)劃問題。
import numpy as np
import geatpy as ea
class MyProblem(ea.Problem): # 繼承Problem父類
def __init__(self):
name = 'BNH' # 初始化name(函數(shù)名稱,可以隨意設(shè)置)
M = 2 # 初始化M(目標(biāo)維數(shù))
maxormins = [1] * M # 初始化maxormins
Dim = 2 # 初始化Dim(決策變量維數(shù))
varTypes = [0] * Dim # 初始化varTypes(決策變量的類型,0:實(shí)數(shù);1:整數(shù))
lb = [0] * Dim # 決策變量下界
ub = [5, 3] # 決策變量上界
lbin = [1] * Dim # 決策變量下邊界
ubin = [1] * Dim # 決策變量上邊界 # 調(diào)用父類構(gòu)造方法完成實(shí)例化
ea.Problem.__init__(self, name, M, maxormins, Dim, varTypes, lb,ub, lbin, ubin)
def aimFunc(self, pop): # 目標(biāo)函數(shù)
Vars = pop.Phen # 得到?jīng)Q策變量矩陣
x1 = Vars[:, [0]] # 注意這樣得到的x1是一個(gè)列向量,表示所有個(gè)體的x1
x2 = Vars[:, [1]]
f1 = 4*x1**2 + 4*x2**2
f2 = (x1 - 5)**2 + (x2 - 5)**2
# 采用可行性法則處理約束
pop.CV = np.hstack([(x1 - 5)**2 + x2**2 - 25,-(x1 - 8)**2 - (x2 - 3)**2 + 7.7])
# 把求得的目標(biāo)函數(shù)值賦值給種群pop的ObjV
pop.ObjV = np.hstack([f1, f2])
## 目標(biāo)函數(shù)主要需要計(jì)算出CV和ObjV
4.2 調(diào)用算法模板進(jìn)行求解
模板求解,和單目標(biāo)規(guī)劃類似。
import geatpy as ea # import geatpy
from ga_more_aim import MyProblem # 導(dǎo)入自定義問題接口
import numpy as np
"""=======================實(shí)例化問題對(duì)象==========================="""
problem = MyProblem() # 實(shí)例化問題對(duì)象
"""=========================種群設(shè)置=============================="""
Encoding = 'RI' # 編碼方式
NIND = 100 # 種群規(guī)模
Field = ea.crtfld(Encoding, problem.varTypes, problem.ranges,problem.borders) # 創(chuàng)建區(qū)域描述器
population = ea.Population(Encoding, Field, NIND) # 實(shí)例化種群對(duì)象(此時(shí)種群還沒被真正初始化,僅僅是生成一個(gè)種群對(duì)象)
"""=========================算法參數(shù)設(shè)置============================"""
myAlgorithm = ea.moea_NSGA2_templet(problem, population) # 實(shí)例化一個(gè)算法模板對(duì)象
myAlgorithm.mutOper.Pm = 0.2 # 修改變異算子的變異概率
myAlgorithm.recOper.XOVR = 0.9 # 修改交叉算子的交叉概率
myAlgorithm.MAXGEN = 200 # 最大進(jìn)化代數(shù)
myAlgorithm.logTras = 1 # 設(shè)置每多少代記錄日志,若設(shè)置成0則表示不記錄日志
myAlgorithm.verbose = False # 設(shè)置是否打印輸出日志信息
myAlgorithm.drawing = 1 # 設(shè)置繪圖方式(0:不繪圖;1:繪制結(jié)果圖;2:繪制目標(biāo)空間過程動(dòng)畫;3:繪制決策空間過程動(dòng)畫)
"""==========================調(diào)用算法模板進(jìn)行種群進(jìn)化==============
調(diào)用run執(zhí)行算法模板,得到帕累托最優(yōu)解集NDSet以及最后一代種群。
NDSet是一個(gè)種群類Population的對(duì)象。
NDSet.ObjV為最優(yōu)解個(gè)體的目標(biāo)函數(shù)值;NDSet.Phen為對(duì)應(yīng)的決策變量值。
詳見Population.py中關(guān)于種群類的定義。
"""
[NDSet, population] = myAlgorithm.run() # 執(zhí)行算法模板,得到非支配種群以及最后一代種群
NDSet.save() # 把非支配種群的信息保存到文件中
"""===========================輸出結(jié)果========================"""
print('用時(shí):%s 秒' % myAlgorithm.passTime)
print('非支配個(gè)體數(shù):%d 個(gè)' % NDSet.sizes) if NDSet.sizes != 0 else print('沒有找到可行解!')
if myAlgorithm.log is not None and NDSet.sizes != 0:
print('GD', myAlgorithm.log['gd'][-1])
print('IGD', myAlgorithm.log['igd'][-1])
print('HV', myAlgorithm.log['hv'][-1])
print('Spacing', myAlgorithm.log['spacing'][-1])
"""======================進(jìn)化過程指標(biāo)追蹤分析=================="""
metricName = [['igd'], ['hv']]
Metrics = np.array([myAlgorithm.log[metricName[i][0]] for i in range(len(metricName))]).T
# 繪制指標(biāo)追蹤分析圖
ea.trcplot(Metrics, labels=metricName, titles=metricName)
4.3 結(jié)果
很多初學(xué)者可能不太清楚評(píng)價(jià)多目標(biāo)規(guī)劃的一些指標(biāo)GD、IGD、HV等,這里給大家參考: 多目標(biāo)進(jìn)化算法的性能評(píng)價(jià)指標(biāo)總結(jié).
帕累托前沿結(jié)果:

hv的趨勢(shì):

最后結(jié)果:

5. 參考資料
geatpy官網(wǎng)教程: https://geatpy.com.
多目標(biāo)規(guī)劃評(píng)價(jià)指標(biāo): 多目標(biāo)進(jìn)化算法的性能評(píng)價(jià)指標(biāo)總結(jié).
到此這篇關(guān)于python遺傳算法之單/多目標(biāo)規(guī)劃問題的文章就介紹到這了,更多相關(guān)python 單/多目標(biāo)規(guī)劃 內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python matplotlib超詳細(xì)教程實(shí)現(xiàn)圖形繪制
matplotlib 模塊不僅提供了繪制統(tǒng)計(jì)圖表的功能,還支持繪制圓形、正方形、矩形等各種圖形。這篇文章主要為大家詳細(xì)介紹了利用matplotlib.patches 繪制一些基本圖形,快來跟隨小編一起學(xué)習(xí)吧2021-12-12
python 逆向爬蟲正確調(diào)用 JAR 加密邏輯
這篇文章主要介紹了python 逆向爬蟲正確調(diào)用 JAR 加密邏輯,幫助大家更好的理解和使用python,感興趣的朋友可以了解下2021-01-01
Python爬蟲實(shí)例扒取2345天氣預(yù)報(bào)
本篇文章給大家詳細(xì)分析了通過Python爬蟲如何采集到2345的天氣預(yù)報(bào)信息,有興趣的朋友參考學(xué)習(xí)下吧。2018-03-03
python網(wǎng)絡(luò)編程socket實(shí)現(xiàn)服務(wù)端、客戶端操作詳解
這篇文章主要介紹了python網(wǎng)絡(luò)編程socket實(shí)現(xiàn)服務(wù)端、客戶端操作,結(jié)合實(shí)例形式分析了python基于socket實(shí)現(xiàn)服務(wù)端、客戶端相關(guān)操作技巧與使用注意事項(xiàng),需要的朋友可以參考下2020-03-03
十個(gè)常見的Python腳本詳細(xì)介紹及代碼舉例
這篇文章主要給大家介紹了十個(gè)常見的Python腳本的相關(guān)資料,包括批量重命名文件、下載網(wǎng)頁(yè)圖片、發(fā)送郵件通知、讀取和寫入CSV文件、爬取網(wǎng)頁(yè)數(shù)據(jù)、自動(dòng)化測(cè)試、圖像處理、數(shù)據(jù)可視化以及創(chuàng)建簡(jiǎn)單的Web應(yīng)用,需要的朋友可以參考下2024-11-11
python隨機(jī)種子ranrandom seed的使用
本文介紹了在Python中設(shè)置隨機(jī)種子random seed的方法,可以使用seed()函數(shù)設(shè)置隨機(jī)種子,確保你的隨機(jī)數(shù)生成過程是可重復(fù)的,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-12-12

