1. 程式人生 > >Python遺傳演算法框架——Geatpy學習筆記(一)

Python遺傳演算法框架——Geatpy學習筆記(一)

    最近各項比賽告一段落,期間我逐漸開始接觸遺傳演算法。最近由同學推薦,我開始學習一個Python高效能遺傳演算法框架——Geatpy。它是由華工、華農、德州奧斯汀公立大學的學生組成的聯合團隊開發。

    華工的師兄目前才研二,就和志同道合的人組建團隊開發了這款實用型框架,實屬難得,打破了“幾乎所有好用的庫、框架長期都由外國人擁有”的局面。這裡點個贊!

    前幾天有幸參加師兄線上直播教學,瞭解到Geatpy的相關用法。在此作一下學習記錄。

    一. 安裝:

pip install geatpy

  直接執行上述程式碼即可。

在後面要更新時,可以執行:

pip install --upgrade geatpy

  師兄著重講了如何與Matlab銜接學習。Matlab上有比較著名的gatbx和GEATbx,Geatpy的庫函式命名風格是基本與它們相容的,因此可以輕鬆過渡到使用Python進行遺傳演算法的程式設計。我沒有用過Matlab,因此就不管這個了。

    二. Geatpy最簡單用法:

    Geatpy除了提供了遺傳和進化演算法的各種庫函式外,還提供了多種“演算法模板”來實現遺傳和進化演算法。一般在使用時直接套用即可。這裡我試了一下求多目標優化DTLZ2的帕累託前沿。因為Geatpy是支援動畫輸出的,可以觀察帕累託前沿求解的過程,不過要注意,在輸出動畫前,要在python控制檯執行以下程式碼:

matplotlib qt5

    個人十分推薦使用Anaconda3進行程式設計。它裡面的Spyder介面友好、簡單易用。

    根據Geatpy官方教程,Geatpy進行遺傳演算法程式設計時需要做以下兩步:

    1. 編寫目標函式介面檔案:

"""
aimfuc.py 多目標函式DTLZ1,2,3,4
"""

# DTLZ3
def DTLZ3(Chrom, M = 3): # M為問題維度,如2維、3維
    x = Chrom.T
    XM = x[M-1:]
    k = x.shape[0] - M + 1
    gx = 100 * (k + np.sum((XM - 0.5) ** 2 - np.cos(20 * np.pi * (XM - 0.5)), 0))
    
    ObjV = (np.array([[]]).T) * np.zeros((1, Chrom.shape[0]))
    ObjV = np.vstack([ObjV, np.cumprod((np.cos(x * np.pi / 2))[:M-1], 0)[-1] * (1 + gx)])
    for i in range(2, M):
        ObjV = np.vstack([ObjV, np.cumprod((np.cos(x * np.pi / 2))[: M-i], 0)[-1] * np.sin(x[M-i] * np.pi / 2) * (1 + gx)])
    ObjV = np.vstack([ObjV, np.sin(x[0] * np.pi / 2) * (1 + gx)])
    return ObjV.T

  2. 編寫執行指令碼:

"""main.py"""
import numpy as np
import geatpy as ga # import geatpy

AIM_M = __import__('aimfuc') # get the address of objective function
AIM_F = 'DTLZ2' # You can set DTL1,2,3 or 4

"""==================================variables setting================================"""
ranges = np.vstack([np.zeros((1,7)), np.ones((1,7))]) # define the ranges of variables in DTLZ1
borders = np.vstack([np.ones((1,7)), np.ones((1,7))]) # define the borders of variables in DTLZ1
FieldDR = ga.crtfld(ranges, borders) # create the FieldDR
"""=======================use sga2_templet to find the Pareto front==================="""
[ObjV, NDSet, NDSetObjV, times] = ga.nsga2_templet(AIM_M, AIM_F, None, None, FieldDR, problem = 'R', maxormin = 1, MAXGEN = 1000, MAXSIZE = 2000, NIND = 50, SUBPOP = 1, GGAP = 1, selectStyle = 'tour', recombinStyle = 'xovdprs', recopt = 0.9, pm = None, distribute = False, drawing = 2)

    執行上述指令碼,就可以看到帕累託前沿的求解過程:

    過程截圖1:

    過程截圖2:

    過程截圖3:

    最終執行結果:

    上述程式碼就是這麼簡潔。在上面的程式碼中,我是直接呼叫Geatpy自帶的"nsga2_templet"演算法模板的,它實現的是改進的NSGA-II演算法。其實,我還可以自定義演算法模板,來實現各種改進創新的遺傳演算法,以便相關研究工作的開展。