【问题标题】:How to find all subset which is the summation of its elements equals to a constant number?如何找到其元素之和等于常数的所有子集?
【发布时间】:2016-10-19 21:53:39
【问题描述】:

我需要找到所有数字子集以通过对其元素求和来获得一个数字 N。我不知道如何解决这种类型的组合问题。在这种组合中,不同数字的顺序很重要。

数字示例N=4

1 + 1 + 1 + 1
2 + 1 + 1
1 + 2 + 1
1 + 1 + 2
2 + 2
3 + 1
1 + 3

零对我来说并不重要。那么我怎样才能得到这样的数字集作为一个精确数字的数组呢?

【问题讨论】:

  • 请澄清您的具体问题或添加其他详细信息以准确突出您的需要。正如目前所写的那样,很难准确地说出你在问什么。同时向我们展示你到目前为止所做的工作
  • 看起来很像家庭作业。无论如何,你应该提供你迄今为止尝试过的东西,所以不会在没有部分尝试的情况下继续解决你的算法。
  • 说这样的话很不礼貌。我正在尝试开发一款名为 101 OKEY 的土耳其游戏。游戏有 21 张牌,因此我给出了一个确切的数字。我需要这些组合来计算将瓷砖系列与不同点分开的最佳点。
  • 您可以start with this answer,它会为您提供所有独特的结果。对该答案进行一些小的修改应该可以满足您的需要。
  • 也可以看看partitioning (number theory)——你会在 google 上找到几个 C# 实现和实现它的方法。

标签: c# combinations subset-sum


【解决方案1】:

您要查找的内容称为整数compositions,或有序partitions

组合可以递归生成(按字典顺序,如果我没记错的话)如下:

public static IEnumerable<List<int>> Compositions(int n)
{
    if (n < 0)
        throw new ArgumentOutOfRangeException(nameof(n));

    return GenerateCompositions(n, new List<int>());
}

private static IEnumerable<List<int>> GenerateCompositions(int n, List<int> comp)
{
    if (n == 0)
    {
        yield return new List<int>(comp); // important: must make a copy here
    }
    else
    {
        for (int k = 1; k <= n; k++)
        {
            comp.Add(k);

            foreach (var c in GenerateCompositions(n - k, comp)) 
                yield return c;

            comp.RemoveAt(comp.Count - 1);
        }
    }
}

未经测试!这是从 Python 实现转录而来的。如果有人想用更惯用的 C# 进行更正或更新代码,请随意。

另外,as @aah notedn 的合成数量是2^(n-1),所以即使对于普通的n,这也会变得笨拙。

【讨论】:

  • 您的代码是正确的。无需进行更正。谢谢!
【解决方案2】:

如果顺序无关紧要,则只有 2^(N-1) 种可能性。 (您的示例没有 2 + 2 或 4)

然后你可以用它的二进制表示来表示任何序列。要生成,想象 N 1 连续,所以它们之间有 N-1 个“空格”。选择任何空间子集,您可以合并通过所选空间相邻的任何 1。您可以通过扩展任何此类序列并插入这些空格来验证这对所有可能的集合是 1-1。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多