engine.vns
变邻域搜索求解器(VNS),集成多种邻域算子和自适应权重机制。
Attributes
Classes
变邻域搜索求解器(Variable Neighborhood Search)。 |
Functions
|
Numba JIT 编译的适应度计算内核。 |
Module Contents
- engine.vns.VNS_DEFAULT_PARAMS
- engine.vns.EARLY_EXPLORE_RATIO = 0.3
- engine.vns.VIOLATOR_TARGET_PROB = 0.6
- engine.vns.DYNAMIC_STRENGTHEN_AFTER = 10
- engine.vns.WEIGHT_REWARD_FACTOR = 1.02
- engine.vns._cal_fitness_numba(line: numpy.ndarray, cost_mat: numpy.ndarray, travel_speed: float, penalty_weight: float, early_wait_weight: float, late_return_weight: float, depot_index: int, spots_start: numpy.ndarray, spots_end: numpy.ndarray, spots_stay: numpy.ndarray, use_real_time_matrix: bool = False) Tuple[float, float, float]
Numba JIT 编译的适应度计算内核。
沿路径逐段模拟行程,累计总成本与时间惩罚。 路径必须从 depot 出发并回到 depot,长度不足 3 时返回极大惩罚值。
两种矩阵模式: - use_real_time_matrix=False(默认,标准数据集):矩阵元素为距离,travel_time = d / travel_speed - use_real_time_matrix=True(高德真实数据):矩阵元素为旅行时间(小时),travel_time = d
- Args:
line: 路径数组(含起终点的完整路径)。 cost_mat: 距离/旅行时间矩阵。 travel_speed: 旅行速度(距离/时间单位)。use_real_time_matrix=True 时该参数无效。 penalty_weight: 迟到惩罚权重。 early_wait_weight: 早到等待惩罚权重。 late_return_weight: 晚归惩罚权重。 depot_index: 起终点索引。 spots_start: 各景点时间窗开始时间数组。 spots_end: 各景点时间窗结束时间数组。 spots_stay: 各景点停留时长数组。 use_real_time_matrix: 矩阵是否为旅行时间(避免 d / travel_speed 重复计算)。
- Returns:
- Tuple[float, float, float]: (总成本, 旅行累积值, 时间惩罚).
旅行累积值:标准模式下为总距离,真实模式下为总旅行时间。
- class engine.vns.VNSSolver(city_indices: list[int], spots_dict: dict[int, backend.typedefs.SpotDict], travel_speed: float = 1.0, penalty_weight: float = 100.0, early_wait_weight: float = 0.1, late_return_weight: float = 50.0, depot_index: int = 0, use_real_time_matrix: bool = False, **kwargs)
变邻域搜索求解器(Variable Neighborhood Search)。
集成多种邻域结构(swap/inversion/insert/2opt)与 VND 局部搜索, 通过 SA 准则控制扰动接受,并维护精英池保留历史最优解。
增强特性: - SA 混合接受准则:改善解直接接受,劣化解按概率接受(避免陷入局部最优) - 压缩退火:penalty 权重从 0.1 线性增长至 1.0(早期允许探索不可行区域,后期收敛到可行解) - 早期定向约束扰动:迭代前期针对违规时间窗的节点执行针对性扰动(加速可行解发现) - 自适应算子权重:根据历史成功率动态调节各邻域算子的被选中概率(加速收敛) - 精英池后优化:主循环结束后对精英池中的多组候选解执行 VND,提升最终解稳定性
- city_indices
- num_cities
- spots_dict
- travel_speed = 1.0
- penalty_weight = 100.0
- early_wait_weight = 0.1
- late_return_weight = 50.0
- depot_index = 0
- use_real_time_matrix = False
- params
- spots_start
- spots_end
- spots_stay
- fitness_cache
- elite_pool = []
- operator_weights
- last_operator: str | None = None
- _cal_fitness(line: list[int], cost_mat: numpy.ndarray) Tuple[float, float, float]
带缓存的适应度计算,避免重复触发 Numba 调用的开销
- Args:
line: 路径列表(含起终点的完整路径)。 cost_mat: 距离/旅行时间矩阵。
- Returns:
Tuple[float, float, float]: (总成本, 旅行累积值, 时间惩罚).
- _init_nearest_neighbor(cost_mat: numpy.ndarray) list[int]
最近邻贪心初始解:从未访问节点中选成本最小的加入路径。
- _init_time_window() list[int]
按时间窗起始排序生成初始解(启发式,起终点闭合路径)。
- _init_random() list[int]
随机排列初始解:提供种群多样性,防止陷入局部最优。
- _swap(route: list[int]) list[int]
Swap 算子:随机交换两个内部节点,改变路径结构。
- Args:
route: 当前路径。
- Returns:
List[int]: 扰动后的路径。
- _inversion(route: list[int]) list[int]
Inversion 算子:反转内部一段子序列,改变路径拓扑。
- Args:
route: 当前路径。
- Returns:
List[int]: 扰动后的路径。
- _insert(route: list[int]) list[int]
Insert 算子:随机删除一个节点并插入到另一位置,改变路径结构。
- Args:
route: 当前路径。
- Returns:
List[int]: 扰动后的路径。
- _2opt(route: list[int]) list[int]
2-opt 算子:反转内部两个切割点之间的子序列,消除路径交叉。
- Args:
route: 当前路径。
- Returns:
List[int]: 扰动后的路径。
- _shaking(solution, k, cost_mat, iter_ratio=0.5)
执行 k 步抖动。
搜索早期优先对违反时间窗的节点做针对性扰动, 后期退化到随机算子 + 自适应权重。
- Args:
solution: 当前解路径。 k: 抖动步数。 cost_mat: 距离矩阵。 iter_ratio: 当前迭代进度比例(0~1)。
- Returns:
Tuple[List[int], str | None]: (抖动后的解, 最后使用的算子名称).
- _perturb_around(route, target, op)
针对特定节点进行扰动(对其附近片段操作)
- Args:
route: 当前路径。 target: 目标节点索引。 op (str): 使用的扰动算子,可选 'swap'/'inversion'/'insert'。
- Returns:
List[int]: 扰动后的路径。
- _local_search(solution, cost_mat, move_type)
指定邻域类型的第一改善型局部搜索。
遍历所有合法操作对,找到第一个改善即返回(First Improvement)。
- Args:
solution: 当前解路径。 cost_mat: 距离矩阵。 move_type (str): 邻域类型,可选 'swap'/'inversion'/'insert'/'2opt'。
- Returns:
List[int]: 局部搜索后的路径。
- _vnd(solution, cost_mat)
变邻域下降(Variable Neighborhood Descent)。
依次尝试 swap → inversion → insert → 2opt, 任一邻域改善则回到第一个邻域重新搜索。
- Args:
solution: 当前解路径。 cost_mat: 距离矩阵。
- Returns:
List[int]: VND 优化后的路径。
- _update_elite(solution, cost)
将解加入精英池,超出容量时替换最差者。
- Args:
solution: 当前解路径。 cost: 当前解成本。
- get_elite_pool()
返回精英池((解, 成本) 列表)
- solve(cost_mat, initial_solution=None)
执行 VNS 主循环。
- Args:
cost_mat: 距离矩阵。 initial_solution: 可选的初始解,None 则自动择优选取。
- Returns:
- dict: 包含以下键:
best_solution (List[int]): 最优路径(含起终点)。
best_cost (float): 最优总成本(旅行累积值 + 时间惩罚,单位由输入矩阵决定)。
best_distance (float): 旅行累积值。标准模式 = 总距离;真实模式 = 总旅行时间。
best_penalty (float): 最优路径总时间惩罚。
convergence_history (List[float]): 收敛曲线,每轮迭代后的最优成本。