Python遗传算法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()