再议“生成全排列算法”

  看了“白话算法(7) 生成全排列的几种思路(一)”和“白话算法(7) 生成全排列的几种思路(二) 康托展开”。在此,将以前本人推导的全排列算法介绍一下,和广大的网友交流一下。

  以例子说明,用0、1、2、3,四个数组成全排列。

  首先可以知道,这四个数组成的全排列一共有4!=24个。那么给这24个全排列编号,分别为0、1、2……23。再给定一个算法,通过编号计算出一个全排列。本文的目的就是找到这样的算法。

  把所有的全排列列举出来可以发现,0在末位的有6个,1在末位的有6个,等等。

  观察0在末位的六个,分别是

  1、2、3、0

  1、3、2、0

  2、1、3、0

  2、3、1、0

  3、1、2、0

  3、2、1、0

  可以看出这6个全排列,除了末位是0外,前面三个数正好是1、2、3的全排列

  再观察1在末位的六个,分别是

  0、2、3、1

  0、3、2、1

  2、0、3、1

  2、3、0、1

  3、0、2、1

  3、2、0、1

  也可以看出这6个全排列,除了末位是1外,前面三个数正好是0、2、3的全排列

  类似的,末位是2和3的6个全排列,除了末位是一样的以外,前面三个数正好是剩下的三个数的全排列。

  

  于是该问题就可以用下面的步骤来解决。

  1、根据编号确定末位数字

  2、确定末位数字后,获得剩余的数字

  3、对编号适当的处理,得到新的编号

  4、问题演化成除了末位数字后,用新的编号和剩余的数字,计算剩余数字的全排列。

 

  再用一个具体的例子来说明。比方说,用编号13来计算0、1、2、3的一个全排列。

  1、先给这4个数字排好序。是0、1、2、3

  2、计算[13/3!]+1=3,表示末位数是第3个数。注:[X]表示取X的整数部分。

  3、把第3个数和第4个数(未排的最后1个数)交换。此时,数字的顺序是0、1、3、2。蓝色的表示已经排好。

  4、新的编号为13 mod 3!=1

  5、计算[1/2!]+1=1,表示末位数是第1个数。

  6、把第1个数和第3个数(未排的最后1个数)交换。此时,数字的顺序是3、1、0、2。蓝色的表示已经排好。

  7、新的编号为1 mod 2!=1

  8、计算[1/1!]+1=2,表示末位数是第2个数。

  9、把第2个数和第2个数(未排的最后1个数)交换。此时,数字的顺序是3、1、0、2。蓝色的表示已经排好。

  10、因为只剩下一个数,所以编号13对应的全排列就是3、1、0、2

 

  其他的编号计算方法和此一样。

  后面的这个表格就是按照上面的算法得到所有的编号和全排列的关系

A(0) A(1) A(2) A(3) 编号
1 2 3 0 0
2 1 3 0 1
2 3 1 0 2
3 2 1 0 3
1 3 2 0 4
3 1 2 0 5
3 2 0 1 6
2 3 0 1 7
2 0 3 1 8
0 2 3 1 9
3 0 2 1 10
0 3 2 1 11
1 3 0 2 12
3 1 0 2 13
3 0 1 2 14
0 3 1 2 15
1 0 3 2 16
0 1 3 2 17
1 2 0 3 18
2 1 0 3 19
2 0 1 3 20
0 2 1 3 21
1 0 2 3 22
0 1 2 3 23

  

  通过这样的算法,通过指定的编号就能算出一个全排列。

  如果要遍历所有的全排列,则只要遍历编号就能完成。

  如果要随机获得一个全排列,则随机生成一个编号,再计算出全排列就可以了。

 

  具体的代码在我之前的文章“遍历排列的实现——VB2005”中,这里就不重复贴出了。

时间: 2024-10-10 23:08:22

再议“生成全排列算法”的相关文章

全排列算法的非递归实现与递归实现的方法(C++)_C 语言

(一)非递归全排列算法基本思想是:    1.找到所有排列中最小的一个排列P.    2.找到刚刚好比P大比其它都小的排列Q,    3.循环执行第二步,直到找到一个最大的排列,算法结束.下面用数学的方法描述:给定已知序列 P =  A1A2A3An ( Ai!=Aj , (1<=i<=n  , 1<=j<=n, i != j  ) )找到P的一个最小排列Pmin = P1P2P3Pn  有  Pi > P(i-1) (1 < i <= n)从Pmin开始,总是目

全排列算法的原理和实现代码_C 语言

全排列是将一组数按一定顺序进行排列,如果这组数有n个,那么全排列数为n!个.现以{1, 2, 3, 4, 5}为例说明如何编写全排列的递归算法. 1.首先看最后两个数4, 5. 它们的全排列为4 5和5 4, 即以4开头的5的全排列和以5开头的4的全排列. 由于一个数的全排列就是其本身,从而得到以上结果. 2.再看后三个数3, 4, 5.它们的全排列为3 4 5.3 5 4. 4 3 5. 4 5 3. 5 3 4. 5 4 3 六组数. 即以3开头的和4,5的全排列的组合.以4开头的和3,5的

PHP全排列算法实现程序代码

  从n个不同元素中任取m(m≤n)个元素,按照一定的顺序排列起来,叫做从n个不同元素中取出m个元素的一个排列.当m=n时所有的排列情况叫全排列. 简介 如1,2,3三个元素的全排列为: 1,2,3 1,3,2 2,1,3 2,3,1 3,1,2 3,2,1 共3*2*1=6种 3! 2公式 全排列数f(n)=n!(定义0!=1) 递归算法 1,2,3 1,3,2 2,1,3 2,3,1 3,2,1 3,1,2 这是由于算法只是考虑到了如何输出全排列,而没有考虑到换位是否有问题.所以我提出了解决

下载程序 边获取数据边生成Local的文件,还是等数据获取完后,再去生成Local文件?

问题描述 我个人兴趣,想做个下载器,假如等数据获取完后,再去生成Local文件,如果文件太大的话,会把内存吃光,假如边获取数据边生成Local的文件,不知道这样会不会影响到我Getfile的效率?谢谢 解决方案 解决方案二:我就是前期不清楚,看你可能是能下载了,我觉得你这个问题不难,咱二个互相探讨探讨行否我的帖子http://topic.csdn.net/u/20090111/09/d045db27-a2ff-43ae-9c44-7618931be0a6.html解决方案三:没有知道的人吗??解

class-关于.net RNGCryptoServiceProvider 生成随机数算法

问题描述 关于.net RNGCryptoServiceProvider 生成随机数算法 关于.net RNGCryptoServiceProvider 生成随机数算法 最近在看 RNGCryptoServiceProvider类 网上都说这个类能产生强随机数 而且大多数帖子都是拿这个类和random函数来比较 我比较疑惑的是这个类生成随机数是用什么算法生成的 具体的算法流程是什么查不到生成随机数的种子是什么也不太清楚 有没有大神知道呢 解决方案 .NET生成随机数C++伪随机数生成算法生成不重

代码-【递归】全排列算法的问题

问题描述 [递归]全排列算法的问题 class AnagramApp { static char[] arrChar; static int size; public static void main(String[] args) { String input = "abc"; arrChar =input.toCharArray(); size =input.length(); doAnagram(input.length()); } public static void doAna

再议高校教室监控 隐私与安全之间如何权衡

2016年10月,一则中山大学拟在教室安装监控摄像头的消息曾引起一番热议.起因是中山大学印发了一份<中山大学关于全面深化本科教育教学改革提高人才培养质量的若干意见>,其中提出,拟"对教学实施全过程监控".这一<意见>引起该校学生的担忧,质疑监控教学会泄露和侵犯隐私.事后社会各方对此事件发表了各种意见,总的来说,大家还是支持监控教学的,只是希望在监控教学的管理上能有更完善的管理以减少大家对隐私泄露的担忧. 再议高校教室监控 隐私与安全之间如何权衡 为什么会今天再议

生成学习算法(Generative Learning algorithms)

一.引言      前面我们谈论到的算法都是在给定\(x\)的情况下直接对\(p(y|x;\theta)\)进行建模.例如,逻辑回归利用\(h_\theta(x)=g(\theta^T x)\)对\(p(y|x;\theta)\)建模,这类算法称作判别学习算法.      考虑这样一个分类问题,我们根据一些特征来区别动物是大象\((y=1)\)还是狗\((y=0)\).给定了这样一个训练集,逻辑回归或感知算法要做的就是去找到一个决策边界,将大象和狗的样本分开来.可以换个思路,首先根据大象的特征来

文本比较算法Ⅷ——再议Nakatsu算法

研究文本比较算法已经一段时间了.把思路重新理了理. 在"文本比较算法Ⅳ--Nakatsu算法"中提到"对角线上的数字就是最长公共子序列的下标". 在"文本比较算法Ⅶ--线性空间求最长公共子序列的Nakatsu算法"中提到"每行最左边不为V的数字就是最长公共子序列的下标". 以上两个结论,网友Sumtec都提出了质疑,并提出了反例.经过本人的验算,Sumtec是正确的,我的文章有问题. 不过,不能说Nakatsu算法有问题.在&