網站首頁 編程語言 正文
在上一篇博客中,我們學習了python遺傳算法包geatpy。并用它展示了一個不帶約束的單目標規劃問題,對往期內容感興趣的同學可以參考??:
鏈接: python遺傳算法之geatpy學習.
在上一期的介紹中,我們用遺傳算法求解時,采用的是類似matlab式的非面向對象編程,導致每一步寫的都很繁瑣,今天我們采用面向對象編程的方式來簡化求解過程。
1. 運行環境
這里先介紹一下運行環境
- 系統:Windows10
- 配置:i7-6700 16G
- python版本:3.10
- geatpy版本:2.7.0
2. 面向對象的原理
前面的章節中,我們介紹了遺傳算法主要分為算法模板類 (Algorithm)、種群類 (Population)、多染色體混合編碼種群類 (PsyPopulation) 以及問題類 (Problem)。其中 Population 類和 PsyPopulation 類是可以直接被實例化成對象去來使用的類;Algorithm 類和 Problem 類是父類,需要實例化其子類來使用。下面我們通過案例來演示一下用法。
3. 帶約束的單目標優化問題
3.1 繼承 Problem 問題類完成對問題模型的描述
在這一步中,主要是將我們的問題按照模板描述清楚,包括目標函數和約束條件。
import numpy as np
import geatpy as ea
class MyProblem(ea.Problem): # 繼承Problem父類
def __init__(self):
name = 'MyProblem' # 初始化name(函數名稱,可以隨意設置)
M = 1 # 初始化M(目標維數)
maxormins = [-1] # 初始化目標最小最大化標記列表,1:min;-1:max
Dim = 3 # 初始化Dim(決策變量維數)
varTypes = [0] * Dim # 初始化決策變量類型,0:連續;1:離散
lb = [0, 0, 0] # 決策變量下界
ub = [1, 1, 2] # 決策變量上界
lbin = [1, 1, 0] # 決策變量下邊界
ubin = [1, 1, 0] # 決策變量上邊界
# 調用父類構造方法完成實例化
ea.Problem.__init__(self, name, M, maxormins, Dim, varTypes, lb,
ub, lbin, ubin)
def aimFunc(self, pop): # 目標函數,pop為傳入的種群對象
Vars = pop.Phen # 得到決策變量矩陣
x1 = Vars[:, [0]] # 取出第一列得到所有個體的x1組成的列向量
x2 = Vars[:, [1]] # 取出第二列得到所有個體的x2組成的列向量
x3 = Vars[:, [2]] # 取出第三列得到所有個體的x3組成的列向量 # 計算目標函數值,賦值給pop種群對象的ObjV屬性
pop.ObjV = 4 * x1 + 2 * x2 + x3
# 采用可行性法則處理約束,生成種群個體違反約束程度矩陣
pop.CV = np.hstack([2 * x1 + x2 - 1, # 第一個約束
x1 + 2 * x3 - 2, # 第二個約束
np.abs(x1 + x2 + x3 - 1)]) # 第三個約束
3.2 調用算法模板進行求解
在第二步中,我們主要編寫的是算法模板對第一步中問題的定義進行求解,這里需要依次設置種群、算法參數、種群進化、結果的輸出。
"""main_solve.py"""
import geatpy as ea # import geatpy
from myaim import MyProblem # 導入自定義問題接口
"""============================實例化問題對象========================"""
problem = MyProblem() # 實例化問題對象
"""==============================種群設置==========================="""
Encoding = 'RI' # 編碼方式
NIND = 50 # 種群規模
Field = ea.crtfld(Encoding, problem.varTypes, problem.ranges,problem.borders) # 創建區域描述器
population = ea.Population(Encoding, Field, NIND) # 實例化種群對象(此時種群還沒被真正初始化,僅僅是生成一個種群對象)
"""===========================算法參數設置=========================="""
myAlgorithm = ea.soea_DE_best_1_L_templet(problem, population) # 實例化一個算法模板對象
myAlgorithm.MAXGEN = 1000 # 最大進化代數
myAlgorithm.mutOper.F = 0.5 # 差分進化中的參數F
myAlgorithm.recOper.XOVR = 0.7 # 設置交叉概率
myAlgorithm.logTras = 1 # 設置每隔多少代記錄日志,若設置成0則表示不記錄日志
myAlgorithm.verbose = True # 設置是否打印輸出日志信息
myAlgorithm.drawing = 1 # 設置繪圖方式(0:不繪圖;1:繪制結果圖;2:繪制目標空間過程動畫;3:繪制決策空間過程動畫)
"""==========================調用算法模板進行種群進化==============="""
[BestIndi, population] = myAlgorithm.run() # 執行算法模板,得到最優個體以及最后一代種群
BestIndi.save() # 把最優個體的信息保存到文件中
"""=================================輸出結果======================="""
print('評價次數:%s' % myAlgorithm.evalsNum)
print('時間花費 %s 秒' % myAlgorithm.passTime)
if BestIndi.sizes != 0:
print('最優的目標函數值為:%s' % BestIndi.ObjV[0][0])
print('最優的控制變量值為:')
for i in range(BestIndi.Phen.shape[1]):
print(BestIndi.Phen[0, i])
else:
print('此次未找到可行解。')
3.3 結果
種群進化的結果為:
最終的結果為:
4. 帶約束的多目標優化問題
4.1 繼承 Problem 問題類完成對問題模型的描述
對于多目標的問題,依舊是先編寫目標規劃問題。
import numpy as np
import geatpy as ea
class MyProblem(ea.Problem): # 繼承Problem父類
def __init__(self):
name = 'BNH' # 初始化name(函數名稱,可以隨意設置)
M = 2 # 初始化M(目標維數)
maxormins = [1] * M # 初始化maxormins
Dim = 2 # 初始化Dim(決策變量維數)
varTypes = [0] * Dim # 初始化varTypes(決策變量的類型,0:實數;1:整數)
lb = [0] * Dim # 決策變量下界
ub = [5, 3] # 決策變量上界
lbin = [1] * Dim # 決策變量下邊界
ubin = [1] * Dim # 決策變量上邊界 # 調用父類構造方法完成實例化
ea.Problem.__init__(self, name, M, maxormins, Dim, varTypes, lb,ub, lbin, ubin)
def aimFunc(self, pop): # 目標函數
Vars = pop.Phen # 得到決策變量矩陣
x1 = Vars[:, [0]] # 注意這樣得到的x1是一個列向量,表示所有個體的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])
# 把求得的目標函數值賦值給種群pop的ObjV
pop.ObjV = np.hstack([f1, f2])
## 目標函數主要需要計算出CV和ObjV
4.2 調用算法模板進行求解
模板求解,和單目標規劃類似。
import geatpy as ea # import geatpy
from ga_more_aim import MyProblem # 導入自定義問題接口
import numpy as np
"""=======================實例化問題對象==========================="""
problem = MyProblem() # 實例化問題對象
"""=========================種群設置=============================="""
Encoding = 'RI' # 編碼方式
NIND = 100 # 種群規模
Field = ea.crtfld(Encoding, problem.varTypes, problem.ranges,problem.borders) # 創建區域描述器
population = ea.Population(Encoding, Field, NIND) # 實例化種群對象(此時種群還沒被真正初始化,僅僅是生成一個種群對象)
"""=========================算法參數設置============================"""
myAlgorithm = ea.moea_NSGA2_templet(problem, population) # 實例化一個算法模板對象
myAlgorithm.mutOper.Pm = 0.2 # 修改變異算子的變異概率
myAlgorithm.recOper.XOVR = 0.9 # 修改交叉算子的交叉概率
myAlgorithm.MAXGEN = 200 # 最大進化代數
myAlgorithm.logTras = 1 # 設置每多少代記錄日志,若設置成0則表示不記錄日志
myAlgorithm.verbose = False # 設置是否打印輸出日志信息
myAlgorithm.drawing = 1 # 設置繪圖方式(0:不繪圖;1:繪制結果圖;2:繪制目標空間過程動畫;3:繪制決策空間過程動畫)
"""==========================調用算法模板進行種群進化==============
調用run執行算法模板,得到帕累托最優解集NDSet以及最后一代種群。
NDSet是一個種群類Population的對象。
NDSet.ObjV為最優解個體的目標函數值;NDSet.Phen為對應的決策變量值。
詳見Population.py中關于種群類的定義。
"""
[NDSet, population] = myAlgorithm.run() # 執行算法模板,得到非支配種群以及最后一代種群
NDSet.save() # 把非支配種群的信息保存到文件中
"""===========================輸出結果========================"""
print('用時:%s 秒' % myAlgorithm.passTime)
print('非支配個體數:%d 個' % 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])
"""======================進化過程指標追蹤分析=================="""
metricName = [['igd'], ['hv']]
Metrics = np.array([myAlgorithm.log[metricName[i][0]] for i in range(len(metricName))]).T
# 繪制指標追蹤分析圖
ea.trcplot(Metrics, labels=metricName, titles=metricName)
4.3 結果
很多初學者可能不太清楚評價多目標規劃的一些指標GD、IGD、HV等,這里給大家參考: 多目標進化算法的性能評價指標總結.
帕累托前沿結果:
hv的趨勢:
最后結果:
5. 參考資料
geatpy官網教程: https://geatpy.com.
多目標規劃評價指標: 多目標進化算法的性能評價指標總結.
原文鏈接:https://blog.csdn.net/weixin_48077303/article/details/124212333
相關推薦
- 2022-11-09 ASP.NET?MVC視圖頁使用jQuery傳遞異步數據的幾種方式詳解_實用技巧
- 2022-09-06 C語言模擬實現strstr函數的示例代碼_C 語言
- 2022-04-16 Django中外鍵ForeignKey介紹使用_python
- 2022-12-10 React?useCallback詳細使用教程_React
- 2022-03-28 .Net?Core依賴注入IOC和DI介紹_實用技巧
- 2022-02-12 Flutter項目中有些依賴不支持64位的library的解決方式
- 2022-12-04 WxPython界面如何用pubsub展示進程工作的進度條_python
- 2022-11-20 C#?崩潰異常中研究頁堆布局的詳細過程_C#教程
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支