n个竞争者竞赛中k个职位的安排

时间:2015-05-14 21:14:36

标签: java algorithm function math set

这是我在mathexchange.com上的帖子的副本。

E(n) 成为 n 的所有可能结束安排的集合em> 竞争对手

显然,因为这是一场比赛, n 竞争对手中的每一个都希望获胜。 因此,安排的顺序确实很重要。 我们还要说,如果两个竞争对手以相同的时间结束,他们会赢得相同的位置。

例如, E(3) 包含以下几组安排:

{(1,1,1),(1,1,2),(1,2,1),(1,2,2),(1,2,3),(1, 3,2),(2,1,1),(2,1,2),(2,1,3),(2,2,1),(2,3,1),(3,1, 2),(3,2,1)}。

毋庸置疑,例如,(1,3,3)的安排无效,因为据称的两个竞争者在第三名结束,实际上以第二名结束。所以上述安排"将" 转移到(1,2,2)。

k 定义为子集中竞争对手的不同 排名的数量 E(n)中。 我们有例如:

(1,1,1)-------> k = 1

(1,2,1)-------> k = 2

(1,2,3,2)-------> k = 3

(1,2,1,5,4,4,3)-------> k = 5

最后,让 M(n,k) 子集数量 em> E(n) 其中竞争对手以完全 k 不同的职位结束。

我们得到,例如, M(3,3)= M(3,2)= 6 M(3,1) )= 1

-------------------------------------------------------------------------------------------

到目前为止是问题

这是我自己想出的一个问题。经过一段时间的思考后,我想出了 | E(n)|: 的以下递归公式 (如果您想自己推导出公式,请不要继续阅读!)

| E(n)| = 从l = 1到n的C(n,l)* | E(nl)| 其中 | E(0)| = 1

这个函数的Java代码,使用BigInteger类:

public static BigInteger E (int n)
{
    if (!Ens[n].equals(BigInteger.ZERO))
        return Ens[n];
    else
    {
        BigInteger ends=BigInteger.ZERO;
        for (int l=1;l<=n;l++)
            ends=ends.add(factorials[n].divide(factorials[l].multiply(factorials[n-l])).multiply(E(n-l)));
        Ens[n]=ends;
        return ends;
    }
}

factorials 数组是一个预先计算的因子数组,用于更快的二项式系数计算。

Ens 数组是memoized / cached E(n) 值的数组,由于需要,它们可以真正加快计算速度重复计算某些 E(n) 值。

这种递归关系背后的逻辑是 l 象征着有多少&#34;第一&#34;我们有斑点。对于每个 l ,二项式系数 C(n,l)表示我们可以从多少种方式中选择 l 第一个位置< strong> n 竞争对手。一旦我们选择了它们,我们需要弄清楚我们可以在多少方面安排我们留下的 n-l 竞争对手,这只是 | E(n-l)| 。 我得到以下内容:

| E(3)| = 13

| E(5)| = 541

| E(10)| = 102247563

| E(100)| mod 1 000 000 007 = 619182829 -------&gt; 20毫秒。

和| E(1000)| mod 1 000 000 007 = 581423957 -------&gt; 39秒

我发现 | E(n)| 也可以显示为以下适用的套数:

对于每个 i = 1,2,3 ... n ,原始集的每个 i-tuple 子集都具有GCD(最大公约数)它的元素等于1。 但我对此并不是100%肯定,因为我无法为大 n 计算此方法。 然而,即使使用预先计算因子并记忆 E(n),高 n 的计算时间也会非常快。 有人能够验证上述公式和价值吗? 任何人都可以获得更好,更快的公式吗?也许产生功能?

至于 M(n,k) ..我完全无能为力。我绝对不知道如何计算它,因此我无法发布任何有意义的数据点。 也许它的 P(n,k)= n!/(n-k)! 任何人都可以找出 M(n,k) 的公式吗?

我不知道哪个函数难以计算, E(n) M(n,k) ,但帮助我解决其中任何一个都会非常明显。

我希望这些解决方案既通用又有效,即使对于大型 n 也是如此。不幸的是,详尽的搜索并不是我所寻找的。 我正在寻找的是纯粹基于组合方法和有效公式的解决方案。

我希望自己能够清楚地了解我的帖子中的措辞和要求。顺便说一句,我可以用Java编程。我也非常了解Mathematica :)。

提前多多感谢,

马坦。

1 个答案:

答案 0 :(得分:3)

E(n)是Fubini numbers。 M(n,k)= S(n,k)* k !,其中S(n,k)是Stirling number of the second kind,因为S(n,k)是不同放置分区的数量,并且k!是排名的方式的数量。