让AI重构2000行“屎山”:代码量减半,性能提升40%,但我掉了两周头发

30秒速览

  • 别指望AI全自动重构,你得当它的架构师和产品经理,给它画好框框。
  • 第一版AI生成的代码性能反而更差,因为它不懂算法复杂度和Python开销。
  • 让AI做代码分析和片段生成,你来组装和性能调优,效率最高。
  • 用AI做代码审查和逻辑对比,能揪出你自己都忽略的业务逻辑遗漏。
  • 最终代码量减半,性能提升40%,但过程充满了来回拉扯和手动调试。

这个2000行的路径规划模块,已经成了团队的“技术债”

上周三下午,我被CTO叫到办公室,他指着监控大屏上一路飙红的曲线问我:“老王,咱们这个‘智能路径规划’服务,最近平均响应时间怎么又爬到1.8秒了?客户那边的物流调度员已经在骂娘了。”我盯着那个熟悉又刺眼的服务名——legacy_router.py,心里咯噔一下。这玩意儿我太熟了,一个在我司物流SaaS平台里服役了快五年的Python模块,专门负责给日活5万用户的物流公司计算最优取送货路径。它就像一个老旧的发动机,勉强维持着运转,但每次提速都要冒着散架的风险。

这个模块的“光辉历史”可以追溯到公司初创期。当时为了快速上线,几个实习生用最原始的贪心算法堆出了第一版,后来随着业务复杂,什么动态权重、实时交通规避、车辆载重约束、软时间窗……各种需求像打补丁一样往上糊。五年下来,没人敢动核心逻辑,因为牵一发而动全身。模块膨胀到了惊人的2000多行,全塞在一个文件里。我随便截一段核心函数给大家感受一下:

def calculate_route(orders, vehicles, current_time, weather_data=None, traffic_coefficient=1.0):
    # ... 前面80行是各种参数检查和数据预处理,混杂着业务逻辑
    # 中间开始真正的路径计算
    tentative_routes = []
    for v in vehicles:
        # 为每辆车初始化一条空路径
        route = {'vehicle_id': v.id, 'path': [], 'eta_list': [], 'load': 0}
        remaining_orders = orders.copy()
        # 一个基于距离和紧急程度的混合启发式,写了150行
        while len(remaining_orders) > 0 and route['load']  10:
                    dist_score *= 1.5  # 雨天惩罚
                # 还有十几行各种权重调整和特殊处理
                total_score = 0.7 * dist_score + 0.3 * urgency_score + (some_other_magic_number)
                if total_score > best_score and route['load'] + o.weight <= v.max_load:
                    best_score = total_score
                    best_order = o
            if best_order:
                route['path'].append(best_order.pickup_loc)
                route['path'].append(best_order.delivery_loc) # 这里直接把取送货点连起来,没考虑顺序优化
                route['load'] += best_order.weight
                remaining_orders.remove(best_order)
                # 计算ETA,又是一堆硬编码的逻辑
                eta = _calc_eta(route['path'][-2], route['path'][-1], current_time, traffic_coefficient)
                route['eta_list'].append(eta)
            else:
                break
        tentative_routes.append(route)
    # 后面还有100多行,是“后处理”:尝试交换订单看看能不能优化,但算法效率是O(n^2),订单一多就卡死
    # 最终返回一个字典,结构混乱
    return {'status': 'ok', 'routes': tentative_routes, 'meta': {'calc_time': time.time() - start_time}}

这代码的问题,我闭着眼睛都能数出来:一个函数干了所有事(输入解析、核心算法、结果封装)、硬编码的参数和魔法数字满天飞算法复杂度是O(n²*m)(n是订单,m是车辆),订单超过50个就能感觉到明显卡顿、数据结构混乱,中间变量tentative_routes的结构在函数不同位置被修改、单元测试为零,全靠线上真实流量验证。更可怕的是,里面还有一些为了兼容老客户而永远不敢删的“僵尸逻辑”。每次有新需求,我们都是在边缘加个if分支,而不是重构。它就像一栋不断加盖违章建筑的危楼。

CTO给我的死命令是:一个月内,在不改变外部接口的前提下,让这个模块的P99响应时间降到800毫秒以下,并且代码可维护性必须提升。我知道,手动重写至少需要一个人月,而且风险极高。于是,我把目光投向了最近团队在试用的Cursor(基于GPT-4的AI编程助手)和Claude Code。这次,我决定让AI当主力,我来当架构师和质检员。没想到,这个决定开启了我职业生涯里最密集的一次“人机协作”踩坑之旅。

别急着让AI直接开干,你得先当它的“导游”

我的第一反应是,把整个legacy_router.py文件扔给Cursor,然后打上一行命令:/重构此文件,优化性能与结构。但我立刻刹住了车。十年前我刚入行时,导师就告诉我:“给机器下指令,要像给一个聪明但不懂业务的新人下指令一样。”直接扔过去2000行混沌代码,AI最好的情况是给你做点格式整理,最坏的情况是给你生成一堆语法正确但逻辑跑偏的“新屎山”。

我得先帮AI理解上下文。我做了三件事:

  1. 创建“重构说明书”:我新建了一个REFACTOR_PLAN.md文件,不是写给自己看的,是专门给AI看的。里面用最直白的语言描述了模块的职责、输入输出格式、核心痛点,以及最重要的——不可更改的约束
  2. 提取“核心接口契约”:我把这个模块被其他服务调用的方式,以及返回的数据结构,用几个具体的示例写了出来。这相当于定义了重构的“安全边界”。
  3. 建立测试锚点:虽然没有单元测试,但我们有历史请求日志。我从中筛选了20个有代表性的请求(包括正常场景、边缘场景、曾经出过bug的场景),把它们的输入和对应的正确输出(从日志里提取的结果)做成了一个简单的“验证套件”,一个Python字典文件。这是验证AI生成代码是否“跑偏”的生命线。

我的REFACTOR_PLAN.md开头是这样的:

# 路径规划模块重构计划 (给AI助手看的)

## 模块核心职责
根据一批订单(包含取货点、送货点、重量、时间窗)和一批车辆(包含当前位置、载重),计算出一组分配方案,将订单分配给车辆并生成行驶路径,目标是**总行驶距离尽可能短**,并兼顾时间窗。

## 必须保持不变的接口
1. 函数签名:`def calculate_route(orders, vehicles, current_time, weather_data=None, traffic_coefficient=1.0)`
2. 输入参数格式:`orders`是`Order`对象列表,`vehicles`是`Vehicle`对象列表。(`Order`和`Vehicle`的类定义见附件)
3. 返回值格式:必须返回一个字典,包含 `{'status': 'ok', 'routes': list, 'meta': dict}`。`routes`里每个元素必须包含`vehicle_id`, `path`(位置列表), `eta_list`, `load`。

## 当前主要问题 (必须解决)
1. **性能**:单次计算超过1.5秒(订单>50时)。目标:P99 < 800ms。
2. **可读性**:一个函数2000行,无法维护。
3. **算法缺陷**:当前贪心算法效果差,且后处理优化效率极低(O(n²))。

## 重构目标与建议方向
1. **拆分函数**:将输入校验、距离计算、核心算法、结果格式化拆分成独立函数/类。
2. **算法升级**:考虑用更高效的启发式算法(如插入启发式、2-opt局部搜索)替换部分逻辑。**注意**:不能引入需要长时间训练或复杂第三方求解器(如OR-Tools)的算法,必须保持轻量。
3. **缓存**:对耗时的计算(如两点间距离)进行缓存。
4. **去除硬编码**:将权重参数(0.7, 0.3等)、惩罚系数提取为配置常量。

## 绝对禁止
- 不能改变函数签名和返回的字典结构。
- 不能删除对`weather_data`和`traffic_coefficient`的处理逻辑(即使它看起来蠢)。
- 第一阶段不要引入多线程/异步,优先优化单线程算法。

有了这份“导游手册”,我才感觉心里有点底。我把它和原始的legacy_router.py、数据类定义文件、以及那20个测试用例一起,在Cursor里打开,准备开始第一次“人机对话”。

AI写的第一版代码,跑起来比原来还慢

我把计划书和代码都喂给Cursor,用/命令提示:“请根据重构计划,对`legacy_router.py`进行第一步:函数拆分和结构整理。先不要修改核心算法逻辑。”

Cursor哗啦啦地开始输出。它确实理解了“拆分”的指令,把那个巨无霸函数拆成了七八个小函数:_validate_input, _initialize_routes, _compute_order_score, _assign_order_to_vehicle, _apply_post_optimization等等。代码看起来清爽多了,逻辑被归了类。我心中一喜,赶紧把它生成的新代码保存为router_v1.py,并跑了一下我的20个测试用例。

结果全部通过!接口完全一致。我立马用包含100个虚拟订单和20辆车的压力测试脚本跑了一下性能。优化前:1.62秒。Cursor生成的v1版:2.11秒

我懵了。结构更清晰了,怎么反而更慢了?我立刻打开代码分析工具(Python的cProfile)和仔细阅读生成代码。坑来了:

def _compute_order_score(order, vehicle, current_pos, current_load, max_load, weather_data, traffic_coeff):
    """计算一个订单对当前车辆路径的‘得分’ (AI生成的)"""
    # 问题1:重复计算。每次调用都重新计算哈弗辛距离,而距离计算是CPU密集型操作。
    pickup_dist = haversine(current_pos, order.pickup_loc)
    # 问题2:AI‘贴心’地做了参数检查,但每次调用都做,开销巨大。
    if not hasattr(order, 'weight'):
        raise ValueError("Order object must have 'weight' attribute")
    if current_load + order.weight > max_load:
        return -float('inf')  # 载重检查,逻辑正确,但放在这里每单都判断
    # 问题3:把原来内联的天气判断也抽出来了,但增加了函数调用和条件判断层级。
    rain_penalty = 1.5 if weather_data and weather_data.get('rainfall', 0) > 10 else 1.0
    dist_score = pickup_dist * traffic_coeff * rain_penalty
    urgency_score = (order.deadline - current_time).total_seconds() / 3600.0
    # 问题4:AI把魔法数字替换成了模块级常量(好事),但计算仍在函数内。
    return DIST_WEIGHT * dist_score + URGENCY_WEIGHT * urgency_score

def _assign_order_to_vehicle(vehicle, available_orders, ...):
    """AI生成的主循环逻辑"""
    while available_orders:
        best_order = None
        best_score = -float('inf')
        for order in available_orders:
            # 致命问题:对每个订单、每辆车、每次循环迭代,都调用一次`_compute_order_score`。
            # 算法复杂度从O(n²)变成了O(n³),因为把原来一些提前退出的条件也包进函数里了。
            score = _compute_order_score(order, vehicle, ...)
            if score > best_score:
                best_score = score
                best_order = order
        if best_order:
            # ... 分配订单
            available_orders.remove(best_order)
        else:
            break

看到这里我血压就上来了。AI完美地执行了“拆分函数”和“提取常量”的指令,但它没有“性能意识”。它把原来虽然乱但还有些紧凑的循环,拆成了多次函数调用,并且引入了大量重复计算。函数拆分的代价是调用开销和缓存不友好,这在Python里尤其明显。同时,它把载重检查从外层循环移到了每个订单的评分函数里,导致无效计算暴增。

我尝试提示它优化:“函数`_compute_order_score`被频繁调用,请优化其性能,减少重复计算。”AI给出的方案是加了一个lru_cache装饰器。但问题在于,这个函数的参数里有对象(order, vehicle),它们不是可哈希的,直接缓存会报错。AI又生成了一段尝试将对象ID转换为元组进行缓存的复杂代码,看得我头皮发麻,而且缓存命中率其实很低,因为车辆位置、当前负载在循环中是变化的。

这个坑让我明白:AI擅长遵循代码风格和结构指令,但对算法复杂度和性能瓶颈的感知非常弱。它不会主动去分析哪些计算可以前置、哪些循环可以合并。它只是机械地执行“拆分”这个动作。第一回合,我高估了AI的“理解”能力,低估了架构设计中人脑的价值。

让AI“拆解”比让它“重写”更靠谱

吃了性能的亏,我调整了策略。我不再让AI直接从混沌代码生成“优质代码”,而是让它帮我做“代码分析”和“片段生成”,我来做“组装”和“性能调优”。我把这个过程叫做“外科手术式”重构。

第一步,数据流分析。 我让AI分析原始代码中的数据流动。我提问:“在`legacy_router.py`中,列出所有被多次计算的中间结果,特别是基于订单和车辆位置的计算。”AI给了一个列表:

  • 订单取货点到车辆当前位置的距离(在每辆车的循环中,对每个未分配订单计算)
  • 订单取货点到送货点的距离(仅在最终ETA计算时用一次)
  • 车辆当前负载(在循环中不断更新)

这让我立刻意识到,距离矩阵预计算是性能提升的关键。原来代码在多层循环里重复调用haversine这个计算球面距离的函数,这是最大的瓶颈。

第二步,生成关键片段。 我不让AI重写整个函数,而是让它为我生成我需要的“零件”。比如:“请写一个函数`precompute_distance_matrix(location_list)`,返回一个二维数组,表示任意两点间的距离。使用哈弗辛公式,并对结果进行缓存,避免重复计算相同位置。”AI这次给出了不错的代码:

from functools import lru_cache
from math import radians, sin, cos, sqrt, atan2

@lru_cache(maxsize=None)
def _haversine_cache(lat1, lon1, lat2, lon2):
    """带缓存的哈弗辛距离计算,参数是基本类型,可哈希。"""
    # 将十进制度数转化为弧度
    lat1, lon1, lat2, lon2 = map(radians, [lat1, lon1, lat2, lon2])
    # 哈弗辛公式
    dlat = lat2 - lat1
    dlon = lon2 - lon1
    a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2
    c = 2 * atan2(sqrt(a), sqrt(1-a))
    r = 6371.0  # 地球平均半径,单位公里
    return c * r

def precompute_distance_matrix(locations):
    """
    预计算所有位置点之间的距离矩阵。
    :param locations: list of (lat, lon) tuples
    :return: 2D numpy array, dist_matrix[i][j] = distance(loc_i, loc_j)
    """
    n = len(locations)
    dist_matrix = np.zeros((n, n))
    for i in range(n):
        lat1, lon1 = locations[i]
        for j in range(i+1, n):  # 利用对称性,只计算上三角
            lat2, lon2 = locations[j]
            dist = _haversine_cache(lat1, lon1, lat2, lon2)
            dist_matrix[i][j] = dist
            dist_matrix[j][i] = dist
    return dist_matrix

这个代码比我想得还周到,用了lru_cache和矩阵对称性优化。我手动把它集成到我的重构框架中。

第三步,算法替换指导。 我告诉AI:“原始的后处理优化(尝试交换订单)是O(n²)的,且效果有限。请为我提供一个简单的、基于2-opt原则的路径局部优化函数伪代码,只优化单条车辆的路径距离,不考虑时间窗。”AI给了我清晰的步骤描述和代码框架。我基于这个框架,自己实现了针对我们数据结构(位置列表)的2-opt优化,复杂度还是O(k*n²)(k是迭代次数),但我通过设置最大迭代次数和早停机制来控制。

第四步,组装。 这次我自己担任“总工程师”。我设计新的主流程:

  1. 数据预处理与校验(使用AI生成的校验函数)。
  2. 收集所有位置点(车辆位置+所有订单的取送点),预计算距离矩阵。
  3. 使用插入启发式算法(我参考AI提供的算法描述自己实现)进行初始分配。核心是:每次选择“成本增加最小”的订单-车辆-插入位置组合。这需要利用预计算的距离矩阵快速计算插入成本。
  4. 对每辆车生成的路径,运行简化版的2-opt优化。
  5. 格式化输出。

AI是我的“高级代码片段生成器”和“算法顾问”。每当我在实现插入启发式遇到细节问题时(比如“如何高效计算将一个点插入路径某位置后的距离增量?”),我就把问题抛给AI,它给我代码片段,我修改、整合。最终,我手写出了router_v2.py的核心算法部分,代码量约500行,比原来少了四分之三。

性能测试结果:处理100订单/20车辆,耗时0.89秒!首次低于1秒大关。这个结果证明,让AI做它擅长的事(生成片段、解释算法),而把系统设计、性能整合、代码组装这些需要全局观和深度理解的工作留给自己,是最高效的人机协作模式。

重构不是一锤子买卖,得拉着AI一起“走查”

性能达标了,但我心里不踏实。代码是我在AI辅助下“拼”出来的,里面有没有隐藏的bug?逻辑覆盖是否全面?尤其是那些陈年“僵尸逻辑”和边缘情况。这时候,我让AI切换角色,从“代码生成器”变成“严格的代码审查员”。

我把router_v2.py和原始的legacy_router.py同时发给Cursor,并开启一个“差异分析”对话。我的指令是:“请逐行对比新旧两个版本的核心逻辑,特别关注在天气数据处理、交通系数应用、时间窗判断、以及载重检查这些业务逻辑上,新版本是否完整保留了旧版本的所有行为?列出任何可能的行为不一致点。”

AI花了点时间,给出了一个非常详细的对比报告,用表格形式呈现:

功能点 旧版本逻辑 新版本逻辑 是否一致 风险提示
雨天惩罚 在计算单个订单距离分时,判断`if weather_data.get(‘rainfall’) > 10`,然后`dist_score *= 1.5` 在预计算距离矩阵时未考虑天气,在计算插入成本时也未加入天气因子。 不一致 新版本完全丢失了雨天惩罚逻辑,可能导致雨天路径规划不准确。
交通系数 `dist_score * traffic_coefficient` 在计算两点间旅行时间ETA时使用了,但在核心距离计算中未使用。 不一致 交通系数本应用于影响距离权重,新版本仅影响ETA,会改变优化目标。
载重检查 在内层订单循环中判断`if route[‘load’] + o.weight <= v.max_load` 在插入启发式算法中,计算插入成本前会检查插入后载重是否超标。 一致 新版本逻辑更清晰。
时间窗紧急度分数 `(deadline – current_time).seconds / 3600.0` 新版本算法未显式使用此分数作为优化目标。 不一致 新算法只优化距离,可能忽略紧急订单。

看到这个表格,我后背冒汗。AI的审查直接揪出了三个严重的逻辑遗漏!我光顾着优化距离和性能,差点把业务规则给扔了。这就是“重构”最危险的地方——在不改变接口的伪装下,悄悄改变了核心行为。

我立刻根据AI的提示进行修复。对于天气和交通系数,我不能简单地加回惩罚,因为我的新算法基于预计算的距离矩阵。我的解决方案是:将“成本”概念从纯粹的地理距离,扩展为“加权旅行时间”。我修改了距离矩阵预计算的逻辑,使其变成一个“成本矩阵”。

def precompute_cost_matrix(locations, base_time_per_km=0.1, traffic_coeff=1.0, weather_data=None):
    """
    预计算成本矩阵,成本 = 基础旅行时间 * 交通系数 * 天气系数。
    基础旅行时间由距离和假设的平均速度推导。
    """
    n = len(locations)
    cost_matrix = np.zeros((n, n))
    # 天气惩罚系数:全局计算一次,避免在循环中重复判断
    weather_penalty = 1.0
    if weather_data and weather_data.get('rainfall', 0) > 10:
        weather_penalty = 1.5  # 和旧逻辑保持一致

    for i in range(n):
        lat1, lon1 = locations[i]
        for j in range(i+1, n):
            lat2, lon2 = locations[j]
            distance_km = _haversine_cache(lat1, lon1, lat2, lon2)
            # 核心修改:成本 = 距离 * 单位时间成本 * 交通系数 * 天气系数
            base_cost = distance_km * base_time_per_km  # 假设每公里需要0.1小时
            adjusted_cost = base_cost * traffic_coeff * weather_penalty
            cost_matrix[i][j] = adjusted_cost
            cost_matrix[j][i] = adjusted_cost
    return cost_matrix

对于时间窗紧急度,我修改了插入启发式算法的“成本”计算。在选择下一个插入的订单时,成本不再只是地理距离成本,而是“地理成本 – 紧急度系数 * 时间紧迫性”。这样,紧急的订单会因为其“负成本”(即收益)而被优先安排。这相当于将多目标优化(距离短、订单急)融合到了一个成本函数里。

修复后,我再次运行那20个历史测试用例。谢天谢地,全部通过,并且结果与旧版本在业务逻辑上基本等价(由于算法升级,路径不可能完全一致,但都满足约束且趋势合理)。性能测试:0.92秒。比纯距离优化版慢了0.03秒,但这是为业务正确性必须付出的代价,完全可以接受。

这个“AI辅助走查”的环节,价值巨大。它像一个不知疲倦、极度细致的复核员,弥补了人类开发者容易产生的“视觉盲区”。

最终效果:代码量减半,性能提升40%,但代价是两周的折腾

经过前后两周的迭代、踩坑、修复,新的路径规划模块终于达到了上线标准。我们来做个最终盘点:

指标 旧模块 (legacy_router.py) 新模块 (router_final.py) 变化
代码行数 (逻辑代码) ~2150 行 ~980 行 -54%
文件数 1个巨型文件 3个文件 (主算法、工具函数、常量配置) 结构清晰
平均响应时间 (100单/20车) 1620 ms 920 ms -43%
P99响应时间 (生产采样) ~1850 ms ~820 ms 达到目标(<800ms)
算法核心 混乱贪心 + 低效交换 插入启发式 + 2-opt局部优化 质量提升
单元测试覆盖率 0% 75% (我补了测试) 可维护性大增
我的头发损失 若干根 显著增加

上线过程是平滑的。因为接口纹丝不动,下游服务无感知。监控曲线上的红色警报变成了稳定的绿色。CTO拍了拍我的肩膀,说了句“干得漂亮”。但我知道,这漂亮的结果背后,是一地鸡毛的踩坑过程。

最后,我想分享几点这次“AI重构”实战的真心话:

  • AI不是银弹,而是杠杆。 它不能替代你对业务和系统的深度理解。它的价值在于放大你的效率。试图让它全自动完成复杂重构,一定会掉坑里。正确的姿势是你来设计蓝图、把握方向、控制质量,让它去完成重复、琐碎或需要查阅大量知识的编码任务。
  • 给AI的指令,质量决定输出的质量。 “重构代码”是垃圾指令。“根据这份详细计划,先进行安全的函数拆分,保持接口不变”才是好指令。花时间写“重构说明书”和“测试锚点”,比盲目尝试节省十倍时间。
  • 性能优化必须亲力亲为。 AI对算法复杂度不敏感,对语言特有的性能开销(如Python函数调用、对象创建)缺乏直觉。核心的算法改造和性能热点,必须由你主导,AI辅助。
  • 用AI做审查,效果惊人。 让它对比逻辑、查找遗漏、甚至生成边界测试用例,它比大多数匆忙的人类审查员要细致和全面得多。这可能是本次实践中我最意外的收获。
  • 心理准备:过程是曲折的。 别指望一次对话就成功。准备好来回拉扯、反复验证、亲手调试。把AI当成一个能力超强但需要明确指引和频繁纠正的实习生。

这次经历后,我对“AI编程”的态度更务实了。它极大地改变了我的工作流,但没有改变软件工程的核心:清晰的架构、严谨的逻辑、和对业务价值的深刻理解。下一次再面对“技术债”,我依然会拉起AI这个帮手,但我会更清楚,方向盘必须牢牢抓在自己手里。

(附:最终版核心算法函数骨架,以示诚意)

def calculate_route(orders, vehicles, current_time, weather_data=None, traffic_coefficient=1.0):
    """重构后的主函数,清晰的分层结构"""
    # 1. 输入验证 (AI生成)
    _validate_inputs(orders, vehicles)

    # 2. 数据准备与成本矩阵预计算 (我设计,AI辅助实现片段)
    all_locations = _gather_all_locations(orders, vehicles)
    cost_matrix = precompute_cost_matrix(
        all_locations,
        traffic_coeff=traffic_coefficient,
        weather_data=weather_data
    )
    location_to_index = {loc: idx for idx, loc in enumerate(all_locations)}

    # 3. 核心算法:插入启发式分配 (我主导实现,AI提供算法描述和片段)
    vehicle_routes = _initialize_empty_routes(vehicles, location_to_index)
    unassigned_orders = orders.copy()

    while unassigned_orders:
        best_cost_increase = float('inf')
        best_assignment = None  # (order, vehicle, insert_position)

        # 寻找最佳插入点——这里用了预计算的成本矩阵,O(n*m*k)但比O(n²)好
        for order in unassigned_orders:
            for v_idx, route in enumerate(vehicle_routes):
                if route['load'] + order.weight > vehicles[v_idx].max_load:
                    continue
                # 计算将此订单插入该车辆路径各个位置的成本增量
                for insert_pos in range(len(route['path']) + 1):
                    inc = _calculate_insertion_cost(
                        order, route, insert_pos, cost_matrix, location_to_index, current_time
                    )
                    if inc < best_cost_increase:
                        best_cost_increase = inc
                        best_assignment = (order, v_idx, insert_pos)

        if best_assignment:
            order, v_idx, insert_pos = best_assignment
            _insert_order_into_route(order, v_idx, insert_pos, vehicle_routes, location_to_index)
            unassigned_orders.remove(order)
        else:
            # 无法分配任何订单(如载重不足),提前结束
            break

    # 4. 局部路径优化 (基于AI提供的2-opt伪代码实现)
    for route in vehicle_routes:
        _apply_2opt_optimization(route, cost_matrix)

    # 5. 格式化输出 (AI根据旧格式生成)
    return _format_output(vehicle_routes, vehicles, all_locations, cost_matrix, current_time)

发表评论