You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

图论最优分配问题:大规模场景下替代暴力枚举的方案求助

解决大规模房间-蚂蚁组分配的最小总移动距离问题

问题本质分析

你的问题属于加权二分图的最小权完美匹配,是运筹学中的经典分配问题:

  • 两个独立集合:房间集合(A-G共7个,可扩展至42个)、蚂蚁组集合(数量为7、6…1)
  • 分配代价定义:将蚂蚁组j分配给房间i的总移动代价 = 蚂蚁组j的数量 × 房间i到EXIT的距离
  • 目标:找到一组一一对应的分配方案,使所有房间的总移动代价最小

暴力枚举所有排列的复杂度为O(n!),n=42时计算量是天文数字,完全不可行,必须用多项式时间算法解决。

最优解决方案

1. 贪心算法(针对你的特定场景)

你的场景满足排序不等式的应用条件,可直接用贪心算法得到最优解,时间复杂度仅为O(n log n):

  • 核心逻辑:数量最多的蚂蚁组分配给离EXIT最近的房间,次多的分配给次近的,以此类推(逆序匹配),此时总移动代价最小;若顺序匹配(最少蚂蚁组给最近房间),总代价最大。

实现代码

import pandas as pd
import math
import numpy as np

def create_room_layout():
    # 还原你给出的房间布局
    return pd.DataFrame([
        ['A', '.', '.', '.', 'B', '.', '.', '.', 'C', '.', '.', '.', 'EXIT'],
        ['.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.'],
        ['.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.'],
        ['D', '.', '.', '.', 'E', '.', '.', '.', 'F', '.', '.', '.', 'G']
    ])

def get_distance(df, room, target="EXIT"):
    """计算单个房间到EXIT的欧氏距离"""
    try:
        room_pos = [(x, y) for x, y in zip(*np.where(df.values == room))][0]
        target_pos = [(x, y) for x, y in zip(*np.where(df.values == target))][0]
    except Exception as e:
        print(f"错误:{e},无法找到坐标")
        return None
    return math.sqrt((target_pos[1]-room_pos[1])**2 + (target_pos[0]-room_pos[0])**2)

def optimal_ant_allocation():
    df = create_room_layout()
    rooms = ['A', 'B', 'C', 'D', 'E', 'F', 'G']
    ant_counts = [7, 6, 5, 4, 3, 2, 1]

    # 计算每个房间到EXIT的距离
    room_dist = [(room, get_distance(df, room)) for room in rooms]
    # 按距离从小到大排序房间
    sorted_rooms = sorted(room_dist, key=lambda x: x[1])
    # 蚂蚁组按数量从大到小排序
    sorted_ants = sorted(ant_counts, reverse=True)

    # 执行贪心分配
    allocation = {}
    total_dist = 0.0
    print("最优分配方案:")
    for (room, dist), count in zip(sorted_rooms, sorted_ants):
        allocation[room] = (count, dist)
        cost = count * dist
        total_dist += cost
        print(f"房间{room} → {count}只蚂蚁,单组代价:{cost:.2f},距离EXIT:{dist:.2f}")
    
    print(f"\n总移动距离:{total_dist:.2f}")

    # 可选:计算最大总移动距离(顺序匹配)
    sorted_ants_reversed = sorted(ant_counts)
    max_total = 0.0
    print("\n最大总移动距离方案:")
    for (room, dist), count in zip(sorted_rooms, sorted_ants_reversed):
        cost = count * dist
        max_total += cost
        print(f"房间{room} → {count}只蚂蚁,单组代价:{cost:.2f}")
    print(f"\n最大总移动距离:{max_total:.2f}")

if __name__ == "__main__":
    optimal_ant_allocation()

2. 匈牙利算法(通用复杂场景)

如果你的分配代价不是简单的「数量×距离」,而是更复杂的自定义规则(代价矩阵不满足单调性),则使用匈牙利算法(Kuhn-Munkres算法),它能在O(n³)时间内解决n元素的最小权完美匹配问题,n=42时计算量完全可控。

实现代码(基于scipy库)

from scipy.optimize import linear_sum_assignment
import numpy as np

# 假设已得到房间距离列表和蚂蚁数量列表
room_distances = [d for _, d in sorted_rooms]
ant_counts = [7,6,5,4,3,2,1]
n = len(room_distances)

# 构造代价矩阵:cost[i][j]表示将第j组蚂蚁分配给第i个房间的代价
cost_matrix = np.array([[ant_counts[j] * room_distances[i] for j in range(n)] for i in range(n)])

# 执行匈牙利算法
row_indices, col_indices = linear_sum_assignment(cost_matrix)
total_min_cost = cost_matrix[row_indices, col_indices].sum()

print("最小总移动代价:", total_min_cost)
# 分配结果:第row_indices[i]个房间 → 第col_indices[i]组蚂蚁

总结

  • 针对你的特定场景,贪心算法是最优选择,效率极高且实现简单
  • 复杂场景下使用匈牙利算法,借助scipy库可快速实现,完全支持42个房间的规模

内容的提问来源于stack exchange,提问作者Achille G

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 16:36:44