最接近记录与所需值的总和

时间:2015-01-06 12:33:37

标签: c# algorithm sum expression

如何编写该方法具有以下结果,如何创建Filter metod?最接近记录与所需值的总和

class Program
{
public Program()
{
    List<item> items = new List<item>() 
    {
        new item () { Id = 11 , Value = 100},
        new item () { Id = 12 , Value = 300},
        new item () { Id = 13 , Value = 10},
        new item () { Id = 14 , Value = 20},
        new item () { Id = 15 , Value = 200},
        new item () { Id = 16 , Value = 600},
        new item () { Id = 17 , Value = 7},
        new item () { Id = 18 , Value = 3},
        new item () { Id = 19 , Value = 3},
        new item () { Id = 20 , Value = 2},
        new item () { Id = 21 , Value = 70},
        new item () { Id = 22 , Value = 200},
        new item () { Id = 23 , Value = 300},
        new item () { Id = 24 , Value = 250},
        new item () { Id = 25 , Value = 900},
        new item () { Id = 26 , Value = 700},
        new item () { Id = 27 , Value = 400},
    };

    var list_1 = items.Filter(1000);    //expect id : 11,12,16
    var list_2 = items.Filter(25);      //expect id : 13,17,18,19,20
    var list_3 = items.Filter(400);     //expect id : 11,12
    var list_4 = items.Filter(1935);    //expect id : 11,12,13,14,15,16,18,20,25
    var list_5 = items.Filter(101);     //expect id : 11
    var list_6 = items.Filter(150);     //expect id : 11,13,14,17,18,19,20

}

2 个答案:

答案 0 :(得分:2)

这是0/1 Knapsack Problem的变体,它在两个空间都有一个伪多项式的解,即O(k),而时间是O(Tk),其中k是项目数,T是预期数字。

上面链接的文章有简单的伪代码来解决问题。您应该修改它以使用一对单维数组而不是2D数组来节省内存。这是可能的,因为每次迭代最多引用2D数组中的两行 - 正在构造的那一行,以及紧接在它前面的那一行。

该算法构造一个可达总数的数组。您可以反向运行算法以提取导致您要过滤的特定结果的ID序列。

答案 1 :(得分:0)

您需要分步处理

  1. 按值降序排列列表
  2. 迭代列表,直到达到等于或小于过滤值的第一个值
  3. 创建剩余项目的列表并将它们组合在一起,直到分组项目的总和等于或超过过滤器值
  4. 最后,检查总和是否超过过滤器值,如果是,请删除值最小的项目
  5. 继续迭代,直到列表为空或直到您有完全匹配
  6. 注意:这是一个简单的实现,因为它将得到一个紧密匹配而不是完全匹配,如下所示:

    values: 3,5,7,9,11
    
    filter value: 19
    
    returns 11, 7 (total : 18)
    

    一个更好的算法会返回11, 5, 3 (total: 19),但这会在计算上更加昂贵,需要多次迭代这些值。

    您的方案的准确性有多重要?