生成供应有限的组合/数字组列表

时间:2011-07-18 18:17:05

标签: combinations combinatorics

假设我有1个红球,1个蓝色球,2个黄球和3个绿球,总共7个球。

我想从七人组中选出3个球。我有多少种方法可以做到这一点?

当我手动计算时,我得到了11组/套。即123 124 133 134 144 233 234 244 334 344 444

生成和显示所有这些组合/集的有效方法是什么?

请注意,唯一性适用,因此(yellow, red, yellow) = (yellow, yellow, red)

2 个答案:

答案 0 :(得分:2)

第二,我建议使用生成函数方法。

  • 红球的数量可以是:0,1
  • 蓝球的数量可以是:0,1
  • 黄球的数量可以是:0,1,2
  • 绿球的数量可以是:0,1,2,3

因此,您想扩展以下多项式

(1 + x) * (1 + x) * (1 + x + x^2) * (1 + x + x^2 + x^3)

并查看x^3的系数,因为你想要总共3个球。

这将为您提供执行此操作的方法的数量,并且从每个带括号的表达式中获取一个项的获取系数的方式将告诉您如何进行组合。这是有效的,因为选择01红球与分别从第一个词1选择x(1 + x)相同,同样选择{{ 1}}绿球意味着从上一个术语中选择术语i。然后,所选球的总数是指数的总和。由于你想要x^i个球,你应该在扩展这个多项式时查看3的系数:

x^3

因此,来自给定集合的1 + 4x + 8x^2 + 11x^3 + 11x^4 + 8x^5 + 4x^6 + x^7 球的11种可能组合。

要迭代各种可能性,您只需按顺序从表达式中选择一个术语:

3

在此示例中,前两个int count = 0; for (int r=0; r<=1 && r<=3; ++r) { for (int b=0; b<=1 && r+b<=3; ++b) { for (int y=0; y<=2 && r+b+y<=3 ; ++y) { for (int g=0; g<=3 && r+b+y+g==3; ++g) { count++; printf(" red: %d\n blue: %d\nyellow: %d\n green: %d",r,b,y,g); } } } } return count; 循环(forr<=3)中的第二个条件是不必要的,但我将其留下来说明问题可以如何推广。< / p>

答案 1 :(得分:1)

generate_combinations(a1, a2, a3, a4, c1, c2, c3, c4)
1. if a1 + a2 + a3 + a4 = 3 then print (a1, a2, a3, a4)
2. else then
3.    if c1 > 0 then generate_combinations(a1+1, a2, a3, a4, c1-1, c2, c3, c4)
4.    if c2 > 0 then generate_combinations(a1, a2+1, a3, a4, c1, c2-1, c3, c4)
5.    if c3 > 0 then generate_combinations(a1, a2, a3+1, a4, c1, c2, c3-1, c4)
6.    if c4 > 0 then generate_combinations(a1, a2, a3, a4+1, c1, c2, c3, c4-1)

或类似的东西。虽然这不会重复,但是......我想你可以添加一些逻辑来过滤掉那些重复的东西。也许后期处理?

一些澄清:这是通过保持(1)手中的球和(2)球中的球的计数。它确保手+包=每种颜色的原始。用一个最初空的手来调用它,它将以你手上可以有三个球的方式打印。

如果你真的想确保算法只提供唯一的算法(而不是将其与算法结合使用以从列表中删除重复项),你可以确保不添加任何例子。如果你已经添加了任何更高阶的球(例如,如果a2> 0和a1 = 0,那么你不需要添加任何红色),你手上的红球。