C# 按'分组;等额和';

C# 按'分组;等额和';,c#,linq,grouping,C#,Linq,Grouping,我试图获取一个数字列表,并将它们放入>=N组中,这样每个组的总和大致相等(但不一定完全相等),并且“异常值”可以在它们自己的一组中 因此,对于3个群体的目标和类似以下内容的输入: [3, 2, 1, 4, 2, 5] 输出可能是: [[5,1], [4,2], [3,2]] 每组的各自总和为: 6, 6, 5 我想我已经把方法学搞定了,因为伪代码看起来像这样: let target = Ceil(Sum(Series) / NumberOfTargetGroups) //The ideal

我试图获取一个数字列表,并将它们放入>=N组中,这样每个组的总和大致相等(但不一定完全相等),并且“异常值”可以在它们自己的一组中

因此,对于3个群体的目标和类似以下内容的输入:

[3, 2, 1, 4, 2, 5]
输出可能是:

[[5,1], [4,2], [3,2]]
每组的各自总和为:

6, 6, 5
我想我已经把方法学搞定了,因为伪代码看起来像这样:

let target = Ceil(Sum(Series) / NumberOfTargetGroups) //The ideal size of each group

while (count(UnpickedNumbers) > 0)
    let CurrentGroup = new group
    while (sum(CurrentGroup) < target)
        for each Unpicked in sortDesc(UnpickedNumbers)
            if (sum(CurrentGroup) + Unpicked)
                Add Unpicked to current group
                Remove unpicked from available numbers
let target=Ceil(Sum(Series)/NumberOfTargetGroups)//每个组的理想大小
而(计数(未拼接编号)>0)
让CurrentGroup=新组
while(总和(当前组)

我搞不懂的是如何将该逻辑转换成一个
GroupBy(n=>…)
——之所以要这样做,是因为数字列表实际上来自一系列我想以这种方式分组的对象的属性。

分区是NP完全问题。 我有一个prepred片段:

public IEnumerable<IEnumerable<TObject>> Algo<TObject>(IEnumerable<TObject> source, int groups,
                                                       Func<TObject, int> intSelector)
{
    if (source == null)
    {
        throw new ArgumentNullException("source");
    }

    source = source.OrderByDescending(intSelector);
    var evaluated = source as IList<TObject> ?? source.ToList();
    if (groups > evaluated.Count())
    {
        throw new ArgumentException("Invalid group count.");
    }

    var result = new List<List<TObject>>();
    for (var i = 0; i < groups; i++)
    {
        result.Add(new List<TObject> { evaluated[i] });
    }

    for (var i = groups; i < evaluated.Count(); i++)
    {
        var bestIndex = 0;
        var bestSum = result[bestIndex].Sum(intSelector);
        for (var j = 1; j < result.Count; j++)
        {
            var sum = result[j].Sum(intSelector);
            if (sum < bestSum)
            {
                bestSum = sum;
                bestIndex = j;
            }
        }

        result[bestIndex].Add(evaluated[i]);
    }

    return result;
}

这很好地实现了它,但我仍然不知道如何将它与GroupBy()一起使用,以便在我的对象上使用它。假设我是通过Widget.Height属性对IEnumerable进行分组的。@PhonicUK还有什么,你不必使用
GroupBy
:)@L.B好吧,如果OP或其他读者学不到任何东西,那就是他们的损失:)重要的是我学到了一些东西:)
var widgets = new List<Widget>  { W1, W2, etc. };
var result = Algo(widgets, groups: 3, intSelector: widget => widget.Height);