组合数元组编号

Posted Zetaa

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了组合数元组编号相关的知识,希望对你有一定的参考价值。

前言:仅个人小记。

问题描述

如何遍历 n n n个点中的所有 4 4 4元组呢,即如何遍历 ( n 4 ) \\binomn4 (4n)个不同的四元组呢?举例: n = 6 n=6 n=6,则所有的 4 4 4元组共有 ( 6 4 ) = 15 \\binom64=15 (46)=15个,具体为
( 1 , 2 , 3 , 4 ) ( 1 , 2 , 3 , 5 ) ( 1 , 2 , 3 , 6 ) ( 1 , 2 , 4 , 5 ) ( 1 , 2 , 4 , 6 ) ( 1 , 2 , 5 , 6 ) ( 1 , 3 , 4 , 5 ) ( 1 , 3 , 4 , 6 ) ( 1 , 3 , 5 , 6 ) ( 1 , 4 , 5 , 6 ) ( 2 , 3 , 4 , 5 ) ( 2 , 3 , 4 , 6 ) ( 2 , 4 , 5 , 6 ) ( 3 , 4 , 5 , 6 ) (1,2,3,4)\\\\(1,2,3,5)\\\\(1,2,3,6)\\\\(1,2,4,5)\\\\(1,2,4,6)\\\\(1,2,5,6)\\\\(1,3,4,5)\\\\(1,3,4,6)\\\\(1,3,5,6)\\\\(1,4,5,6)\\\\(2,3,4,5)\\\\(2,3,4,6)\\\\(2,4,5,6)\\\\(3,4,5,6) (1,2,3,4)(1,2,3,5)(1,2,3,6)(1,2,4,5)(1,2,4,6)(1,2,5,6)(1,3,4,5)(1,3,4,6)(1,3,5,6)(1,4,5,6)(2,3,4,5)(2,3,4,6)(2,4,5,6)(3,4,5,6)
现在,因为编程需要(必须需要对这些四元组给出一个序关系,便于比较等操作),故而希望对这些四元组进行编号,使得对四元组的操作转化为对一元编号的操作。具体地效果希望如下

( 1 , 2 , 3 , 4 ) → 1 ( 1 , 2 , 3 , 5 ) → 2 ( 1 , 2 , 3 , 6 ) → 3 ( 1 , 2 , 4 , 5 ) → 4 ( 1 , 2 , 4 , 6 ) → 5 ( 1 , 2 , 5 , 6 ) → 6 ( 1 , 3 , 4 , 5 ) → 7 ( 1 , 3 , 4 , 6 ) → 8 ( 1 , 3 , 5 , 6 ) → 9 ( 1 , 4 , 5 , 6 ) → 10 ( 2 , 3 , 4 , 5 ) → 11 ( 2 , 3 , 4 , 6 ) → 12 ( 2 , 3 , 5 , 6 ) → 13 ( 2 , 4 , 5 , 6 ) → 14 ( 3 , 4 , 5 , 6 ) → 15 (1,2,3,4)\\rightarrow1\\\\(1,2,3,5)\\rightarrow2\\\\(1,2,3,6)\\rightarrow3\\\\(1,2,4,5)\\rightarrow4\\\\(1,2,4,6)\\rightarrow5\\\\(1,2,5,6)\\rightarrow6\\\\(1,3,4,5)\\rightarrow7\\\\(1,3,4,6)\\rightarrow8\\\\(1,3,5,6)\\rightarrow9\\\\(1,4,5,6)\\rightarrow10\\\\(2,3,4,5)\\rightarrow11\\\\(2,3,4,6)\\rightarrow12\\\\(2,3,5,6)\\rightarrow13\\\\(2,4,5,6)\\rightarrow14\\\\(3,4,5,6)\\rightarrow15 (1,2,3,4)1(1,2,3,5)2(1,2,3,6)3(1,2,4,5)4(1,2,4,6)5(1,2,5,6)6(1,3,4,5)7(1,3,4,6)8(1,3,5,6)9(1,4,5,6)10(2,3,4,5)11(2,3,4,6)12(2,3,5,6)13(2,4,5,6)14(3,4,5,6)15
用于对组合数进行编号,抽象地看就是希望将一个四元组映射成一个编号 ( a , b , c , d ) → i s . t .   a < b < c < d (a,b,c,d)\\rightarrow i\\\\s.t.\\ a<b<c<d (a,b,c,d)is.t. a<b<c<d

方案

给出映射函数 p ( a , b , c , d , n ) = ∑ i = 1 a ( n − i 3 ) + ∑ i = 0 b − a − 2 ( n − b + i 2 ) + ∑ i = 0 c − b − 2 ( n − c + i 1 ) + ( d − c + 1 ) p(a,b,c,d,n)=\\sum_i=1^a\\binomn-i3+\\sum_i=0^b-a-2\\binomn-b+i2+\\sum_i=0^c-b-2\\binomn-c+i1+(d-c+1) p(a,b,c,d,n)=i=1a(3ni)+i=0ba2(2nb+i)+i=0cb2(1nc+i)+(dc+1)

程序实现

def combN(n,m):# 计算简单的组合数, n 选 m
    a = 1
    b = 1
    for i in range(1,m+1):
        b *= i
        a *= (n-i+1)
    return a//b

def p(a,b,c,d,n): # n 为总体数目 p(a,b,c,d,n) 表示从 n中选出 K4= a,b,c,d 并映射成的单值
    # 从 n 个数中选出 K4 个数,对 K4 进行编号
    index = 0
    for i in range(1,a+1):
        index += combN(n-i,3)

    for i in range(0,b-a-1):
        index += combN(n-b+i,2)

    for i in range(0,c-b-1):
        index += combN(n-c+i,1)
        
    index += (d-c-1)
    
    return index

小结

上述只是给出了从四元组到编号的映射,而实际上显然应该同样存在从编号到四元组的映射,本文并没有给出。

邮箱: officeforcsdn@163.com

以上是关于组合数元组编号的主要内容,如果未能解决你的问题,请参考以下文章

python时间和日期处理

有n个带编号的人和n个带编号的座位,求每个人都不坐在相同号码座位的方案数目

列表和元组)

Catalan数

Rust学习教程15 - 元组tuple

Rust学习教程15 - 元组tuple