获得所有组合的最有效方法是什么?

时间:2011-07-21 18:14:21

标签: algorithm

  

可能重复:
  Finding all possible combinations of numbers to reach a given sum

问题

您有一个人员列表作为输入,每个人都有一些学分。您需要通过使用一个或多个人员积分来获得总额。该函数应输出将导致总数的所有组合。

例如见下文: -

static void Main(string[] args)
{
    int total = Convert.ToInt32(args[0]);
    var persons = new List<Person>();
    persons.Add(new Person { Credits = 10, Name="Steve"});
    persons.Add(new Person { Credits = 5, Name = "Paul" });
    persons.Add(new Person { Credits = 4, Name = "David" });
    persons.Add(new Person { Credits = 1, Name = "Kenneth" });

    PrintAllCombinations(persons, total); // The function in question
}
public class Person
{
    public string Name { get; set; }
    public int Credits { get; set; }
}

在上面的例子中,总共有10个,PrintAllCombinations函数应该输出类似于: -

  • 组合1)Steve:10
  • 组合2)Paul:5,David 4,Kenneth 1
  • 组合3)史蒂夫:9,保罗1
  • 组合4)史蒂夫:5,保罗5
  • ...等

更新:我忘了提及,你可以使用任何人的学分

我使用的示例已经过简化,但实际情况将限制为不超过100人,总数将始终小于90.

什么是最佳解决方案?

2 个答案:

答案 0 :(得分:2)

您可以在PythonJavaHaskell

中阅读这个无处不在的问题的解决方案

Finding all possible combinations of numbers to reach a given sum


根据您的编辑指定您可以获得部分学分,您还应该看看这篇文章:

generate a list of combinations/sets of numbers with limited supplies

用C语言写的

My solution同样适用于您的情况。

答案 1 :(得分:0)

由于背包问题是NP完成的,因此在一般情况下没有一种有效的算法。但是,由于学分数很少,您可以使用动态编程来记忆以下功能:

F(N, W) := can we add up to W, using only the first N people?

F(0, 0) = True
F(0, _) = False
F(N, W) = F(N-1, W) || F(N-1, W-w[N])