生成排列
Stirling公式:n! ~ sqrt(2*π*n)(n/e)n
生成算法1:Johnson,Trotter
要生成全排列n,则在全排列n-1上,每个排列用插空法插入n
n=2:
1 2
2 1
n=3:
1 2 3
1 3 2
3 1 2
3 2 1
2 3 1
2 1 3
生成算法2:S.Even, Algorithm Combinatorics, 1973
如果一个数k的箭头指向一个比他小的相邻的数,那么称k是活动的
对于1..n的序列中的整数n,除以下两种情况外,n总是活动的
1. n在最左边,n的箭头指向左
2. n在最右边,n的箭头指向右
生成方法:从123..n开始(每个肩头初始指向左),做:
1. 求出最大的活动整数m
2. 交换m和其指向的整数
3. 交换所有p>m的整数p的方向
直到序列中没有活动整数为止。
生成组合
生成所有组合方案:
基2算法:
从an-1..a2a1a0=00..0开始,当an-1..a2a1a0!=11..1,做
1. 求出最小的j使得aj=0
2. 用1替换aj并用0替换所有aj-1aj-2..a0
生成的序称为n元组的字典序
Gray码生成:
算法1:
1. 1阶Gray码是0, 1
2. 假设n-1阶Gray码已经生成,首先给n-1阶Gray码前面加0,再给逆序n-1阶Gray码前面加1。
算法2:
从an-1..a2a1a0=00..0开始,当an-1..a2a1a0!=10..0,做
1. 如果σ(an-1..a1a0)为偶数,则改变a0
2. 否则,找最小的j使得aj=1,改变aj+1
生成r-组合:
令 a1a2..ar是1..n的一个组合。字典序中,第一个组合是12..r。当a1a2..ar不是(n-r+1)(n-r+2)..n,令k是满足ak+1<=n且ak+1不是a1, a2..ar的最大整数,使用序列a1a2..ak-1(ak+1)(ak+2)..(ak+r-k+1)
例如:n=6的4组合中,1234的下一个组合是1235,2356的下一个组合是2456