我知道如何计算给定n和k的binomial coefficient(我使用了一个库)。 现在假设您将所有这些组合存储在数组中。每个组合都有一个索引。我实际上并不需要将它们存储在一个数组中,但我需要知道,如果我要存储它们,那么每个组合的数组索引是什么。
E.g。给定一组C(n,k)可能组合的元素,我需要一个函数,它给出了它在数组中的索引i,但实际上并没有创建整个数组。编程语言并不重要,虽然我需要在java中实现该函数,但任何(伪)语言算法都可以,我会将它翻译成java。
例如,在n = 5且k = 2的情况下,我凭经验将此函数f(n, k, [a,b]) => N
定义为:
f(5, 2, [1,2]) = 0
f(5, 2, [1,3]) = 1
f(5, 2, [1,4]) = 2
f(5, 2, [1,5]) = 3
f(5, 2, [2,3]) = 4
f(5, 2, [2,4]) = 5
f(5, 2, [2,5]) = 6
f(5, 2, [3,4]) = 7
f(5, 2, [3,5]) = 8
f(5, 2, [4,5]) = 9
意味着(3,5)组合将占据数组中的索引8。另一个n = 5和k = 3的例子是f(n, k, [a,b,c]) => N
,根据经验定义为
f(5, 3, [1,2,3]) = 0
f(5, 3, [1,2,4]) = 1
f(5, 3, [1,2,5]) = 2
f(5, 3, [1,3,4]) = 3
f(5, 3, [1,3,5]) = 4
f(5, 3, [1,4,5]) = 5
f(5, 3, [2,3,4]) = 6
f(5, 3, [2,3,5]) = 7
f(5, 3, [2,4,5]) = 8
f(5, 3, [3,4,5]) = 9
评论后编辑澄清:
在上面的例子中,[1,2,3],[2,4,5]等是C(n,k)集的元素之一,例如, n个可能数字中k个数的可能组合之一。该函数需要它们才能在数组中计算它们的索引。
但是我需要为n和k的通用值编写此函数,而不创建数组。也许这种功能已经存在于某些组合微积分库中,但我甚至都不知道如何调用它。
答案 0 :(得分:1)
您应该查看combinatorial number system,部分"组合中的位置"特别是。
甚至还有一个例子,它可以帮到你:National Lottery example in Excel。 (对不起,但我不能在这里打字。)
在你的情况下,这将是
f(5, 3, [2,3,4]) = binom(5,3) - 1 - binom(5-2,3) - binom(5-3,2) - binom(5-4,1) =
= 10 - 1 - 1 - 1 - 1 = 6
或者如果您接受颠倒的顺序,则可以省略binom(5,3) - 1
部分并计算
f'(5, 3, [2,3,4]) = binom(5-2,3) + binom(5-3,2) + binom(5-4,1) - 1 =
= 1 + 1 + 1 - 1 = 2
(这应该可以节省一些时间,因为这里不需要binom(5, 3)
。)
在Java中,方法可以是
int f(int n, int k, int[] vars) {
int res = binom(n, k) - 1;
for(int i = 0; i < k; i++) {
res -= binom(n - vars[i], k - i);
}
return res;
}
或
int fPrime(int n, int k, int[] vars) {
int res = -1;
for(int i = 0; i < k; i++) {
res += binom(n - vars[i], k - i);
}
return res;
}
为int binom(int n, int k)
假设方法binom(n, k) = 0
和n < k
。