首頁  >  文章  >  後端開發  >  簡單介紹Python遺傳演算法Geatpy工具箱

簡單介紹Python遺傳演算法Geatpy工具箱

WBOY
WBOY轉載
2022-09-09 13:38:562347瀏覽

【相關推薦:Python3影片教學

一、 什麼是遺傳演算法?

遺傳演算法是模擬生物遺傳學和自然選擇機理,透過人工方式所建構的一類搜尋演算法,從某種程度上說遺傳演算法是對生物演化過程的數學方式模擬。生物族群的生存過程普遍遵循達爾文進化準則,群體中的個體根據對環境的適應能力而被大自然所選擇或淘汰。演化過程的結果反映在個體的結構上,其染色體包含若干基因,相應的表現型和基因型的連結反映了個體的外在特性與內在機理間邏輯關係。透過個體之間的交叉、變異來適應大自然環境。生物染色體用數學方式或電腦方式來體現就是一串數碼,仍叫染色體,有時也叫個體;適應能力是對應著一個染色體的一個數值來衡量;染色體的選擇或淘汰則按所面對的問題是求最大還是最小來進行。

#二、遺傳演算法庫Geatpy

2.1 遺傳演算法工具箱Geatpy參數介紹

# API官方參考文件

population參數【重要屬性:Chrom,Phen,Objv,CV,FitnV】

  • sizes : int - 族群規模,即族群的個體數目。
  • ChromNum : int - 染色體的數目,即每個個體有多少染色體。
  • Encoding : str - 染色體編碼方式, 'BG':二進位/格雷編碼; 'RI':實整數編碼,即實數和整數的混合編碼; 'P':排列編碼
  • #Field : array - 譯碼矩陣
  • Chrom : array - 族群染色體矩陣,每一行對應一個個體的一條染色體。
  • Lind : int - 族群染色體長度。
  • ObjV : array - 族群目標函數值矩陣,每一行對應一個個體的目標函數值,每一列對應一個目標
  • FitnV : array - 族群個體適應度列向量,每個元素對應一個個體的適應度,最小適應度為0
  • CV : array - CV(Constraint Violation Value)是用來定量描述違反約束條件程度的矩陣,每行對應一個個體,每列對應一個限制條件
  • Phen : array - 族群表現型矩陣(即族群各染色體解碼後所代表的決策變數所組成的矩陣)。
  • 如果透過CV矩陣基於可行性法則進行約束的設置,那麼不等式限制需要≤,等式限制需要傳入abs( ) (因為遵循值越大,適應度越小的原則)

  • ea.Problem.init()中的lbin與ubin(決策變數範圍邊界矩陣)表示範圍區間的開閉,1閉合0開區間

#Geatpy 結果參數介紹

success: True or False, 表示演算法是否成功求解。

stopMsg: 儲存著演算法停止原因的字串。

optPop: 儲存演算法求解結果的族群物件。如果無可行解,則optPop.sizes=0。 optPop.Phen為決策變數矩陣,optPop.ObjV為目標函數值矩陣。

lastPop: 演算法演化結束後的最後一代族群物件。

Vars: 等於optPop.Phen,此處即最優解。若無可行解,則Vars=None。

ObjV: 等於optPop.ObjV,此處為最優解對應的目標函數值。若無可行解,ObjV=None。

CV: 等於optPop.CV,此處即最優解對應的違反約束程度矩陣。若無可行解,CV=None。

startTime: 程式執行開始時間。

endTime: 程式執行結束時間。

executeTime: 演算法 所用時間。

nfev: 演算法評價次數

gd: (多目標最佳化且給定了理論最優解時才有) GD指標值。

igd: (多目標最佳化且給定了理論最優解時才有) IGD指標值。

hv: (多目標最佳化才有) HV指標值。

spacing: (多目標最佳化才有) Spacing指標值。

三、最佳實務

3.1 程式碼範例| 參數範本

解集:

header_regex = '|'.join(['{}'] * len(headers))
header_str = header_regex.format(*[str(key).center(width) for key, width in zip(headers, widths)])
print("=" * len(header_str))
            print(header_str)
            print("-" * len(header_str))

gen: 演化代數     
eval:記錄評估次數       
f\_opt: 當代最優個體的目標函數值 \_max=當代種群最大函數值         
f\_min 最小  f\_avg : 平均水平         
f\_std: 標準約束水平

3.2 最佳實踐

使用geatpy函式庫求解有向無環圖最短路

程式碼【最短路】一:使用geatpy函式庫

import numpy as np
import geatpy as ea
class MyProblem(ea.Problem):  # 继承Problem父类
    def __init__(self):
        name = 'Shortest_Path'  # 初始化name(函数名称,可以随意设置)
        M = 1  # 初始化M(目标维数)
        maxormins = [1]  # 初始化maxormins(目标最小最大化标记列表,1:最小化该目标;-1:最大化该目标)
        Dim = 10  # 初始化Dim(决策变量维数)
        varTypes = [1] * Dim  # 初始化varTypes(决策变量的类型,元素为0表示对应的变量是连续的;1表示是离散的)
        lb = [0] * Dim  # 决策变量下界
        ub = [9] * Dim  # 决策变量上界
        lbin = [1] * Dim  # 决策变量下边界 1表示闭合区间,0表示开区间
        ubin = [1] * Dim  # 决策变量上边界
        # 调用父类构造方法完成实例化
        ea.Problem.__init__(self, name, M, maxormins, Dim, varTypes, lb, ub, lbin, ubin)
        # 设置每一个结点下一步可达的结点(结点从1开始数,因此列表nodes的第0号元素设为空列表表示无意义)
        self.nodes = [[], [2, 3], [3, 4, 5], [5, 6], [7, 8], [4, 6], [7, 9], [8, 9], [9, 10], [10]]
        # 设置有向图中各条边的权重
        self.weights = {'(1, 2)': 36, '(1, 3)': 27, '(2, 4)': 18, '(2, 5)': 20, '(2, 3)': 13, '(3, 5)': 12,
                        '(3, 6)': 23,
                        '(4, 7)': 11, '(4, 8)': 32, '(5, 4)': 16, '(5, 6)': 30, '(6, 7)': 12, '(6, 9)': 38,
                        '(7, 8)': 20,
                        '(7, 9)': 32, '(8, 9)': 15, '(8, 10)': 24, '(9, 10)': 13}
    def decode(self, priority):  # 将优先级编码的染色体解码得到一条从节点1到节点10的可行路径
        edges = []  # 存储边
        path = [1]  # 结点1是路径起点
        while not path[-1] == 10:  # 开始从起点走到终点
            currentNode = path[-1]  # 得到当前所在的结点编号
            nextNodes = self.nodes[currentNode]  # 获取下一步可达的结点组成的列表
            chooseNode = nextNodes[np.argmax(
                priority[np.array(nextNodes) - 1])]  # 从NextNodes中选择优先级更高的结点作为下一步要访问的结点,因为结点从1数起,而下标从0数起,因此要减去1
            path.append(chooseNode)
            edges.append((currentNode, chooseNode))
        return path, edges
    def aimFunc(self, pop):  # 目标函数
        pop.ObjV = np.zeros((pop.sizes, 1))  # 初始化ObjV
        for i in range(pop.sizes):  # 遍历种群的每个个体,分别计算各个个体的目标函数值
            priority = pop.Phen[i, :]
            path, edges = self.decode(priority)  # 将优先级编码的染色体解码得到访问路径及经过的边
            pathLen = 0
            for edge in edges:
                key = str(edge)  # 根据路径得到键值,以便根据键值找到路径对应的长度
                if not key in self.weights:
                    raise RuntimeError("Error in aimFunc: The path is invalid. (当前路径是无效的。)", path)
                pathLen += self.weights[key]  # 将该段路径长度加入
            pop.ObjV[i] = pathLen  # 计算目标函数值,赋值给pop种群对象的ObjV属性
## 执行脚本
if __name__ == "__main__":
    # 实例化问题对象
    problem = MyProblem()
    # 构建算法
    algorithm = ea.soea_EGA_templet(problem,
                                    ea.Population(Encoding='RI', NIND=4),
                                    MAXGEN=10,  # 最大进化代数
                                    logTras=1)  # 表示每隔多少代记录一次日志信息
    # 求解
    res = ea.optimize(algorithm, verbose=True, drawing=1, outputMsg=False, drawLog=False, saveFlag=True,
                      dirName='result')
    print('最短路程为:%s' % (res['ObjV'][0][0]))
    print('最佳路线为:')
    best_journey, edges = problem.decode(res['Vars'][0])
    for i in range(len(best_journey)):
        print(int(best_journey[i]), end=' ')
    print()

【相關推薦:

Python3影片教學

以上是簡單介紹Python遺傳演算法Geatpy工具箱的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:jb51.net。如有侵權,請聯絡admin@php.cn刪除