遺傳算法| Python Geatpy庫 1 Geatpy庫的由來 2 Geatpy庫的用途 3 Geatpy庫的案例 4 參考

1 Geatpy庫的由來

由華南農業大學、暨南大學、華南理工大學等一批大佬們研發的超高性能、通用性強、能夠輕鬆應用到實際工程項目之中的、能讓用戶快速上手進化算法的工具箱(遺傳算法工具箱),詳情見官網http://geatpy.com/index.php/home/

2 Geatpy庫的用途

Geatpy 是一個高性能實用型進化算法工具箱,提供了許多已實現的進化算法各項操作的函數,如初始化種羣、選擇、交叉、變異、多目標優化參考點生成、非支配排序、多目標優化 GD、IGD、HV 等指標的計算等等。

3 Geatpy庫的案例

3.1 帶約束的單目標優化問題

3.1.1 Python程序

問題描述程序
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)])   # 第1.2.3個約束
主程序
import numpy as np
import geatpy as ea
from MyProblem 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                                         # 設置差分進化的變異縮放因子
myAlgorithm.recOper.XOVR = 0.5                                      # 設置交叉概率
myAlgorithm.drawing = 1                                             # 設置繪圖方式

"""=====================調用算法模板進行種羣進化====================="""
[population, obj_trace, var_trace] = myAlgorithm.run()              # 執行算法模板 # 輸出結果
best_gen = np.argmax(obj_trace[:, 1])                               # 記錄最優種羣是在哪一代
best_ObjV = obj_trace[best_gen, 1]
print('最優的目標函數值爲:%s'%(best_ObjV))
print('最優的決策變量值爲:')
for i in range(var_trace.shape[1]):
    print(var_trace[best_gen, i])
print('有效進化代數:%s'%(obj_trace.shape[0]))
print('最優的一代是第 %s 代'%(best_gen + 1))
print('評價次數:%s'%(myAlgorithm.evalsNum))
print('時間已過 %s 秒'%(myAlgorithm.passTime))


3.2 帶約束的多目標優化問題

3.2.1 Python程序

問題描述程序
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]]
        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])

    def calBest(self):                                  # 計算全局最優解
        N = 10000                                       # 欲得到10000個真實前沿點
        x1 = np.linspace(0, 5, N)
        x2 = x1.copy()
        x2[x1 >= 3] = 3
        return np.vstack((4 * x1**2 + 4 * x2**2, (x1 - 5)**2 + (x2 - 5)**2)).T
主程序
import geatpy as ea                 # import geatpy
from MyProblem import MyProblem     # 導入自定義問題接口

"""=========================實例化問題對象==========================="""
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.MAXGEN = 200            # 最大遺傳代數
myAlgorithm.drawing = 1             # 設置繪圖方式

"""===================調用算法模板進行種羣進化=======================
調用run執行算法模板,得到帕累托最優解集NDSet。
NDSet是一個種羣類Population的對象。
NDSet.ObjV爲最優解個體的目標函數值;NDSet.Phen爲對應的決策變量值。
詳見Population.py中關於種羣類的定義。
"""
NDSet = myAlgorithm.run()           # 執行算法模板,得到非支配種羣
NDSet.save()                        # 把結果保存到文件中 # 輸出
print('用時:%f 秒'%(myAlgorithm.passTime))
print('評價次數:%d 次'%(myAlgorithm.evalsNum))
print('非支配個體數:%d 個'%(NDSet.sizes))
print('單位時間找到帕累託前沿點個數:%d 個'%(int(NDSet.sizes // myAlgorithm.passTime)))
# 計算指標
PF = problem.getBest()              # 獲取真實前沿
if PF is not None and NDSet.sizes != 0:
    GD = ea.indicator.GD(NDSet.ObjV, PF) # 計算GD指標
    IGD = ea.indicator.IGD(NDSet.ObjV, PF) # 計算IGD指標
    HV = ea.indicator.HV(NDSet.ObjV, PF) # 計算HV指標
    Spacing = ea.indicator.Spacing(NDSet.ObjV) # 計算Spacing指標
    print('GD: %f'%GD)
    print('IGD: %f'%IGD)
    print('HV: %f'%HV)
    print('Spacing: %f'%Spacing)

"""=====================進化過程指標追蹤分析========================"""
if PF is not None:
    metricName = [['IGD'], ['HV']]
    [NDSet_trace, Metrics] = ea.indicator.moea_tracking(myAlgorithm.pop_trace, PF, metricName, problem.maxormins)
    # 繪製指標追蹤分析圖
    ea.trcplot(Metrics, labels = metricName, titles=metricName)

4 參考

本文爲學習筆記,參考網站爲Geatpy官網,網址如下。
首頁:http://geatpy.com/index.php/home/
文檔:http://geatpy.com/index.php/details/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章