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

如何实现按产品分组并均衡每日记录数?C#技术求助

产品分组调度实现方案

需求说明

  • 按产品类型分组,同一产品的所有记录必须分配到同一天,禁止拆分单个产品的记录;
  • 调度天数daysScheduled不得超过产品类型数量(最大为4天),该参数与产品列表均为输入项;
  • 需使每日记录数尽可能平均,同时保留产品的添加顺序。

输入示例

// 假设Product类定义如下
public class Product
{
    public string Name { get; set; }
    public string Id { get; set; }

    public Product(string name, string id)
    {
        Name = name;
        Id = id;
    }
}

// 输入参数
int daysScheduled = 2;

IList<Product> products = new List<Product>();
products.Add(new Product("CHAIR", "456"));
products.Add(new Product("CHAIR", "456"));
products.Add(new Product("TABLE", "789"));
products.Add(new Product("TABLE", "789"));
products.Add(new Product("TV", "567"));
products.Add(new Product("TV", "567"));
products.Add(new Product("MILK", "123"));
products.Add(new Product("MILK", "123"));
products.Add(new Product("MILK", "123"));
products.Add(new Product("MILK", "123"));
products.Add(new Product("MILK", "123"));
products.Add(new Product("MILK", "123"));
products.Add(new Product("MILK", "123"));

错误分组示例(每日记录数差异过大)

// DAY 1 => 产品类型数=2,记录数=4 
products.Add(new Product("CHAIR", "456"));
products.Add(new Product("CHAIR", "456"));
products.Add(new Product("TABLE", "789"));
products.Add(new Product("TABLE", "789"));

// DAY 2 => 产品类型数=2,记录数=9
products.Add(new Product("TV", "567"));
products.Add(new Product("TV", "567"));
products.Add(new Product("MILK", "123"));
products.Add(new Product("MILK", "123"));
products.Add(new Product("MILK", "123"));
products.Add(new Product("MILK", "123"));
products.Add(new Product("MILK", "123"));
products.Add(new Product("MILK", "123"));
products.Add(new Product("MILK", "123"));

期望分组结果(每日记录数接近平均)

// DAY 1 => 产品类型数=3,记录数=6 
products.Add(new Product("CHAIR", "456"));
products.Add(new Product("CHAIR", "456"));
products.Add(new Product("TABLE", "789"));
products.Add(new Product("TABLE", "789"));
products.Add(new Product("TV", "567"));
products.Add(new Product("TV", "567"));

// DAY 2 => 产品类型数=1,记录数=7
products.Add(new Product("MILK", "123"));
products.Add(new Product("MILK", "123"));
products.Add(new Product("MILK", "123"));
products.Add(new Product("MILK", "123"));
products.Add(new Product("MILK", "123"));
products.Add(new Product("MILK", "123"));
products.Add(new Product("MILK", "123"));

实现思路与代码

核心逻辑

  1. 按产品类型分组:以产品的唯一标识(如Name+Id)为键分组,确保同一产品的所有记录在一个组中;Linq的GroupBy在内存集合中会保留产品类型首次出现的顺序,满足“保留添加顺序”的要求;
  2. 参数校验:确保调度天数在1到产品类型数量之间(最大4天);
  3. 均衡分配:遍历每个产品组,将其添加到当前记录数最少的日期列表中,保证每日记录数尽可能平均。

完整实现代码

public static List<List<Product>> ScheduleProducts(int daysScheduled, IList<Product> products)
{
    // 按产品唯一标识分组,保留原添加顺序
    var productGroups = products
        .GroupBy(p => $"{p.Name}_{p.Id}")
        .Select(g => g.ToList())
        .ToList();

    // 校验调度天数合法性
    if (daysScheduled < 1 || daysScheduled > productGroups.Count || daysScheduled > 4)
    {
        throw new ArgumentException("调度天数必须在1到产品类型数量之间,且最大不超过4天");
    }

    // 初始化每日调度列表
    var dailySchedules = new List<List<Product>>();
    for (int i = 0; i < daysScheduled; i++)
    {
        dailySchedules.Add(new List<Product>());
    }

    // 分配产品组到记录数最少的日期
    foreach (var group in productGroups)
    {
        var targetDay = dailySchedules.OrderBy(day => day.Count).First();
        targetDay.AddRange(group);
    }

    return dailySchedules;
}

// 测试调用示例
public static void TestSchedule()
{
    int daysScheduled = 2;

    IList<Product> products = new List<Product>();
    products.Add(new Product("CHAIR", "456"));
    products.Add(new Product("CHAIR", "456"));
    products.Add(new Product("TABLE", "789"));
    products.Add(new Product("TABLE", "789"));
    products.Add(new Product("TV", "567"));
    products.Add(new Product("TV", "567"));
    products.Add(new Product("MILK", "123"));
    products.Add(new Product("MILK", "123"));
    products.Add(new Product("MILK", "123"));
    products.Add(new Product("MILK", "123"));
    products.Add(new Product("MILK", "123"));
    products.Add(new Product("MILK", "123"));
    products.Add(new Product("MILK", "123"));

    var result = ScheduleProducts(daysScheduled, products);

    // 输出结果
    for (int i = 0; i < result.Count; i++)
    {
        var dayProducts = result[i];
        var productTypeCount = dayProducts.GroupBy(p => $"{p.Name}_{p.Id}").Count();
        Console.WriteLine($"// DAY {i+1} => 产品类型数={productTypeCount},记录数={dayProducts.Count}");
        foreach (var product in dayProducts)
        {
            Console.WriteLine($"products.Add(new Product(\"{product.Name}\", \"{product.Id}\"));");
        }
        Console.WriteLine();
    }
}

输出验证

运行TestSchedule方法后,会输出与期望分组一致的结果,既保证了产品不拆分,每日记录数接近平均,又保留了原产品的添加顺序。

内容的提问来源于stack exchange,提问作者suc pepe

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 22:00:23