蚁群算法求解需求可拆分车辆路径问题(SDVRP)

蚁群算法求解需求可拆分车辆路径问题(SDVRP)

**作者简介:**本人擅长运筹优化建模及算法设计,包括各类车辆路径问题、生产车间调度、二三维装箱问题,熟悉CPLEX和gurobi求解器
**微信公众号:**运筹优化与学习
​​​

前言

今天给大家介绍SDVRP(split delivery vehicle routing problem,需求可拆分的车辆路径问题),同时介绍蚁群优化算法求解SDVRP。

话不多说,我们直接开始。

问题简介

传统的VRP通常假设车辆载重大于客户需求。如果车辆载重小于顾客的实际需求,就需要多辆车来服务一个顾客,由此衍生出了SDVRP。

SDVRP,即需求可拆分的车辆路径问题,是车辆路径问题的变体,它在VRP的基础之上增加了一个条件:每个顾客的需求可以拆分并分配给不同的车辆配送,而不是必须由一个车辆在一条路径中满足。

定义SDVRP在一个无向完全网络 G = ( V , E ) G=(V,E) G=(V,E),其中 V = { 0 , 1 , ⋯   , n } V=\left\{0,1,\cdots, n\right\} V={0,1,n}为所有的顶点集, E = { ( i , j ) : i , j ∈ V , i ≠ j } E=\left\{(i,j):i,j\in V, i\ne j\right\} E={(i,j):i,jV,i=j}为边集。节点 0 0 0表示配送中心,每个客户 i ∈ { 1 , 2 , ⋯   , n } i\in \left\{1,2,\cdots, n\right\} i{1,2,,n}需求为 q i q_i qi,车辆最大载重为 Q Q Q

求解思路

蚁群算法原理

(1)状态转移函数

初始状态下,每条路径上的信息素数量是相同的。同时,初始状态下,每只蚂蚁会通过随机寻找路径的方式前行,信息素释放的数量与搜索路径的目标函数值成反比。随后,搜索过程中,每只蚂蚁根据路径上残留的信息素,计算蚂蚁前往每一个节点的概率,并基于概率选择下一个访问的节点。其中,第 t t t次迭代蚂蚁 k k k从节点 i i i前往节点 j j j的概率 P i j k ( t ) P_{ij}^k(t) Pijk(t)的计算表达式如下:

表达式中, τ i j ( t ) \tau_{ij}(t) τij(t)表示第 t t t次迭代从节点 i i i前往节点 j j j残留的信息素数量, η i j ( t ) \eta_{ij}(t) ηij(t)表示节点 i i i前往节点 j j j的距离长度的倒数, J k J_k Jk表示蚂蚁 k k k还没有访问过的节点的集合。同时, a a a表示信息素因子, b b b表示启发函数因子,这两个参数为蚁群优化算法的关键参数。

(2)更新信息素

在初始状态下,每条路径的信息素数量均设置为0。在搜索过程中,部分信息素会随着时间流逝而挥发,信息素挥发快慢通过参数信息素挥发因子 c c c进行控制。信息素的更新计算表达式如下:

表达式中, Δ τ i j k \Delta \tau_{ij}^k Δτijk蚂蚁 k k k遍历过的路径总长度的倒数, τ i j ( t ) \tau_{ij}(t) τij(t)表示第 t t t次迭代从节点 i i i前往节点 j j j残留的信息素数量。

求解步骤

  1. 蚂蚁从配送中心(节点0)出发;
  2. 根据状态转移函数,选择前往的下一个节点,判断当前车辆载重是否超出;若当前节点需求量超出车辆最大载重,则进行需求拆分,同时车辆返回配送中心;
  3. 局部更新车辆走过路径的信息素;
  4. 判断车辆是否已完成所有客户配送,否则返回步骤2;
  5. 当车辆对所有客户配送完毕之后,计算所有车辆行驶的路径长度之和,对信息素进行整体更新
  6. 如果迭代次数达到最大次数要求,则算法结束,输出最短路径的总长度和最优配送路线;否则返回步骤1,继续迭代。

部分代码展示

##  主函数
def main():
    bestSolution = None
    vertices, edges, capacityLimit, demand, feromones, optimalValue = generateGraph() # 读取数据

    for i in range(iterations): 
        solutions = list()
        for _ in range(ants):
            solution = solutionOfOneAnt(vertices.copy(), edges, capacityLimit, demand.copy(), feromones)
            solutions.append((solution, rateSolution(solution, edges)))
        bestSolution = updateFeromone(feromones, solutions, bestSolution)
        print(str(i) + "/" + str(iterations) + ": " + str(bestSolution[1]), end='\r', flush=True)
    return bestSolution

小规模算例结果展示

参考文献

[1]姜婷.求解需求可拆分车辆路径问题的人工蜂群算法[J].四川理工学院学报(自然科学版),2017,30(03):6-9.

  • 26
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

eternal1995

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值