C# 如何基于某些条件从现有集合创建新列表

C# 如何基于某些条件从现有集合创建新列表,c#,.net,algorithm,C#,.net,Algorithm,比方说,我在列表中有一组自定义对象。每个对象的持续时间属性设置为几分钟(10分钟、15分钟或45分钟等) 我必须把他们分成3个小时的名单。也就是说,ListA将有一组对象,其持续时间总和应等于3小时,以此类推。但最终列表需要/不需要坚持3个小时(可能更少或相等) 我应该使用哪种算法从列表中读取对象,并根据3小时的总持续时间创建新列表 这里的困难可能是,假设我有5个30分钟的物体和2个45分钟的物体。在ListA中,如果我在阅读时添加了5个30分钟的对象(6*50=150),那么我不能添加1个45

比方说,我在列表中有一组自定义对象。每个对象的持续时间属性设置为几分钟(10分钟、15分钟或45分钟等)

我必须把他们分成3个小时的名单。也就是说,ListA将有一组对象,其持续时间总和应等于3小时,以此类推。但最终列表需要/不需要坚持3个小时(可能更少或相等)

我应该使用哪种算法从列表中读取对象,并根据3小时的总持续时间创建新列表

这里的困难可能是,假设我有5个30分钟的物体和2个45分钟的物体。在ListA中,如果我在阅读时添加了5个30分钟的对象(6*50=150),那么我不能添加1个45分钟的对象。因为这不等于3小时。我会先添加2个45分钟的对象,然后再添加3个30分钟的对象(2*45+3*30=3小时),然后将另外2个对象放在另一个列表中


感谢您的阅读。

如果您尝试先存储大对象,然后使用小对象来完成,那么这会很容易

下面是我为您编写的一个快速代码,它运行良好:

    static void Main(string[] args)
    {
        // data
        List<Int32> listElement = new List<Int32>() { 10, 20, 10, 30, 45, 10, 20, 30, 40, 50, 60, 40, 30, 50, 60, 70, 80, 90, 20, 30, 10, 50, 60, 40, 60, 80, 90, 60, 80, 70, 80, 90, 90, 50 };
        Int32 MaxStack = 180;

        // result
        List<List<Int32>> listResult = new List<List<Int32>>();

        // process
        foreach (Int32 element in listElement.OrderByDescending(i => i))
        {
            List<Int32> listToStore = listResult.Where(l => l.Sum() + element <= MaxStack).FirstOrDefault();
            if (listToStore == null)
            {
                listToStore = new List<Int32>();
                listResult.Add(listToStore);
            }

            listToStore.Add(element);
        }

        // view
        foreach (List<Int32> list in listResult)
        {
            Console.Write("List " + (listResult.IndexOf(list) + 1) + "[total " + list.Sum() + "]: ");                
            foreach (Int32 element in list)
            {
                Console.Write(element.ToString() + " ");
            }

            Console.WriteLine();
        }

        Console.ReadKey();
    }
编辑:如果您希望列表达到180,可以在进程和视图之间添加(快速和错误)代码:

        // switching element for better fill
        List<List<Int32>> unfilledlist = listResult.Where(l => l.Sum() < MaxStack).ToList();
        // truncate original result
        unfilledlist.ForEach(l => listResult.Remove(l));

        while (unfilledlist != null && unfilledlist.Count > 1)
        {
            List<Int32> list = unfilledlist.First();
            unfilledlist.Remove(list);

            foreach (Int32 element in list)
            {
                Int32 needed = MaxStack - list.Sum() + element;
                Boolean isFound = false;

                foreach (List<Int32> smallerlist in unfilledlist)
                {
                    List<Int32> switchingList = new List<int>();

                    // searching how to fill what we needed
                    foreach (Int32 e in smallerlist.OrderByDescending(i => i))
                    {
                        if (e + switchingList.Sum() <= needed)
                            switchingList.Add(e);
                    }

                    // we found a possible switch
                    if (switchingList.Sum() == needed)
                    {
                        // moving first element
                        list.Remove(element);
                        smallerlist.Add(element);

                        // moving element
                        switchingList.ForEach(e => { smallerlist.Remove(e); list.Add(e); });
                        isFound = true;
                        break;
                    }
                }

                if (isFound)
                    break;
            }

            listResult.Add(list.OrderByDescending(i => i).ToList());
        }

        // completing result with lists that are not with sum 180
        unfilledlist.ForEach(l => listResult.Add(l.OrderByDescending(i => i).ToList()));

我认为列表中的值是按随机顺序排列的?我不确定我的想法是否正确。但是你知道背包的问题吗@太空苹果:你可以随机选择。侯赛因·纳里马尼的帖子看起来就像他的第二张名单应该包括的一样。有固定的时间吗?如果没有,有最小值和最大值吗?@Xaruth:9th列表中有175个小于180个。这个不行。我们能解决这个问题吗?你可以分析列表,并在不在180的列表之间切换项目(总数为180的列表以更好的方式填充,项目更大)。例如,切换列表9的45和列表10的30+10+10。但这是一个好方法吗?您不能确定总是能够以精确的180填充所有列表(例如:objects{10010010010050})。相反,如果你有很多小项目,你就不会有未填充的列表。我添加了一个用于切换元素的编辑代码,以便以更好的方式填充列表。
        // switching element for better fill
        List<List<Int32>> unfilledlist = listResult.Where(l => l.Sum() < MaxStack).ToList();
        // truncate original result
        unfilledlist.ForEach(l => listResult.Remove(l));

        while (unfilledlist != null && unfilledlist.Count > 1)
        {
            List<Int32> list = unfilledlist.First();
            unfilledlist.Remove(list);

            foreach (Int32 element in list)
            {
                Int32 needed = MaxStack - list.Sum() + element;
                Boolean isFound = false;

                foreach (List<Int32> smallerlist in unfilledlist)
                {
                    List<Int32> switchingList = new List<int>();

                    // searching how to fill what we needed
                    foreach (Int32 e in smallerlist.OrderByDescending(i => i))
                    {
                        if (e + switchingList.Sum() <= needed)
                            switchingList.Add(e);
                    }

                    // we found a possible switch
                    if (switchingList.Sum() == needed)
                    {
                        // moving first element
                        list.Remove(element);
                        smallerlist.Add(element);

                        // moving element
                        switchingList.ForEach(e => { smallerlist.Remove(e); list.Add(e); });
                        isFound = true;
                        break;
                    }
                }

                if (isFound)
                    break;
            }

            listResult.Add(list.OrderByDescending(i => i).ToList());
        }

        // completing result with lists that are not with sum 180
        unfilledlist.ForEach(l => listResult.Add(l.OrderByDescending(i => i).ToList()));
List 1[total 180]: 90 90
List 2[total 180]: 90 90
List 3[total 180]: 80 80 20
List 4[total 180]: 80 80 20
List 5[total 180]: 70 70 40
List 6[total 180]: 60 60 60
List 7[total 180]: 60 60 50 10
List 8[total 180]: 50 50 50 30
List 9[total 180]: 40 40 30 30 20 10 10
List 10[total 85]: 45 30 10