大规模邻域搜索算法(Large Neighborhood Search, LNS)

7 阅读3分钟

大规模邻域搜索算法(Large Neighborhood Search, LNS)简介

核心思想:通过交替执行“破坏”(Destroy)和“修复”(Repair)操作,在解空间中高效搜索。
破坏阶段:移除当前解的一部分(如随机删除若干节点)
修复阶段:以新的方式重新填充被移除的部分,生成新解接受新解后重复迭代,逐步逼近全局最优解

优势
跳出局部最优能力强
灵活性高,可适配多种组合优化问题(如TSP、VRP、调度问题) 易于与其他启发式算法结合


Python代码示例:TSP问题求解

问题描述

求解10个城市的旅行商问题(TSP),最小化总路径长度

import random
import math

# ========== 工具函数 ==========
def calculate_distance(city1, city2):
    """计算两个城市间的欧氏距离"""
    return math.sqrt((city1[0]-city2[0])2 + (city1[1]-city2[1])2)

def total_distance(path, distance_matrix):
    """计算路径总长度"""
    return sum(distance_matrix[path[i-1]][path[i]] for i in range(len(path)))

# ========== LNS核心组件 ==========
def destroy(current_solution, num_remove):
    """破坏操作:随机移除num_remove个城市"""
    destroyed = current_solution.copy()
    # 随机选择要移除的城市索引
    remove_indices = random.sample(range(len(destroyed)), num_remove)
    removed_cities = [destroyed[i] for i in remove_indices]
    # 倒序删除避免索引错位
    for i in sorted(remove_indices, reverse=True):
        del destroyed[i]
    return destroyed, removed_cities

def repair(partial_solution, removed_cities, distance_matrix):
    """修复操作:贪心插入最优位置"""
    for city in removed_cities:
        best_position = 0
        min_increase = float('inf')
        # 遍历所有可能插入位置
        for i in range(len(partial_solution)+1):
            new_path = partial_solution[:i] + [city] + partial_solution[i:]
            increase = calculate_insertion_cost(new_path, i, distance_matrix)
            if increase < min_increase:
                min_increase = increase
                best_position = i
        partial_solution.insert(best_position, city)
    return partial_solution

def calculate_insertion_cost(path, insert_index, distance_matrix):
    """计算插入新城市导致的路径长度变化"""
    if insert_index == 0:
        prev = path[-1] if len(path)>0 else path[0]
        next_node = path[0]
    elif insert_index == len(path):
        prev = path[-1]
        next_node = path[0]
    else:
        prev = path[insert_index-1]
        next_node = path[insert_index]
    new_city = path[insert_index]
    return distance_matrix[prev][new_city] + distance_matrix[new_city][next_node] \
           distance_matrix[prev][next_node]

# ========== 主算法 ==========
def lns_tsp(cities, iterations=100, num_remove=3):
    # 初始化数据
    n = len(cities)
    distance_matrix = [[calculate_distance(i,j) for j in cities] for i in cities]
    
    # 生成初始解(贪心算法)
    current_solution = list(range(n))
    random.shuffle(current_solution)
    current_cost = total_distance(current_solution, distance_matrix)
    
    # 迭代优化
    for _ in range(iterations):
        # 破坏阶段
        partial_solution, removed = destroy(current_solution, num_remove)
        
        # 修复阶段
        new_solution = repair(partial_solution, removed, distance_matrix)
        new_cost = total_distance(new_solution, distance_matrix)
        
        # 接受更优解
        if new_cost < current_cost:
            current_solution = new_solution
            current_cost = new_cost
            print(f"Iteration {_+1}: New best cost = {current_cost:.2f}")
    
    return current_solution, current_cost

# ========== 测试运行 ==========
if __name__ == "__main__":
    # 随机生成10个城市坐标
    random.seed(42)
    cities = [(random.uniform(0,100), random.uniform(0,100)) for _ in range(10)]
    
    # 运行LNS算法
    best_path, best_cost = lns_tsp(cities, iterations=50, num_remove=3)
    
    print("\nFinal Result:")
    print(f"Best Path: {best_path}")
    print(f"Total Distance: {best_cost:.2f}")

算法关键点说明

  1. 破坏强度控制:num_remove参数决定每次迭代移除的城市数量(通常设为总城市数的10-30%)
  2. 修复策略:示例使用贪心插入,实际可替换为: regret-k插入 动态规划精确求解 元启发式方法
  3. 接受准则:示例使用严格改进接受策略,可扩展为: 模拟退火准则 禁忌搜索策略 自适应接受机制

典型应用场景

  1. 车辆路径规划(VRP)
  2. 车间调度问题
  3. 资源分配问题
  4. 组合优化问题(如二维装箱问题)

实际使用时需要根据具体问题特点设计针对性的破坏/修复策略,并调整参数设置。