计算一组序列号的第n个组合



我有一个数字n,我的程序用它来表示大小为n:的自然数列表

[0,1,2] // n=3
[0,1,2,3,4,5] // n=6

列表总是以0开头,并且它们的元素按顺序显示,不跳过任何数字。最后一个元素始终是(n-1)

现在,我需要获得这些数组的唯一元素对。因此,我编写了一个算法,将n作为输入,并从上面的对应项返回一个由唯一元素对组成的数组。

[[0,1],[0,2],[1,2]] // n=3
[[0,1],[0,2],[0,3],[0,4],[0,5],[1,2],[1,3],[1,4],[1,5],[2,3],[2,4],[2,5],[3,4],[3,5],[4,5]] // n=6

在该实现中,元素不能与其自身配对(例如[0,0](。对[1,2]被认为等同于[2,1],因此只有前者会出现。

然而,由于这些对具有一致的排序并遵循基本模式,我怀疑有一些数字公式可以直接用于计算它们的,而无需通过编程创建它们的列表。

我想要的是一个函数f(n,i),它会给我n的对数组中第10对CCD_中的值,例如:

f(3,2) => [1,2]
f(6,8) => [1,5]

或者,也可以有两个函数:一个是g(n,i),它返回第一个pair元素,另一个h(n,i),它返回第二个。像这样:

g(3,2) => 1
h(3,2) => 2
g(6,8) => 1
h(6,8) => 5

有没有一个公式可以计算这些数字?

注意:我不是在寻找生成组合数组的算法。我已经有了。我希望避免生成数组组合,只需直接用数字计算组合值。

f(n, i):
m = (n - 1) * n / 2 # error check i <= m
i = m - i # zero-based index
t = floor((sqrt(8 * i + 1) - 1) / 2)
r = i - t * (t + 1) / 2
[n - t - 2, n - r - 1]

诀窍是从最后开始倒计数。否则,你基本上是在寻找i之前的三角形数,并相对于它进行计算。

维基百科有许多关于三角根的属性,包括上面用来推导三角根的公式。

倒三角数的基本思想归功于@shawnt00;我用x = (sqrt(8*i + 1) - 1)//2作为三角根,计算出了。

def find(n, i):
m = n * (n - 1) // 2
i = m - i - 1
t = (sqrt(8 * i + 1) - 1)//2
return (n - t - 2, n - 1 - (i - t * (t + 1) // 2))

最新更新