文章目录
打数模国赛前拿来练手的题,现在题目求解思路分享给大家,包括 所有源代码
和 高清pdf论文
,希望能对大家有所帮助!
题目:快递公司送货策略
VRP问题简介
VRP问题(车辆路径问题)是一类经典的组合优化问题,其目的是在一定约束条件下(如车辆容量限制、路径长度限制等),为一组车辆分配配送任务,使得配送成本最小化。VRP问题广泛应用于物流、运输等领域。
遗传算法
遗传算法是一种模拟自然选择和遗传过程的全局搜索算法,适用于解决复杂的组合优化问题。遗传算法通过选择、交叉、变异等操作来不断迭代种群,以寻找全局最优解。对于VRP问题,遗传算法能够在复杂的解空间中进行高效的搜索,找到较优的车辆路径分配方案。
项目地址
github:遗传算法求解VRP问题
gitee:遗传算法求解VRP问题
代码说明
网上也有很多关于VRP问题的求解代码,但是我几乎没找到可以直接搬过来就能运行的。考虑到数模的需要以及大多数人的编程选择,我借鉴了网上别人的代码,自己用 matlab
再详细写了一遍。大家拿到代码后直接点击main函数,应该就能运行起来并画出相应的图解。
我使用的是
matlab 2023b
的版本,如果版本过低,我不确定是否能直接运行,建议版本高一点好
代码结构
VRP-CODE1
、VRP-CODE2
、VRP-CODE3
分别是三个问题的求解代码,其中每个文件夹都包含以下关键类:
文件名 | 说明 |
---|---|
main.m |
主函数,加载数据并调用export 进行运行 |
Export.m |
根据参数调用vrp.solve 方法,得出结果并进行数据展示 |
VRP.m |
VRP类,确定种群大小、迭代次数、选择交叉变异等操作 |
Chrom.m |
个体类,每个个体都是一个基因序列,基因序列代表一个可行解 |
其他类 |
定义车辆类(指快递员)、派送节点类、工具类等 |
求解流程举例
求解目标
一个个体的基因序列举例:
[ 1,4,3,0,2,6,0,9,8 ]
快递员1:从公司出发,去 1,4,3 号点进行派送,最后回到公司
快递员2:从公司出发,去 2,6 号点进行派送,最后回到公司
快递员3:从公司出发,去 9,8 号点进行派送,最后回到公司
0 表示分隔符,用于区分快递员的路线
可见,其实一个个体就是一个问题的可行解。我们的关键就是,如何找到一个最优的个体,作为题目的答案。
求解步骤
- 输入信息
main函数执行,刚开始读取dp.xlsx
文件,得到送货点坐标,配送量等信息 - 初始化
包括添加30个送货节点Node,若干个快递员车辆Car,并设置号配送的负载和里程约束 - 种群初始化
调用vrp.solve
函数,根据先前得到的信息,初始化1000个Chorm类的个体,这些个体都是满足送货里程,负载约束的可行解,但由于是随机生成,因此不是最优解 - 排序选择
根据定义的适应度函数fitness
,计算出每个个体的适应度值并进行排序,得到当代种群的最优解,保存到res
中 - 交叉变异
交叉
即对单个个体的基因序列进行染色体的位点交叉,如[1,2,3,0,5,6]
其中随机两个数字进行swap交换,得到1,5,3,0,2,6
变异
即对某个位点单独进行数字变换,如[1,2,3,0,5,6]
变为9,2,3,0,5,6
- 考虑到变异后大概率不满足可行解要求,收敛较慢,因此本题不采用变异操作
- 考虑到交叉后可能不是可行解,因此交叉后再对个体进行校验,校验不通过就重新换位点进行交叉,直到出现可行解为止
- 考虑到经过排序后,前一半个体较优秀,后一半个体较差,因此只对后一半个体进行交叉操作,提高收敛速度
- 更新迭代
交叉完成后,得到下一代的种群个体,再次对这一代的种群个体进行排序,得到一个最优解,这相当于模拟了种群繁衍了一代
。如此循环,每次迭代后都选取一个最优解,如果优于前一代的最优解,便更新结果res
- 结果选取
迭代超过指定次数后(比如种群繁衍50代),那么迭代停止,此时的res
就是我们求出的最优基因序列,作为本题的最终结果。此时该最优基因序列并不是理想最优解,而是我们采用遗传算法收敛逼近的结果 - 图像展示
- 在Export中得到
vrp.solve
返回的res
值后,对信息进行整合打印,输出到控制台上 - main函数得到Export 整理的结果后,调用img画图函数,得到的结果图如下所示:
- 在Export中得到
其实题目的三个问题都差不多,第二问和第三问就是在第一问的基础上,调整适应度 fitness 函数而已,关键的求解步骤就是上面所讲的那样
总结
通过遗传算法与VRP问题的结合,我们可以高效地为实际的物流和运输任务找到优化的车辆路径分配方案。
有问题的欢迎在评论区讨论,我会对代码进行修改。