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

求覆盖所有仓库送货任务的最小Agent数量技术咨询

最少Agent数量计算:仓库送货调度问题

这个问题本质上是经典的区间调度资源分配问题,核心是用最少的Agent(资源)来完成所有不冲突的送货任务。先明确一下问题中的关键假设(结合你给出的例子):

当Agent为仓库W1{1,2}送货时,需要1小时脱身——意味着Agent在仓库的startTime时刻开始送货,startTime+1时刻完成任务,且这个1小时窗口必须完全落在仓库的营业时间内(即startTime+1 <= endTime,默认所有仓库都满足这个条件)。

解决思路:贪心算法(排序+最小堆)

这是解决这类问题最高效的方法,时间复杂度为O(n log n)(主要来自排序和堆操作),步骤如下:

  1. 排序任务:把每个仓库对应的送货时间窗口([startTime, startTime+1])按开始时间升序排序;如果开始时间相同,按结束时间升序排序,确保我们按时间顺序处理任务。
  2. 用最小堆跟踪Agent空闲时间:
    • 堆中存储的是每个Agent完成上一个任务后的空闲时间,堆顶是最早能空闲的Agent。
    • 遍历每个送货任务:
      • 如果堆顶Agent的空闲时间 ≤ 当前任务的开始时间,说明这个Agent可以接手新任务,弹出堆顶,把当前任务的结束时间加入堆。
      • 如果堆顶Agent的空闲时间 > 当前任务的开始时间,说明没有Agent能立刻接手,需要新增一个Agent,把当前任务的结束时间加入堆。
  3. 堆的大小就是所需的最小Agent数:堆里每个元素代表一个Agent的下一次空闲时间,元素个数就是正在工作的Agent总数,也就是最小需要的数量。

Java代码实现

import java.util.*;

public class WarehouseDeliveryScheduler {
    // 你的WareHouse类定义,补充必要的访问方法
    static class WareHouse {
        private int startTime;
        private int endTime;

        public WareHouse(int startTime, int endTime) {
            this.startTime = startTime;
            this.endTime = endTime;
        }

        public int getStartTime() {
            return startTime;
        }

        // 获取送货完成时间(1小时任务)
        public int getDeliveryEndTime() {
            return startTime + 1;
        }
    }

    public static int minAgentsNeeded(List<WareHouse> warehouses) {
        // 边界处理:空列表直接返回0
        if (warehouses == null || warehouses.isEmpty()) {
            return 0;
        }

        // 按送货开始时间排序,开始时间相同则按结束时间排序
        Collections.sort(warehouses, (a, b) -> {
            if (a.getStartTime() != b.getStartTime()) {
                return Integer.compare(a.getStartTime(), b.getStartTime());
            }
            return Integer.compare(a.getDeliveryEndTime(), b.getDeliveryEndTime());
        });

        // 最小堆:存储Agent的空闲时间
        PriorityQueue<Integer> agentFreeTimes = new PriorityQueue<>();

        for (WareHouse warehouse : warehouses) {
            int deliveryStart = warehouse.getStartTime();
            int deliveryEnd = warehouse.getDeliveryEndTime();

            // 检查是否有Agent可以复用
            if (!agentFreeTimes.isEmpty() && agentFreeTimes.peek() <= deliveryStart) {
                agentFreeTimes.poll();
            }
            // 加入当前任务的结束时间(不管是复用还是新增Agent)
            agentFreeTimes.offer(deliveryEnd);
        }

        return agentFreeTimes.size();
    }

    // 测试示例
    public static void main(String[] args) {
        List<WareHouse> warehouses = Arrays.asList(
                new WareHouse(1, 3),
                new WareHouse(2, 4),
                new WareHouse(1, 2),
                new WareHouse(3, 5)
        );
        System.out.println("最小需要的Agent数量:" + minAgentsNeeded(warehouses)); // 输出2
    }
}

另一种思路:时间点计数法

如果你不想用堆,也可以用双指针统计时间点的任务重叠数:

  1. 收集所有任务的开始时间和结束时间,分别排序。
  2. 用两个指针遍历两个数组,统计当前同时进行的任务数,最大值就是所需的最小Agent数。

这种方法的时间复杂度也是O(n log n),代码实现起来更简洁,但本质和贪心算法是一致的。

边界情况注意

  • 如果存在仓库的endTime - startTime < 1(比如startTime=2,endTime=2),这类仓库无法安排送货,需要提前过滤或者根据业务需求处理。
  • 空仓库列表直接返回0个Agent。

内容的提问来源于stack exchange,提问作者Himanshu Upadhyay

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 08:24:29