import numpy as np from typing import List def greedy_tsp(distances: np.ndarray) -> List[int]: """贪心算法求解TSP Args: distances: 距离矩阵 Returns: 访问顺序列表 """ n = len(distances) unvisited = set(range(1, n)) # 未访问的城市集合 path = [0] # 从城市0开始 while unvisited: last = path[-1] # 找到距离最后一个城市最近的未访问城市 next_city = min(unvisited, key=lambda x: distances[last][x]) path.append(next_city) unvisited.remove(next_city) return path def nearest_neighbor_tsp(distances: np.ndarray) -> List[int]: """最近邻算法求解TSP Args: distances: 距离矩阵 Returns: 访问顺序列表 """ n = len(distances) unvisited = set(range(1, n)) path = [0] # 从城市0开始 while unvisited: curr = path[-1] # 找到距离当前城市最近的未访问城市 next_city = min(unvisited, key=lambda x: distances[curr][x]) path.append(next_city) unvisited.remove(next_city) return path def insertion_tsp(distances: np.ndarray) -> List[int]: """插入法求解TSP Args: distances: 距离矩阵 Returns: 访问顺序列表 """ n = len(distances) # 初始化包含前两个城市的回路 path = [0, np.argmin(distances[0][1:])+1] unvisited = set(range(1, n)) - {path[1]} while unvisited: min_increase = float('inf') best_pos = -1 best_city = -1 # 尝试将每个未访问城市插入到当前路径的每个可能位置 for city in unvisited: for i in range(len(path)): j = (i + 1) % len(path) # 计算插入后的路径增量 increase = (distances[path[i]][city] + distances[city][path[j]] - distances[path[i]][path[j]]) if increase < min_increase: min_increase = increase best_pos = i + 1 best_city = city # 将最佳城市插入到最佳位置 path.insert(best_pos, best_city) unvisited.remove(best_city) return path def tsp_01(distances: np.ndarray) -> List[int]: """动态规划+2-opt优化求解TSP(内存优化版) Args: distances: 距离矩阵 Returns: 访问顺序列表 """ from itertools import combinations from typing import List import numpy as np n = len(distances) # 使用字典存储dp表,只保存必要的状态 dp = {} dp[(1, 0)] = 0 # 动态规划部分,使用位运算加速 for size in range(2, n + 1): # 提前计算所有可能的子集 subsets = list(combinations(range(n), size)) for subset in subsets: mask = sum(1 << i for i in subset) for v in subset: if v == 0: continue prev_mask = mask ^ (1 << v) min_dist = float('inf') # 只遍历必要的前驱节点 for u in subset: if u != v and (prev_mask & (1 << u)): curr_dist = dp.get((prev_mask, u), float('inf')) + distances[u][v] min_dist = min(min_dist, curr_dist) if min_dist != float('inf'): dp[(mask, v)] = min_dist # 重建路径,使用贪心策略 final_mask = (1 << n) - 1 last_city = min(range(1, n), key=lambda u: dp.get((final_mask, u), float('inf')) + distances[u][0]) path = [0] curr_mask = final_mask curr_city = last_city # 使用集合加速查找 remaining = set(range(n)) remaining.remove(0) while remaining: path.append(curr_city) remaining.remove(curr_city) prev_mask = curr_mask ^ (1 << curr_city) curr_city = min(remaining, key=lambda u: dp.get((prev_mask, u), float('inf')) + distances[u][curr_city]) curr_mask = prev_mask path.append(curr_city) # 优化版2-opt improved = True best_dist = float('inf') while improved: improved = False curr_dist = sum(distances[path[i]][path[i+1]] for i in range(n-1)) + distances[path[-1]][path[0]] if curr_dist < best_dist: best_dist = curr_dist for i in range(1, n-2): for j in range(i+2, n): delta = (distances[path[i-1]][path[j-1]] + distances[path[i]][path[j]] - distances[path[i-1]][path[i]] - distances[path[j-1]][path[j]]) if delta < 0: path[i:j] = reversed(path[i:j]) improved = True break if improved: break return path def tsp_02(distances: np.ndarray) -> List[int]: """动态规划+简化遗传算法求解TSP Args: distances: 距离矩阵 Returns: 访问顺序列表 """ from typing import List import numpy as np import random n = len(distances) # 使用贪心算法生成初始解 path = list(range(n)) for i in range(n-1): min_j = min(range(i+1, n), key=lambda j: distances[path[i]][path[j]]) path[i+1], path[min_j] = path[min_j], path[i+1] # 简化的遗传算法 pop_size = 20 # 减小种群大小 generations = 100 # 减少迭代次数 population = [path[:]] # 生成初始种群 for _ in range(pop_size - 1): new_path = path[:] i, j = random.sample(range(1, n), 2) new_path[i], new_path[j] = new_path[j], new_path[i] population.append(new_path) for _ in range(generations): # 选择最优的一半 population.sort(key=lambda x: sum(distances[x[i]][x[i+1]] for i in range(n-1)) + distances[x[-1]][x[0]]) population = population[:pop_size//2] # 通过交叉生成新解 while len(population) < pop_size: p1, p2 = random.sample(population, 2) cut = random.randint(1, n-2) child = p1[:cut] child.extend(x for x in p2 if x not in child) population.append(child) return min(population, key=lambda x: sum(distances[x[i]][x[i+1]] for i in range(n-1)) + distances[x[-1]][x[0]]) def tsp_03(distances: np.ndarray) -> List[int]: """快速模拟退火求解TSP Args: distances: 距离矩阵 Returns: 访问顺序列表 """ from typing import List import numpy as np import random import math n = len(distances) # 使用贪心算法生成初始解 route = list(range(n)) for i in range(n-1): min_j = min(range(i+1, n), key=lambda j: distances[route[i]][route[j]]) route[i+1], route[min_j] = route[min_j], route[i+1] current_cost = sum(distances[route[i]][route[i+1]] for i in range(n-1)) + distances[route[-1]][route[0]] # 快速降温的模拟退火 temp = 100.0 cooling = 0.95 iterations = 50 # 减少迭代次数 while temp > 0.1: for _ in range(iterations): i, j = random.sample(range(1, n), 2) new_route = route[:] new_route[i], new_route[j] = new_route[j], new_route[i] new_cost = sum(distances[new_route[k]][new_route[k+1]] for k in range(n-1)) + distances[new_route[-1]][new_route[0]] if new_cost < current_cost or random.random() < math.exp((current_cost - new_cost) / temp): route = new_route current_cost = new_cost temp *= cooling return route def two_opt(route, distances): """简化版2-opt优化""" improved = True while improved: improved = False for i in range(1, len(route) - 2): if improved: break for j in range(i + 2, len(route)): old_dist = (distances[route[i-1]][route[i]] + distances[route[j-1]][route[j]]) new_dist = (distances[route[i-1]][route[j-1]] + distances[route[i]][route[j]]) if new_dist < old_dist: route[i:j] = reversed(route[i:j]) improved = True break return route def calculate_cost(route, distances): """计算路径总成本""" return sum(distances[route[i]][route[(i + 1) % len(route)]] for i in range(len(route))) def tsp_04(distances): """ 高性能TSP求解算法,结合多种优化策略: 1. 贪心构造初始解 2. 快速模拟退火 3. 2-opt局部搜索 """ import random import math n = len(distances) # 贪心构造初始解 unvisited = set(range(1, n)) current = 0 route = [0] while unvisited: next_city = min(unvisited, key=lambda x: distances[current][x]) route.append(next_city) unvisited.remove(next_city) current = next_city # 快速模拟退火 temp = 100.0 cooling = 0.95 iterations = 30 current_cost = calculate_cost(route, distances) best_route = route[:] best_cost = current_cost while temp > 0.1: for _ in range(iterations): # 随机交换两个城市 i, j = random.sample(range(1, n), 2) new_route = route[:] new_route[i], new_route[j] = new_route[j], new_route[i] new_cost = calculate_cost(new_route, distances) if new_cost < current_cost or random.random() < math.exp((current_cost - new_cost) / temp): route = new_route current_cost = new_cost if new_cost < best_cost: best_route = new_route[:] best_cost = new_cost temp *= cooling # 2-opt局部优化 best_route = two_opt(best_route, distances) return best_route def tsp_05(distances): """ 基于插入法的TSP优化算法: 1. 插入法构造初始解 2. 快速模拟退火 3. 2-opt局部搜索 """ import random import math n = len(distances) # 插入法构造初始解 route = [0, 1] # 从城市0和1开始 unvisited = set(range(2, n)) while unvisited: # 找到最佳插入位置和待插入城市 min_increase = float('inf') best_pos = 0 best_city = 0 for city in unvisited: # 尝试所有可能的插入位置 for i in range(len(route)): if i == len(route) - 1: increase = (distances[route[i]][city] + distances[city][route[0]] - distances[route[i]][route[0]]) else: increase = (distances[route[i]][city] + distances[city][route[i+1]] - distances[route[i]][route[i+1]]) if increase < min_increase: min_increase = increase best_pos = i + 1 best_city = city # 在最佳位置插入城市 route.insert(best_pos, best_city) unvisited.remove(best_city) # 快速模拟退火 temp = 100.0 cooling = 0.95 iterations = 30 current_cost = calculate_cost(route, distances) best_route = route[:] best_cost = current_cost while temp > 0.1: for _ in range(iterations): # 随机交换两个城市 i, j = random.sample(range(1, n), 2) new_route = route[:] new_route[i], new_route[j] = new_route[j], new_route[i] new_cost = calculate_cost(new_route, distances) if new_cost < current_cost or random.random() < math.exp((current_cost - new_cost) / temp): route = new_route current_cost = new_cost if new_cost < best_cost: best_route = new_route[:] best_cost = new_cost temp *= cooling # 2-opt局部优化 best_route = two_opt(best_route, distances) return best_route