【问题标题】:Java maths, working out total combinations [closed]Java数学,计算总组合[关闭]
【发布时间】:2012-12-17 17:48:03
【问题描述】:

我计算出一种方法的所有可能组合的最简单方法是什么?这是我正在尝试解决的示例类;

class Combinations {

    public void generate()
    {
        final int TOTAL_A = 10;
        final int TOTAL_B = 21; // TOTAL_B is used twice
        final int TOTAL_C = 17;
        final int TOTAL_Z = 20;
        int count = 0;
        for (int a = 0; a < TOTAL_A; a++)
        {
            for (int b = 0; b < TOTAL_B; b++)
            {
                for (int b_two = 0; b_two < TOTAL_B; b_two++)
                {
                    for (int c = 0; c < TOTAL_C; c++)
                    {
                        for (int one = 0; one < TOTAL_Z; one++)
                            for (int two = one + 1; two < TOTAL_Z; two++)
                                for (int three = two + 1; three < TOTAL_Z; three++)
                                    for (int four = three + 1; four < TOTAL_Z; four++)
                                        for (int five = four + 1; five < TOTAL_Z; five++)
                                            count++;
                    }
                }
            }
        }
        System.out.println("Total combinations: " + count);
    }

}

在不必实际执行循环的情况下找出“计数”的方法是什么?

【问题讨论】:

  • 你为什么不用文字来解释你想要计算的究竟是什么?
  • 我正在尝试解决一个拼图组合,它需要前 4 个循环中的 4 个唯一对象,第二个对象与第三个对象具有相同的资源大小。在此之后,我必须选择 5 个其他唯一的对象,例如,它们不能具有相同的对象。这就是最后一个数字的 + 1 的来源。
  • 一个更好的解释,如果可能的话?反正你在做 8 个嵌套的 for 循环,那可能是错的。
  • 你是问有多少不同的组合存在给定计数 A、B1、B2、C 和 Z,其中 B1 和 B2 的大小相同?
  • 请花一些时间修改您的问题并更好地解释您想要做什么。就目前的问题而言,即使您试图在 cmets 中澄清,也非常不清楚。

标签: java math recursion combinations


【解决方案1】:
|A| * (|B| choose 2) * |C| * (|Z| choose 5) = 553,492,800

或者,如果您想从具有相同大小的两个不同池 B1 和 B2 中进行选择:

|A| * |B1| * |B2| * |C| * (|Z| choose 5) = 1,162,334,880

其中n choose k定义如下:

n!/(k!*(n-k)!)

【讨论】:

  • 感谢您的回答,并且对排列组合进行了更深入的研究,并找到了与所示相同的数组。但是,我还没有想出将这种类型的算法转换为 Java 代码的方法,所以我暂时保留这个问题。谢谢。
  • 没关系,找到了一个 Apache 库,它有一种计算方法,非常感谢!
【解决方案2】:

外部循环a, b, b_two, c 根本不会影响内部循环中所做的事情,因此它们只会产生重复因素,

TOTAL_A * TOTAL_B² * TOTAL_C

你乘以内部循环的工作。

内部循环,one, two, three, four, five 影响或依赖于其他循环。每个循环都决定了封闭循环的范围,所以你自然会从里到外工作。

for (int five = four + 1; five < TOTAL_Z; five++)
     count++;

所以最里面的循环增加count 总共TOTAL_Z - 1 - four 次。为简洁起见,让我们用N 表示TOTAL_Z - 1。

four 循环确实

N - four

four 的增量范围从 three+1 到 N,

    N             N-three-1
    ∑ (N - four) =    ∑ k    = (N-three)*(N-three-1)/2
four=three+1         k=0

three 循环对three 执行(N-three)*(N-three-1)/2 递增,范围从two+1 到N。设置j = N - three,这给出了

N-two-1
  ∑    j*(j-1)/2 = (N-two)*(N-two-1)*(N-two-2)/6
 j=0

two 循环对two 执行(N-two)*(N-two-1)*(N-two-2)/6 增量,范围从one+1 到N,设置j = N - two,这给出了

N-one-1
   ∑   j*(j-1)*(j-2)/6 = (N-one)*(N-one-1)*(N-one-2)*(N-one-3)/24
  j=0

最后,one 循环对one 进行上述增量,范围从 0 到 N,给出

   N                                            N
   ∑ (N-one)*(N-one-1)*(N-one-2)*(N-one-3)/24 = ∑ k*(k-1)*(k-2)*(k-3)/24
one=0                                          k=0
                                              =  (N+1)*N*(N-1)*(N-2)*(N-3)/120

(或(N+1) `choose` 5)在内循环中一起递增。

N = TOTAL_Z - 1 = 19,20 `choose` 5 = 15504,与外部循环的常数相乘,总共得到 1162334880 个增量 count。

这里允许进行简单计算的关键事实是

 m
 ∑   (n+k) `choose` k = (n+m+1) `choose` m
k=0

【讨论】:

    猜你喜欢
    • 2021-10-23
    • 2013-01-29
    • 1970-01-01
    • 2013-10-06
    • 1970-01-01
    • 1970-01-01
    • 2022-01-01
    • 1970-01-01
    • 2011-06-08
    相关资源
    最近更新 更多