1 车辆路径问题
车辆路径问题的实际应用非常广泛,包括仓储物流配送、信件和报纸投递、公共汽车路线制定、工业废品收集等。车辆路径问题是经典的组合优化问题,它是指一定数量的客户,各自有不同的货物需求,由仓库向客户提供货物,由一个车队负责配送,规划适当的行车路线,使得客户的需求得到满足,并能在满足一定的约束条件下(如车辆容量约束、车辆数量约束、时间窗约束等),达到诸如距离最短、成本最小、耗费时间最少等目的。根据不同的优化目标和约束条件具有不同的数学模型。该问题的示意图1如下:
图 1 VRP问题示意图
2 局部搜索增强的大领域搜索算法设计
本文针对车辆路径问题,设计一种基于局部搜索增强的大领域搜索算法,将局部搜索与大领域搜索结合,使用了丰富的局部搜索算子和领域搜索算子,并改进了部分搜索算子,使得算法具有较强的局部搜索能力和全局搜索能力。再通过生成高质量的初始解和算子自适应选择机制加快了算法的收敛速度。并使用经典的CVRP 数据集,验证了算法的有效性。局部搜索增强的大领域搜索算法设计主要包括以下几个方面:初始解设计、领域搜索算子设计、局部搜索算子设计、变异算子设计、自适应机制设计、接受准则和加速策略。
2.1 初始解设计
一个较高质量的初始解不仅能加快算法的收敛速度还能提高算法求的解的质量,所以初始解的设计是十分重要的,在设计初始解时需要注意满足前文中数学模型的约束条件。VRP问题的解一般采用整数编码的方式来构造,例如{[0-1-3-5-7-9-n+1],[0-2-4-6-8-10-n+1],...}代表一个解,其中0和n+1表示同一个仓库,[0-1-3-5-7-9-n+1]代表一条子路线,每一条子路线由一辆车完成配送服务,且每一条子路线的客户点的总需求不得超过车辆的最大载重量。本文设计了一种根据距离和角度构造较优初始解的方法。
2.2 领域搜索算子设计
领域搜索算子包括移除和插入算子两类,其基本思想是使用移除算子来破坏解,再通过插入算子来修复解,通过设计多组移除和插入算子,提高全局搜索能力,扩大解空间搜索范围,对当前解进行改进。在破坏解的过程中会倾向于找到处在较差位置的客户点将其从子路线中移除,并在修复解的过程中为这些移除的客户点找到更合适的插入位置,因此,在迭代过程中,能对解的质量进行有效的改进。此环节使用了丰富的移除和插入算子,并对部分算子进行了改进,来提高领域搜索范围,加快算法搜索速度。具体使用的领域搜索算子如下表1所示。
表1 领域搜索算子类型及功能
算子类型 | 算子名称 | 功能 |
移除算子 | 随机移除算子 | 从当前解随机移除k个客户点 |
最差移除算子 | 将当前解中的所有客户点依次删除和放回,并记录使目标函数变小最多的客户点。依次找到k个客户点并删除 | |
改进的聚类移除算子 | 随机选择一个客户点,将与客户点角度和距离相近的k个客户点移除 | |
随机路线移除算子 | 随机选择一条子路线,将子路线中所有客户点删除 | |
插入算子 | 改进的贪婪距离插入算子 | 依次将需要插入的客户点循环放入路线中的潜在最优位置,并记录使目标函数增加最少的位置。优先将距离增加最少的客户点插入最优位置 |
改进的贪婪适应度插入算子 | 依次将需要插入的客户点循环放入线路中的潜在最优位置,并记录使适应度增加最少的位置。适应度是距离和角度的加权和,优先将适应度增加最少的客户点插入最优位置 | |
改进的后悔k插入算子 | 后悔插入对比了两个较优插入位置,计算delta cost,最大化把顾客插入到最好的中和第k好的位置中目标函数的差异 |
2.3 局部搜索算子设计
局部搜索算子可以对解的局部区域进行进一步的搜索,提高算法的局部搜索能力,该算子的基本思想是对解进行较小的改动,在局部范围对解进一步改进。此环节使用了丰富的局部搜索算子,并对部分算子进行了改进,来提高算法的局部搜索能力。具体使用的局部搜索算子如下表2所示。
表2 局部搜索算子名称及功能
算子名称 | 功能 |
Relocate算子 | 随机选择当前解方案中的一条子路线,选择该子路线中m个连续的客户点,将这m个客户点重新定位到该子路线中,形成一条新的子路线 |
Exchange 算子 | 随机选择当前解方案中的一条子路线,再随机选择该子路线中的两个客户点进行交换,形成一条新的子路线 |
2opt算子 | 随机选择当前解方案中的一条子路线,将子路线中选中的部分客户点反向访问 |
3opt算子 | 随机选择当前解方案中的一条子路线,从子路线中移除3条边,然后再新增3条边,重新将路径连接起来 |
算子名称 | 功能 |
Swap算子 | 随机选择当前解方案中的两条子路线,分别在每条子路线中选择一个客户点,交换后形成两条新的路径 |
Shift算子 | 该算子随机选择当前解方案中的两条子路线,从一条子路线中随机选择一个客户点i,将客户点i随机插入另一条子路线中,形成两条新的子路线 |
Cross-exchange | 随机选择当前解方案中的两条子路线(子路线中客户点数量要大于3),从一条子路线中移除2条边,从另一条子路线中移除2条边,然后交换上述4条边,产生新的4条边 |
改进的GENE 算子 | 随机选择当前解方案中的两条相邻的子路线,再选择一条子路线中的一个客户点,插入到另一条子路线中,且插入位置为距离该客户最近的两个客户点(这两个客户点可以不连续)之间 |
2.4 变异算子设计
为防止算法长时间陷入局部最优,在解连续超过m代未改善时,会同时使用两种变异算子,变异算子将打乱子路线的客户排列,以及打乱客户点的分配,从而来跳出局部最优。变异算子包括:Or-opt算子、Cross-exchange算子、改进的GENE算子、随机移除和插入算子,其中Cross-exchange算子和改进的GENE算子在局部搜索中已经被使用,其余使用的变异算子如下表3所示。
表3 变异算子名称及功能
算子类型 | 算子名称 | 功能 |
变异算子 | Or-opt算子 | 随机选择当前解方案中的一条子路径,选择该子路径中部分连续客户点,对客户点重新排序 |
随机移除和插入算子 | 从当前解随机移除k个客户点,并将移除的客户点随机插入解的各个位置中 |
3.5 自适应机制设计
算子使用了丰富的领域搜索算子和局部搜索算子,为了保证算法更高效,为此加入了自适应机制,使得算法可以自适应的选择表现更好的算子。各领域搜索算子和局部搜索算子初始分值设为10,当所使用的算子使得解的质量提高时,令grade=1,否则,令grade=0,再更新各算子分值,即在原分值基础上加grade,为防止在算法迭代过程中算子分值差异太大导致部分算子很少使用,在选择算子时,先对算子分值进行开平方根,再进行轮盘赌来选择算子。
3.6 接受准则
接受准则决定了在算法迭代过程中,何时可以接受一个不如当前解的新解。接受准则对于算法是十分关键的,它影响着算法的收敛速度以及最终求解的质量。本章算法中使用了两种接受准则,在经过领域搜索后得到的解使用模拟退火接受准则,在经过局部搜索后得到的解使用贪婪接受准则。
3.7加速策略
由于问题的复杂性,求解十分耗时,为加快算法收敛速度,在算法中通过构造较高质量的初始解、自适应机制和改进的部分算子来提高算法效率,前文对初始解设计和自适应机制进行了详细的介绍,现在对改进的部分算子进行介绍,算子的加速设计主要集中在插入算子,传统的插入算子,如Schneider和Kouider等所使用的贪婪插入算子和后悔插入算子,将选择池内的客户点会遍历插入所有位置,当算例的规模较大时,这个插入是十分耗时的,而本文的插入算子,会考虑选择池内客户点与子路线的客户点的空间关联性,选择潜在最优位置插入,减少了无效的位置插入次数。
3.8算法流程
图2 局部搜索增强的大领域搜索算法流程图
3 CVRP模型求解实验
此算法在Set A的27个算例中,有22个算例求解到最优解,在Set E的9个算例中5个求解到最优解,在Set P的22个算例中,有19个求解到最优解。与其它算法对比本文所提算法能有效的收敛到已知最优解,具有较好的收敛性,在稳定性方面也表现良好,并且求解速度极快。
注释:可私信代码,一起学习交流