具有上限和下限的Powerset

时间:2015-05-26 16:44:12

标签: c# linq

我有一个过程,我需要找到符合特定标准的所有最佳组合。 Powersets是我认为我正在寻找的,但我想建立一些过滤器来避免数百万的结果。

例如,我有以下对象:

public class CableReel
    {
        public string ReelId { get; set; }
        public int Length { get; set; }
    }

我想得到一个上述对象的powerset,其中组合长度也符合下限和上限。

以下列表:

“a”,5200 “b”,2500 “c”,1000

我想加入以下限制,最小3000,最大5000.我想只看到BC组合。

我找到了以下用于返回通用powersets的代码:

public IEnumerable<IEnumerable<T>> GetPowerSet<T>(List<T> list)
    {
        return from m in Enumerable.Range(0, 1 << list.Count)
               select
                 from i in Enumerable.Range(0, list.Count)
                 where (m & (1 << i)) != 0
                 select list[i];
    }

我只是想知道如何调整它以完成我想做的事情?

解决方案:

使用Alex Sikilinda的建议我想出了:

var ls = new List<CableReel>
            {
                new CableReel{Length = 5,ReelId = "A"},
                new CableReel{Length = 3,ReelId = "B"},
                new CableReel{Length = 2,ReelId = "C"},
                new CableReel{Length = 7,ReelId = "e"},
                new CableReel{Length = 3,ReelId = "f"},
                new CableReel{Length = 2,ReelId = "g"}

            };
    var p = GetPowerSet(ls).Where(psl => psl.Sum(ps => ps.Length) > 5 && psl.Sum(ps => ps.Length) < 8);

1 个答案:

答案 0 :(得分:0)

假设您的powerset代码正常,您可以在调用方法之前过滤列表:

var filteredList = list.Where(e => e > 4000 || e < 5000);
var result = GetPowerSet(filteredList.ToList());

编辑: 因为您想要过滤不是元素,而是过滤,您可以过滤结果。 此代码演示了如何过滤集合,其总和大于2:

    public static IEnumerable<IEnumerable<T>> GetPowerSet<T>(List<T> list,       Func<IEnumerable<T>, Boolean> filter)
    {
        var fullPowerSet = from m in Enumerable.Range(0, 1 << list.Count)
                     select
                       from i in Enumerable.Range(0, list.Count)
                       where (m & (1 << i)) != 0
                       select list[i];

        return fullPowerSet.Where(e => filter(e));
    }

    static void Main(String[] args)
    {
        List<Int32> inputList = new List<Int32>()
        {
            1,2
        };

        var result = GetPowerSet(inputList, ps => ps.Sum() > 1);
    }

现在,您可以更改代理ps => ps.Sum() > 1以获得所需内容。