自适应大邻域搜索(Adaptive Large Neighborhood Search, ALNS)
自适应大邻域搜索在大邻域搜索(Large Neighborhood Search, LNS)思路上,为多类破坏算子、多类修复算子配置可更新的权重或得分:反复「破坏当前解的一部分结构 → 再修复成新可行解」,并根据搜索过程中算子的表现自适应地调整其被选概率。适于车辆路径、调度、排料等能自然写出「拿掉若干决策再填回」的问题。见 元启发式总览。
与 LNS 的关系
大邻域搜索(LNS):一步从当前解出发,在「很大」的邻域内选下一个解,常实现为先破坏、后修复,使一次移动相当于改变解中多处分量,能跳出小邻域方法难以跳出的盆地。
ALNS 在 LNS 上的推广:不固定唯一的一对破坏+修复,而是给多组可替换算子,并用权重反映「哪组近期更有用」;与人工固定调度各算子使用频率相比,自适应性减轻手工调参负担,但仍需人设计算子与得分、冷却等规则。
记号与算子
解与目标: 为可行解, 为待优化目标;最小化叙述。
破坏与修复:设破坏算子集合 。每个 把 映为部分解/松弛解 。设修复算子集合 。每个 把在 意义下可修复的对象映回可行解 。从 与 里如何抽到一对 ,实现里定一种并写进复现说明即可,常见有:
- 先在 上按权抽 ,再在 上按权(可与 相关)抽 。
- 在乘积结构 上为各对 设权,一次抽中一对。
权重与抽样概率:为每个参与选择的实体(如每个 、或每个 、或每对 ,索引在有限集 上记为 )维护非负权 。轮盘赌下的选取概率、段末如何由段内统计重算 ,在下一节用公式写清。初值常取均匀或先验偏置,必要时混合少量均匀探索(见下)。
段:每过固定次数迭代或时间,对 再平衡并清零段内统计。段长可理解为「权重跟上算子表现」的快慢:
- 过短:方差大,权噪声重。
- 过长:对近期好坏反应慢。
接受准则、得分与段末权重
记号约定(最小化):
- :当前可行解;:试解;:历史最优, 常记 。
- :本步参与得分的实体(单个算子、算子对或你实现中的编号)。
- :若与 模拟退火 同型接受时用到的温度。
- 、:得分与段末权重用的超参数,可实验标定。
经典分档与反应更新以 Ropke 与 Pisinger(车辆路径大邻域)系文献为主干,与代码须逐项对齐。
算子(或算子对)的抽样
设非负权 。无额外探索时,轮盘赌为
若用均匀项 与均匀律 混合,可写
本步得分(Ropke–Pisinger 型四档)
记 , 常取 0 或负值;一步内按互斥条件把增量加到 的段内累计得分上(实现上也可先记入临时变量、段末再汇总)。用当前 与「是否被接受为新的当前解」区分,一种常用写法是
多目标、罚函数或给「非全局改进」单独分档时,可改为更多行的分段函数;修复失败是并入 还是单独给罚,须与本节「接受准则」及主循环中的接受判定一致。
段末对权重的反应更新
在段 中,对实体 记 为段内 之和, 为 被抽中次数。设反应因子 。一种标准递推是(当 时除法有定义;若 可令后项为 0 或只保留左端遗忘)
段末可再施加下界 或做整体比例缩放。另一种等价塑型是用 对旧权与段内平均表现作凸组合(与上式常可互化):
下一段开始将 、(及临时 )按实现清零或衰减。温度若与段同步,可写 ,。
接受准则
仅接受改进时,接受为新的当前解当且仅当
Metropolis 接受(与 模拟退火 同型)在最小化下为
记录对记录:给定与当前记录 关联的容忍 ,接受新当前解当且仅当
主循环(最小化、示意框)
下框是抽象骨架; 为最小化。抽样、得分、段末权重与 Metropolis 见上节。实现里至少定稿并写进复现说明:
- 抽 与 的次序(或是否抽成对 )。
- 分档、 或 、段长、是否配温度表与 。
- 与上节公式逐项一致。
▶ ALNS 主循环(多破坏/多修复 + 自适应权重)
1. 初始化
生成或构造可行初解 ,记 。为参与选择的每个算子或算子对设初权并归一。若使用温度式接受,设初温或等价参数。段计数器、各算子累计得分置零。设定主终止条件(时间、总迭代、无改进步数等)与段长(或按时间触发权重更新)。
2. 未满足主终止时重复
- 据当前权在 与 上抽样得破坏 与修复 (或抽一对 ,依实现),令 ,;若 不可行,按实现重试或保持 并给罚分/跳过。
- 据接受准则判断是否用 替换 ;若 则 。
- 对本轮所用 、(或 )累计得分(如:新最优/接受/拒绝 对应分档,见上节)。
- 若到段末:据累计得分更新各 (归一、遗忘、下界等按实现),得分清零或衰减,可同步降低温度。
3. 输出
输出 (及日志中的算子调用与权重曲线,若需复现)。
算子示例:以路径类问题为例
以带容量车辆路径(CVRP 等)为例:当前解是若干条访问客户的路线。ALNS 的一步是「先让破坏算子从解里拿走一些客户(暂成未服务池),再让修复算子把客户插回路线,得到新可行解」。
破坏:在完整路线里取走待重插的客户。多种破坏可并存、由权轮盘抽。常见有:
- 随机去掉若干点。
- 去掉对成本「最差」或离路线质心最远等点(worst removal)。
- 按与种子/彼此相近度成批去掉(related / Shaw)。
- 清空整条约路线(route removal)。
不必一次列全,选 2~4 种风格差异大的即可。
修复:把池中客户插回各条路线。常见有:
- 按插入边际成本贪心。
- 按后悔值(次优与最优插入位代价之差,越大越先插)定顺序与位置。
- 带时间窗时,在插入与线内顺移中保持时间窗,可用前推/后推 slack。
注:多类破坏、多类修复与上文权重轮盘、段内得分配合即可;子问题里若用小块最短路/分配,只作为修复算子内部实现。文献与实现里对 random、worst、related、regret 等名不必逐字相同,以「本步移除了什么、再按什么规则插回」理解即可。