文章目录

  • 一.前言
  • 二.最短路径问题描述
  • 三.最短路径问题示例
  • 三.遗传算方法求解最短路径问题
    • 1.个体编码
    • 2.代码实现

一.前言

在优化问题中,网络模型是很重要的一类问题,各种物流配送计划、供应链管理、公路网络设计等等问题都可以简化为网络模型。从这里开始,我们会进入基本网络模型,回顾最短路径、最大流量、最小费用流、最小生成树等网络模型中的基本问题。

二.最短路径问题描述

最短路径问题是在给定权的有向图或无向图中,从连接两个节点的边上寻找权数之和最小的路径的问题。

三.最短路径问题示例

示例问题如图所示:

每条边上显示该边的长度,求从节点1到节点10的最短路径

三.遗传算方法求解最短路径问题

1.个体编码

  1. 一种编码方案是使用二进制序列对边进行编码,为每条边分配一个二进制变量,为1代表选择该边加入路径,为0则代表不选择该边。但是这样的编码方式会生成大量的不可行解,相对于搜索空间,可行域极小,难以找到可行解。
  2. 一种编码方案是用优先度对节点进行编码:要想获得一条可行路径,需要从起始节点到结束节点依次将有路径连接的相邻接点放入备选解中。而每一次沿路径前进中可能会有多个节点作为下一步选择,节点的优先度就代表了在有多个选项的下一个节点中,要选择哪个节点放入备选解

2.代码实现

遗传算法操作:

  1. 个体编码-用优先度对个体进行编码
  2. 评价函数-用字典保存每条路径的长度,根据路径索引对应长度,对求得路径长度加和作为评价函数,此时为最小化问题。
  3. 育种选择:锦标赛选择
  4. 变异算法:交叉-有序交叉,突变-乱序突变
  5. 环境选择:子代完全代替父代,无精英保留
#!usr/bin/env python
# -*- coding:utf-8 _*-
"""
@author: liujie
@software: PyCharm
@file: 最短路径.py
@time: 2020/11/29 16:30
"""
import numpy as np
import matplotlib.pyplot as plt
import random
from deap import creator,tools,baseparams = {'font.family':'serif','figure.dpi':300,'savefig.dpi':300,'font.size':12,'legend.fontsize':'small'
}plt.rcParams.update(params)# 定义问题
creator.create('FitnessMin',base.Fitness,weights=(-1.0,))
creator.create('Individual',list,fitness = creator.FitnessMin)# 生成序列编码-优先级序列
gen_size = 10
toolbox = base.Toolbox()
toolbox.register('Sequence',np.random.permutation,gen_size)
# 注册个体
toolbox.register('Individual',tools.initIterate,creator.Individual,toolbox.Sequence)
# 注册种群
toolbox.register('Population',tools.initRepeat,list,toolbox.Individual)# 解码
# 存储每个节点的可行路径,用于解码
nodeDict = {'1':[2,3], '2':[3,4,5], '3':[5,6], '4':[7,8], '5':[4,6], '6':[7,9], '7':[8,9],'8':[9,10], '9':[10]}def decode(ind):# 输入一个优先度序列之后,返回一条从节点1到节点10的可行路径path = [1]while not path[-1] == 10:curNode = path[-1]  # 当前所在节点toBeSelected = nodeDict[str(curNode)]  # 获取可以到达的下一个节点列表priority = np.asarray(ind)[np.asarray(toBeSelected) - 1]  # 获取优先级,注意列表的index是0-9index= np.argmax(priority)nextNode = toBeSelected[index]path.append(nextNode)return path## 评价函数
# 存储距离矩阵,用于评价个体
costDict = {'12': 36, '13': 27, '24': 18, '25': 20, '23': 13, '35': 12, '36': 23,'47': 11, '48': 32, '54': 16, '56': 30, '67': 12, '69': 38, '78': 20,'79': 32, '89': 15, '810': 24, '910': 13}def eval(ind):# 将优先度序列转换为可行路径path = decode(ind)  # 路径:节点顺序表示pathEdge = list(zip(path[::1], path[1::1]))  # 路径:用边表示pathLen = 0for pair in pathEdge:key = str(pair[0]) + str(pair[1])if not key in costDict:raise Exception("Invalid path!", path)pathLen += costDict[key]  # 将该段路径长度加入return (pathLen),# 注册评估函数
toolbox.register('evaluate',eval)
# 注册遗传算法需要的工具
toolbox.register('select',tools.selTournament,tournsize=2)
toolbox.register('mate',tools.cxOrdered)        # 有序交叉
toolbox.register('mutate',tools.mutShuffleIndexes,indpb = 0.5)# 创建统计对象
stats = tools.Statistics(key=lambda ind : ind.fitness.values)
stats.register('avg',np.mean)
stats.register('std',np.std)
stats.register('min',np.min)
stats.register('max',np.max)# 创建日志对象
logbook = tools.Logbook()
logbook.header = 'gen','avg','std','min','max'# 遗传算法操作
pop_size = 100
N_GEN = 100
CXPB = 0.8
MUTPB = 0.2# 生成种群
pop = toolbox.Population(n = pop_size)# 评价初代种群
invalid_ind = [ind for ind in pop if not ind.fitness.valid]
fitnesses = list(map(toolbox.evaluate,invalid_ind))
for ind,fit in zip(invalid_ind,fitnesses):ind.fitness.values = fit
record = stats.compile(pop)
logbook.record(gen=0,**record)# 遗传迭代
for gen in range(1+N_GEN):# 配种选择selectTour = toolbox.select(pop,pop_size)# 复制selectInd = list(map(toolbox.clone,selectTour))# 交叉for child1,child2 in zip(selectInd[::2],selectInd[1::2]):if random.random() < CXPB:toolbox.mate(child1,child2)del child1.fitness.valuesdel child2.fitness.values# 变异for ind in selectInd:if random.random() < MUTPB:toolbox.mutate(ind)del ind.fitness.values# 对于被改变的个体,重新计算其适应度invalid_ind = [ind for ind in selectInd if not ind.fitness.valid]fitnesses = list(map(toolbox.evaluate,invalid_ind))for ind,fit in zip(invalid_ind,fitnesses):ind.fitness.values = fit# 精英育种-加速迭代combinedPop = pop + selectIndpop = tools.selBest(combinedPop,pop_size)# 记录record = stats.compile(pop)logbook.record(gen = gen,**record)print(logbook)# 输出结果
bestInd = tools.selBest(pop,1)[0]
bestFit = bestInd.fitness.values[0]
print('最优解为:',str(decode(bestInd)))
print('最短路径为:',bestFit)# 可视化
min = logbook.select('min')
avg = logbook.select('avg')
gen = logbook.select('gen')
plt.plot(gen,min,'b-',label = 'MIN_FITNESS')
plt.plot(gen,avg,'r-',label = 'AVG_FITNESS')
plt.xlabel('gen')
plt.ylabel('fitness')
plt.legend(loc = 'best')
plt.tight_layout()
plt.show()

运行结果

gen  avg     std     min max
0   119.58  13.8124 101 148
0   106.4   3.95221 101 111
1   102.87  2.50462 101 107
2   101     0       101 101
3   101     0       101 101
4   101     0       101 101
5   101     0       101 101
6   101     0       101 101
7   101     0       101 101
8   101     0       101 101
9   101     0       101 101
10  101     0       101 101
11  101     0       101 101
12  101     0       101 101
13  101     0       101 101
14  101     0       101 101
15  101     0       101 101
16  101     0       101 101
17  101     0       101 101
18  101     0       101 101
19  101     0       101 101
20  101     0       101 101
21  101     0       101 101
22  101     0       101 101
23  101     0       101 101
24  101     0       101 101
25  101     0       101 101
26  101     0       101 101
27  101     0       101 101
28  101     0       101 101
29  101     0       101 101
30  101     0       101 101
31  101     0       101 101
32  101     0       101 101
33  101     0       101 101
34  101     0       101 101
35  101     0       101 101
36  101     0       101 101
37  101     0       101 101
38  101     0       101 101
39  101     0       101 101
40  101     0       101 101
41  101     0       101 101
42  101     0       101 101
43  101     0       101 101
44  101     0       101 101
45  101     0       101 101
46  101     0       101 101
47  101     0       101 101
48  101     0       101 101
49  101     0       101 101
50  101     0       101 101
51  101     0       101 101
52  101     0       101 101
53  101     0       101 101
54  101     0       101 101
55  101     0       101 101
56  101     0       101 101
57  101     0       101 101
58  101     0       101 101
59  101     0       101 101
60  101     0       101 101
61  101     0       101 101
62  101     0       101 101
63  101     0       101 101
64  101     0       101 101
65  101     0       101 101
66  101     0       101 101
67  101     0       101 101
68  101     0       101 101
69  101     0       101 101
70  101     0       101 101
71  101     0       101 101
72  101     0       101 101
73  101     0       101 101
74  101     0       101 101
75  101     0       101 101
76  101     0       101 101
77  101     0       101 101
78  101     0       101 101
79  101     0       101 101
80  101     0       101 101
81  101     0       101 101
82  101     0       101 101
83  101     0       101 101
84  101     0       101 101
85  101     0       101 101
86  101     0       101 101
87  101     0       101 101
88  101     0       101 101
89  101     0       101 101
90  101     0       101 101
91  101     0       101 101
92  101     0       101 101
93  101     0       101 101
94  101     0       101 101
95  101     0       101 101
96  101     0       101 101
97  101     0       101 101
98  101     0       101 101
99  101     0       101 101
100 101     0       101 101
最优解为: [1, 3, 6, 9, 10]
最短路径为: 101.0

可视化

基于DEAP库的python进化算法--遗传算法实践--最短路径问题相关推荐

  1. 遗传算法 python 简书_基于DEAP库的Python进化算法从入门到入土—(二)简单遗传算法实现...

    前言 在上一篇中,我们已经介绍了如何在DEAP中实现进化算法的基本操作,在这一篇中我们试图将各个操作组装起来,用进化算法解决一个简单的一元函数寻优问题. 进化算法实例 - 一元函数寻优 问题描述与分析 ...

  2. python路线寻优_基于DEAP库的Python进化算法从入门到入土 --(四)遗传算法的改进...

    前言 前面一节我们尝试了用GA求解TSP问题,简单遗传算法总是不能很好收敛到一个较优的解,在用时和求解精度上都被贪心算法吊打.在末尾我们总结了三个可能的改进方向,这次我们想要沿着这三个方向试着改进简单 ...

  3. 基于DEAP库的Python进化算法

    https://www.jianshu.com/p/8fa044ed9267 http://geatpy.com/index.php/category/geatpy_tutorials/

  4. 基于Pyinstaller库将Python项目包括 图片打包exe方法,本人已经实践多次

    基于Pyinstaller库将Python项目包括 图片打包exe方法,本人已经实践多次 文章目录 基于Pyinstaller库将Python项目包括 图片打包exe方法,本人已经实践多次 一.前言 ...

  5. IGD+-EMOA:基于IGD+的多目标进化算法

    IGD±EMOA:基于IGD+的多目标进化算法 参考文献 <IGD±EMOA:A Multi-Objective Evolutionary Algorithm based on IGD+> ...

  6. MaOEA-IBP:带有边界保护的基于指标的多目标进化算法

    MaOEA-IBP:带有边界保护的基于指标的多目标进化算法 参考文献 <An Indicator-Based Many-Objective Evolutionary Algorithm With ...

  7. 【图像压缩】基于matlab香农熵和差分进化算法多级图像阈值图像压缩【含Matlab源码 2035期】

    一.差分进化算法简介 1 前言 在遗传.选择和变异的作用下,自然界生物体优胜劣汰,不断由低级向高级进化和发展.人们注意到,适者生存的进化规律可以模式化,从而构成一些优化算法:近年来发展的进化计算类算法 ...

  8. 进化算法--遗传算法

    遗传算法 一.能解决的问题 如果你需要解决一个问题,这个问题的每一个可能的解均可以用位串来表示,那么遗传算法就能解决这个问题. 二.术语 个体:每一个可能的解: 种群:一群个体: 基因:个体中位的一个 ...

  9. 【路径规划】基于matlab GUI多种蚁群算法栅格地图最短路径规划【含Matlab源码 650期】

    ⛄一.蚁群算法及栅格地图简介 1 蚁群算法 1.1 蚁群算法的提出 蚁群算法(ant colony optimization, ACO),又称蚂蚁算法,是一种用来寻找优化路径的机率型算法.它由Marc ...

  10. 新手题库-《Python语言程序设计》实践6

    选择题 1. 关于Python的分支结构,以下选项中描述错误的是 [ 正确答案: B] A Python中if-elif-else语句描述多分支结构 B 分支结构可以向已经执行过的语句部分跳转 C P ...

最新文章

  1. 6.SQL Server Sql语句
  2. 【datawhale 】打卡 task 01--深度学习
  3. 一个免费的网站长链接转短链接的工具
  4. C++primer 第四版6.12:练习题
  5. Linux 给Qt应用软件创建图标启动
  6. 【C语言重点难点】数据类型、常量和变量
  7. Oracle 1204 RAC failover 测试 (一)
  8. vue中使用kindeditor编辑器_vue中使用kindeditor富文本编辑器
  9. 解决啦啦外卖小程序无法生成海报推广码
  10. 分布式系统必读中文版-分布式系统模式-分享
  11. c语言实现 三角函数,小型嵌入式系统的三角函数C实现
  12. 怎么把pdf文件转换成word方法分享
  13. python sin_Python数字sin()方法
  14. oracle 系统资源正忙,oracle提示资源正忙怎么解决?oracle资源正忙解决方法
  15. pthread_cond_wait和pthread_cond_signal
  16. 妈妈的手除了像写字板还像什么呢?
  17. random用法 python_python:random用法
  18. photoshop旋转图片
  19. MATLAB(九)数值微积分
  20. 西游记中神兽谛听的能力 这款小程序也有

热门文章

  1. 设计模式(六) : 创建型模式--原型模式
  2. Altium Designer(十):极坐标
  3. (转) EF三种编程方式的区别Database first ,Model first ,code first
  4. Singleton模式的.NET实现
  5. JS--我发现,原来你是这样的JS:面向对象编程OOP[1]--(理解对象和对象属性类型)...
  6. redis、kafka、rabittMQ对比 (转)
  7. (O)JS核心:call、apply和bind
  8. Swift 3必看:新的访问控制fileprivate和open
  9. 干货分享:MySQL之化险为夷的【钻石】抢购风暴【转载】
  10. B/S----验证方式及练习