全排列生成算法Word格式文档下载.docx
- 文档编号:15374556
- 上传时间:2022-10-29
- 格式:DOCX
- 页数:8
- 大小:20.99KB
全排列生成算法Word格式文档下载.docx
《全排列生成算法Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《全排列生成算法Word格式文档下载.docx(8页珍藏版)》请在冰豆网上搜索。
1.求i=max{j|Pj-1<
Pj}2.求l=max{k|Pi-1<
Pk}3.
交换Pi-1与Pl得到P1P2…Pi-1(Pi....Pn),将红色部分顺序逆转,得到结果.例
求的下一个排列1.确定i,从左到右两两比较找出后一个数比前一个大的组合,在这里有3947,然后i取这些组中最到的位置号(不是最大的数)在这两组数中7的位置号最大为6,所以i=62.确定l,找出在i(包括i)后面的所有比i前面那一位大的数的最大的位置号,在此例中7,5都满足要求,则选5,5的位置号为7,所以
l=73.先将4和5交换,然后将5后的四位数倒转得到结果à
以上算法是在数论课上老师给出的关于字典序全排列的生成算法,以前也经常要用到全排列生成算法来生成一个全排列对所有的情况进行测试,每次都是现到网上找一个算法,然后直接copy代码,修改一下和自己的程序兼容就行了,也不看是怎么来的,不是我不想看,实在是说的很抽象,那一大堆公式来吓人,一个实例都不给,更有甚者连算法都没有,只是在那里说,想看都看不懂,也没那个耐心取理解那些人写出来的那种让人无法忍受的解释。
不过在说别人的同时我也知道,自己写的也不够好,不过这就是我的理解了,没法子写的再细了。
全排列的生成算法
2008年04月25日星期五下午03:
23
全排列的生成算法就是对于给定的字符集,用有效的方法将所有可能的全排列无重复无遗漏地枚举出来。
任何n个字符集的排列都可以与1~n的n个数字的排列一一对应,因此在此就以n个数字的排列为例说明排列的生成法。
n个字符的全体排列之间存在一个确定的线性顺序关系。
所有的排列中除最后一个排列外,都有一个后继;
除第一个排列外,都有一个前驱。
每个排列的后继都可以从它的前驱经过最少的变化而得到,全排列的生成算法就是从第一个排列开始逐个生成所有的排列的方法。
全排列的生成法通常有以下几种:
字典序法
递增进位数制法
递减进位数制法
邻位交换法
n进位制法
递归类算法
1.字典序法
字典序法中,对于数字1、2、3......n的排列,不同排列的先后关系是从左到右逐个比较对应的数字的先后来决定的。
例如对于5个数字的排列12354和12345,排列12345在前,排列12354在后。
按照这样的规定,5个数字的所有的排列中最前面的是12345,最后面的是54321。
字典序算法如下:
设P是1~n的一个全排列:
p=p1p2......pn=p1p2......pj-1pjpj+1......pk-1pkpk+1......pn
1)从排列的右端开始,找出第一个比右边数字小的数字的序号j(j从左端开始计算),即
j=max{i|pi<
pi+1}
2)在pj的右边的数字中,找出所有比pj大的数中最小的数字pk,即k=max{i|pi>
pj}(右边的数从右至左是递增的,因此k是所有大于pj的数字中序号最大者)
3)对换pi,pk
4)再将pj+1......pk-1pkpk+1pn倒转得到排列p'
=p1p2.....pj-1pjpn.....pk+1pkpk-1.....pj+1,这就是排列p的下一个下一个排列。
例如是数字1~9的一个排列。
从它生成下一个排列的步骤如下:
自右至左找出排列中第一个比右边数字小的数字4
在该数字后的数字中找出比4大的数中最小的一个5
将5与4交换
将7421倒转
所以的下一个排列是。
程序代码如下:
PrivateSubDict(p()AsInteger,ByValnAsInteger)
DimiAsInteger,jAsInteger
OutLp
i=n-1
DoWhilei>
0
Ifp(i)<
p(i+1)Then
Forj=nToi+1Step-1
'
从排列右端开始
Ifp(i)<
=p(j)ThenExitFor
找出递减子序列
Next
Swapp(i),p(j)
将递减子序列前的数字与序列中比它大的第一个数交换
Forj=nTo1Step-1
将这部分排列倒转
i=i+1
Ifi>
=jThenExitFor
Swapp(i),p(j)
OutLp
输出一个排列
i=n
EndIf
i=i-1
Loop
EndSub
Swapp(i),p(j)是交换两个元素的子过程,OutLp是输出排列的子过程。
2.递增进位数制法
在递增进位制数法中,从一个排列求另一个排列需要用到中介数。
如果用ki表示排列p1p2...pi...pn中元素pi的右边比pi小的数的个数,则排列的中介数就是对应的排列k1......ki......kn-1。
例如排列的中介数是,7、2、6、......分别是排列中数字8、3、9、......的右边比它小的数字个数。
中介数是计算排列的中间环节。
已知一个排列,要求下一个排列,首先确定其中介数,一个排列的后继,其中介数是原排列中介数加1,需要注意的是,如果中介数的末位kn-1+1=2,则要向前进位,一般情形,如果ki+1=n-i+1,则要进位,这就是所谓的递增进位制。
例如排列的中介数是,则下一个排列的中介数是+1=(因为1+1=2,所以向前进位,2+1=3,又发生进位,所以下一个中介数是)。
得到中介数后,可根据它还原对应得排列。
算法如下:
中介数k1、k2、......、kn-1的各位数字顺序表示排列中的数字n、n-1、......、2在排列中距右端的的空位数,因此,要按k1、k2、......、kn-1的值从右向左确定n、n-1、......、2的位置,并逐个放置在排列中:
i放在右起的ki+1位,如果某位已放有数字,则该位置不算在内,最后一个空位放1。
因此从可得到排列,它就是的后一个排列。
因为9最先放置,k1=6,9放在右起第7位,空出6个空位,然后是放8,k2=7,8放在右起第8位,但9占用一位,故8应放在右起第9位,余类推。
PrivateSubIncr(p()AsInteger,ByValnAsInteger)
Dimm()AsInteger
保存中介数的数组
DimaAsInteger
ReDimm(n)
Fori=1Ton
第一个排列的中介数为000......0
m(i)=0
DoWhilen>
Fori=1Ton
排列的各位为0
p(i)=0
Next
从右向左察看排列中为0的位
a=m(i)+1
j=n
DoWhilej>
Ifp(j)=0Then
a=a-1
Ifa=0ThenExitDo
0的个数决定数字i的位置
EndIf
j=j-1
p(j)=n-i+1
将数字i放置在指定位置
Next
OutLp
IfMedN(m)ThenExitDo
计算下一个中介数,如果是00...0,则全部排列找到
PrivateFunctionMedN(m()AsInteger)AsBoolean
计算中介数函数
DimiAsInteger,sumAsInteger
DimbAsBoolean
b=False
0
m(i)=m(i)+1
Ifm(i)<
n-i+1ThenExitDo
Sum=0
Fori=1Ton-1
计算中介数各位之和
Sum=Sum+m(i)
Next
IfSum=0Thenb=True
中介数各位之和为0
MedN=b
EndFunction
3.递减进位制数法
在递增进位制数法中,中介数的最低位是逢2进1,进位频繁,这是一个缺点。
把递增进位制数翻转,就得到递减进位制数。
的中介数是(k1k2…kn-1),倒转成为(kn-1…k2k1),这是递减进位制数的中介数:
ki(i=n-1,n-2,…,2)位逢i向ki-1位进1。
给定排列p,p的下一个排列的中介数定义为p的中介数加1。
例如p=,p的中介数为,p的下一个排列的中介数为+1=,由此得到p的下一个排列为。
给定中介数,可用与递增进位制数法类似的方法还原出排列。
但在递减进位制数中,可以不先计算中介数就直接从一个排列求出下一个排列。
具体算法如下:
1)如果p(i)=n且i<
>
n,则p(i)与p(i-1)交换
2)如果p(n)=n,则找出一个连续递减序列9、8、......、i,将其从排列左端删除,再以相反顺序加在排列右端,然后将i-1与左边的数字交换
例如p=的下一个排列是。
求的下一个排列时,因为9在最左边且第2位为8,第3位不是7,所以将8和9从小到大排于最右端,再将7与其左方数字对
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 排列 生成 算法