今天小编准备讲一下用禁忌搜索算法(下文简称TS)求解带时间窗的VRP问题(下文简称VRPTW)。
下面小编带大家体会TS的思想。以VRPTW为例,VRPTW的解的形式为每辆车所经过的顾客,比如说有15个顾客,并且仅需3辆车完成全部配送任务。,则解如下所示(序号代表顾客编号):
车辆1:4 2 9 10 14
车辆2:11 1 3 7 13
车辆3:15 8 6 5 12
假设当前解所有车辆行驶的总距离是100.
要用TS求这个问题,第一步是要确定禁忌表,包括禁忌表的形式以及禁忌表的长度。还是举例说明,先定义(i,k),其表示顾客i由车辆k服务,则当前解S的邻域N(S)为从当前解的任一路径中移除当前路径的任一顾客,并将该顾客插入到其他路径,当然这一系列操作必须满足时间窗约束和容量约束(PS,邻域结构有很多种形式,小编这里只给出一种最简单的邻域结构)。
下面小编先给出禁忌表的形式,初始禁忌表的禁忌长度都设为0。
表中(i,k)表示路径k中的顾客i一旦从路径k中移除,则连续L代不能插回路径k中,这里的L代就是禁忌长度。
在当前解S的邻域N(S)中,如果把顾客5从路径3中移除并插入到其他路径使总行驶距离最小,比如说添加到路径2中的3和7之间,车辆行驶总距离为95(小于初始距离100,在代码里我们不接受劣质解,小伙伴们后续可以用模拟退火继续优化代码),则需要将更新禁忌表,并且更新当前解S,也就是将5行3列的数值更新为禁忌长度。第一次更新后的解为:
车辆1:4 2 9 10 14
车辆2:11 1 3 5 7 13
车辆3:15 8 6 12
我们暂且将禁忌长度设为5(这里更新5行3列数值的含义是:不让顾客5在5次迭代内重新插回到路径3),则第一次更新后的禁忌表如下表所示:
在当前解S的邻域N(S)中,如果把顾客6从路径3中移除,并插入到其他路径使总行驶距离最小,假设插入到路径1的9和10之间,车辆行驶总距离小于上一次迭代优化后的车辆总行驶距离95,则需要将更新禁忌表,也就是将6行3列的数值更新为禁忌长度,同时将5行3列的数值减1,并更新当前解S。第二次更新后的解为:
车辆1:4 2 9 6 10 14
车辆2:11 1 3 5 7 13
车辆3:15 8 12
则第二次迭代后更新的禁忌表为如下表所示
下面我们说一种特殊情况,在当前解S的邻域N(S)中,此时如果将顾客5从路径2移除,又重新插回到路径3,很明显(5,3)是禁忌表禁止的,但是如果重新把5插回路径3后的车辆总行驶距离为90,比当前最优的95还好,那么就可以执行该操作,这就是破禁准则,执行完该操作后,需要将5行3列的数值重置为0,其余非0的数值均减1。这里小编只是举个例子,各位小伙伴不用纠结于把5重新插回3怎么可能使总距离减小。更新后的禁忌表如下表所示。
最后小编给出,TS的伪代码:
这周末小编在实验室加班,所以代码没写完,忘各位小伙伴见谅。