1、 本科毕业论文(科研训练、毕业设计)题 目:多重集全排列算法的研究 模拟比较与汇编分析 姓 名: 学 院:软件学院系:软件工程专 业:软件工程年 级: 学 号: 指导教师: 职称:年 月I摘 要全排列问题是组合数学中的基础问题,对它的研究已经有几个世纪的历史了,几百年来产生了很多种类的全排列算法。但是,大于 25 的全排列对于我们来说规模仍过于庞大,因此我们需要更快的算法。本文研究了众多全排列的经典算法,对它们进行了分析和总结,在此基础上提出了 TWDRI 算法,它突破了以往只有采用换位思想才能达到最快速度的传统思想的束缚,以自身独特的数据结构设计为基石,充分利用递归方式的优势,取得远优于其他
2、同类算法的速度和内存损耗。此外,不同于大多数排列产生算法只能处理数值的特性,本算法适用于各种不同字符的输入情况,具有通用性。本文设计了平均时间测试模型,经过大量的时间测试和模拟比较,得出 TWDRI 是目前速度最快算法的结论。为了进一步验证 该结论,我们选择在汇编语言的环境下进行数学分析,力求通过数学公式的比较证明 TWDRI 算法的优越性。最后,本文还提出了该领域未来的一些研究方向。关键词:全排列 汇编 数学模型 多重集IIAbstractPermutation is the basic problem in combinatorics,and the research work has b
3、een carried on for hundreds of years, which produced many types of methods to do the permutation calculation. However, the permutation of the number which is larger than 25 is still beyond us. As a result, we need a swifter algorithm. This thesis does the research on these classic algorithms, analyz
4、es and summaries them, on the basis of which brings out the TWDRI algorithms. This method broke the traditional limits that the largest speed can only be achieved by using the exchange methods. It is based on the special design of data structure and makes the best use of the advantages of recursion,
5、 thats how it obtains the speed and memory cost which can hardly be achieved by its counterparts. Moreover, different from the traits of most permutations that the algorithms produced can only deal with data, this calculation is quite universal, for it suits different entering situations of all kind
6、s of string. The average time test model is designed in this thesis and we can conclude that TWDGI is the fastest algorithm in the present world after a large amount of time tests and simulation comparisons have been practiced. To further check this conclusion, we decide to do the mathematical analy
7、sis in the environment of compilation language, trying to prove the superiority of TWDRI by the comparisons of mathematical formulas. In the end, this thesis also provides some hints about the future research direction in this field.Key words: Permutation ; Assembly ; Mathematics Model ; MultisetIII
8、目录第一章 绪论 .11.1 研究背景及意义 .11.2 基本概念 .21.3 本文主要内容 .41.4 本文组织结构 .4第二章 经典算法 52.1 基于相邻交换的算法 .52.1.1 简介 .52.1.2 代表算法 .62.2 基于递归的算法 .72.2.1 简介 .82.2.2 代表算法 .82.3 基于迭代的算法 .92.3.1 简介 102.3.2 代表算法 102.4 字典序类算法 112.4.1 简介 112.4.2 代表算法 122.5 其他 122.5.1 Loopless 算法 .122.5.2 基于 GrayCode 序的算法 .122.5.3 随机排列 .13第三章 T
9、WDRI 算法与模拟比较 .143.1 简介 143.2 平均时间测试模型 153.2.1 平均时间测试程序 183.3 模拟比较 193.3.1 Knuth 算法 19IV3.3.2 模拟比较环境 203.3.3 多重集排列算法的时间和内存比较 213.3.4 单集排列算法的时间和内存比较 233.3.5 TWDRI 算法与其它多重集排列算法的比较趋势分析 25第四章 汇编分析 .264.1 分析工具 MIX.264.2 性能分析 27第五章 总结与展望 355.1 总结 .355.1.1 排列的应用 .355.1.2 总结 .355.2 未来的研究方向 .365.2.1 Hybrid al
10、gorithm.365.2.2 多线程并行算法 .39致谢语 42参考文献 43附录 47VContentsChapter 1 Introduction.11.1 Background 11.2 Basic Concept.21.3 Main Content41.4 Structure of This Thesis .4Chapter 2 Classical Algorithm.52.1 Algorithm Based On The Adjacent Exchange .52.1.1 Introduction .52.1.2 Representative Algorithm62.2 Algor
11、ithm Based On Recursive72.2.1 Introduction .82.2.2 Representative Algorithm82.3 Algorithm Based On Iteration 92.3.1 Introduction .102.3.2 Representative Algorithm102.4 Lexicographic Algorithm .112.4.1 Introduction .112.4.2 Representative Algorithm122.5 Others .122.5.1 Loopless Algorithm.122.5.2 Algo
12、rithm Based On GrayCode 122.5.3 Random Algorithm13Chapter 3 TWDRI Algorithm and Simulation Comparison.143.1 Intriduction .143.2 The Average Time Test Model .153.2.1 Test Program for Average Time183.3 Simulation Comparsion193.3.1 Knuth Algorithm .193.3.2 Simulation Comparsion Environment .20VI3.3.3 A
13、verage Time and Memory Consumption of Multiset Permutation.213.3.4 Time and Memory Consumption of Pure Permutation .233.3.5 Speed Ratios of TWDRI Algorithm to Other Algorithms 25Chapter 4 Assemmbly Analysis264.1 Analysis ToolMIX264.2 Performance Analysis.27Chapter 5 Conclusions and Future Work.355.1
14、 Conclusions .355.1.1 Application .355.1.2 Conclusions 355.2 Future Work 365.2.1 Hybrid algorithm 365.2.2 Multi-threads Parallel Algorithm .39Acknowledgments.42References .43Appendix .47厦门大学本科毕业论文1第一章 绪论本章将从课题研究背景及意义,论文主要内容,本文组织结构等方面对论文做总体上的介绍。1.1 研究背景及意义排列和组合一直是组合数学研究的重点,全排列广泛地应用在各种复杂的软件中,尽管数学概念简单,
15、但程序实现并不容易,排列中包含着多种形式的数据结构。排列算法的研究在计算机发明之前已经开始,其历史甚至可以追溯到 14 世纪的印度,当时已经产生了解决排列问题的算法。十六世纪五十年代,教堂中的牧师曾计算过几口大钟如何用不同的撞击顺序来产生各式的音乐效果,这也是排列问题历史上的一个经典事件。几个世纪以来,产生了众多的排列算法 1-50。算法大师 Donald E. Knuth 在其经典著作计算机程序设计艺术一书中写道:“事实上,排列(permutations)问题在计算机领域非常重要。Vaughan Pratt 提议直接把它叫做perms。如果 Pratt 的建议得以实施,那么计算机教科书的厚度
16、将变得薄一些(相应书的价格也会便宜一点) ”1。由此可见排列在计算机领域出现的频率之高。正是因为排列问题如此重要,所以一直以来有众多的研究人员致力于该问题的解决。进入 20 世纪,排列问题的研究取得了突飞猛进的进展,不断涌现出一些有代表性的算法。普林斯顿大学计算机系算法大师Robert Sedgewick 在 1977 年对众多排列产生方法中的经典算法做了分析和比较 2,这是一篇非常经典的极具参考价值的文章, Robert Sedgewick 倾注了大量的心血,阅读了大量的相关资料,对 1977 年以前出现的关于排列问题的论文进行了非常完整的总结。M. B. Wells 在1961 年第一次提
17、出了 Recursive Method3,此后递归算法逐渐成为排列算法的一大类别。1962 年 S. M. Johnson 和 H. F. Trotter 提出的 Adjacent exchanges 算法 4,而这也称为排列算法的一个类别。在 Johnson-Trotter 算法的基础上 G. Ehrlich 引进了减少内部循环的思想得到Loopless 算法 5,之后,随着发展的继续推进, Loopless 也成为排列算法中一个相当重要的类别。此外,基于迭代 6,格雷编码 7,以及树形结构 8等的排列算法在 20 世纪的后几十年里逐渐出现,最近几十年来,各个类型的排列算法大量涌现。2006
18、 年算法大师 Donald E. Knuth 在其巨著计算机程序设计艺术 1第四卷第二册中专门对生成排列的多种算法进行了详细的概括与分析。厦门大学本科毕业论文2之所以出现这么多排列算法,是因为排列问题的瓶颈仍然没法突破,人们一直试图找出速度更快,性能更高的算法,但是其根本问题规模庞大,还是没有实质性的解决办法。我们假设计算机进行一次运算就能给出一个排列(实际的算法不可能做到这点)。对于一台运算速度为百万次每秒的计算机, 给出 11 个元素的集合的所有 11!= 399168 个排列只需几秒钟的时间,而给出 17 个元素的集合的所有 17!= 355687428096000 个排列则需要几年。就
19、算是当前最快的计算机,其运算速度能达到万亿次每秒,要计算出大于 20 个元素的集合的所有排列在时间上也显得不太可能,详见表 1-1。表 1-1 不同性能计算机在各种输入规模下进行排列所需的时间排列问题是一个经典的数学问题,它有着悠久的历史,也有着广泛的实际应用,比如说在密码学领域对输入的一些数字或字符产生其对应的密码;在生物医学领域 DNA 序列的排列等等。在 DNA 分析、加密解密、电路设计、运筹研究、统计计算、化学等领域中你都可以看到排列与组合的应用。因此,研究字符串的全排列问题有很大的实际意义。1.2 基本概念定义 1 (排列): 组合数学的基本概念,从有限个元素中取出全部或一部分按照一
20、定的顺序排成的一个系列。例如 3 个数码 1,2,3 全部取出可以作成 6 个不同的排列:123,132,213,231,312,321。在组合数学中,常要研究由指定的一组元素中每次取出一厦门大学本科毕业论文3定数量的元素来作排列 ,一共能作多少个不同的排列,用符号 表示从 n 个不同的元素中mnp任意取出 m 个元素所作的不同排列的总数,那么有公式 ,称为(1)2.(1)排列数公式。当 mn 时,称为全排列,全排列数公式为 。记号*!nn!表示从 1 到 n 这 n 个自然数的连乘积,称为阶乘。定义 2 (单集排列): 给定的字符串不包含重复字母,将其进行全排列,把其所有可能的全排列准确无重
21、复无遗漏地列举出来。例如:输入 ABC,其全排列的结果有 6 种,分别为:ABC,ACB,BAC,BCA,CAB,CBA。定义 3 (多重集排列): 给定的字符串包含重复字母,将其进行全排列,把其所有可能的全排列准确无重复无遗漏地列举出来。例如:输入 AAB,其全排列的结果有 3 种,分别为:AAB,ABA,BAA。如果 S 是一个多重集,那么 S 的一个 r 排列是 S 的 r 个元素的一个有序排放。如果 S 的元素总个数是 n(包括计算重复元素),那么 S 的 n 排列也称为 S 的排列。例如,如果S3*a , 2*b , 4*c,那么 abbcc , abcac 和 bcccb 都是 S
22、 的 5 排列,而 bccacabca 和abcabcacc 都是 S 的一个排列 60。定义 4 (字典序排列): 所谓字典序排列是指所有可能的排列结果按字典顺序产生。就是预先定义需要排列的 k 个元素的次序 , 。给出两个排列 P1 和 P2,如果 P1 和 P2 的前1n2.ki1 个元素都相同,P1 的第 i 个元素为 ,P2 的第 i 个元素为 ,aj 的个数。 )kcA4: 置 q= + 。如果 qj,则转到 B7。jcoB5 交换 和 。然后置 =q,返回 B2。jcsaqsjcB6 如果 j=1 则结束,否则置 s=s+1。B7 置 =- ,j=j-1,转回 B4。joj厦门大
23、学本科毕业论文71 2 3 44 1 3 21 4 3 21 3 2 41 3 4 24 1 2 31 4 2 31 2 4 3图 2- 2 N=4 时 Johnson-Trotter 算法的前 8 个排列从图 2-2 可以看出该算法的规律性,观察”4” 可知,它从尾部一步步被交换到第一位,然后再被交换到最后一位。换个角度,我们看前 4 条排列结果,相当于在”123”的 4 个空位中插入元素”4”,接下来的 4 条结果相当于在“132 ”的 4 个空位中插入元素”4” 。 其实算法的思想来源很自然,如果我们已经知道 N-1 个元素的所有(N-1)! 个排列;每次将新的第 N 个元素插到原来每个
24、排列中所有可能的 N 个空隙中便可以得到所需的 N!个排列。软件的开发过程中, 常常会涉及到比较复杂的算法问题, 如求解排列组合的所有结果问题,如果从大量的数据中研究并且找到在时间和空间复杂度上尽可能小的算法, 肯定要用大量的时间进行总结归纳, 这样一个项目很可能要延期 , 或者不能交付,因此通常不推荐采用此方法, 而是折中 , 找到一种在时间和空间复杂度上一般, 而在逻辑实现上简单、思路清晰的算法来解决问题。采用排列的邻位互换生成算法, 是直接操作每个元素进行有规律的移动组合。为了不产生冗余的循环, 难免会使算法复杂性提高, 代码虽然简练, 但是逻辑性较差, 不易维护, 并且算法中每步的藕合
25、性很大, 不易扩充和实现更复杂的操作, 只能在一个算法中实现所有的结果, 不能拆分。同时, 由于是针对特定问题所提出的算法, 本身的思想并不一定通用。2.2 基于递归的算法本节详细介绍递归类的排列算法,首先介绍其特点,然后介绍代表算法 Wells 算法。厦门大学本科毕业论文82.2.1 简介递归算法的思想是这样的,假设一组待排列的串 ,为了产生所有的 N!个排123.na列,可以采用这样的步骤:首先,生成 的所有(n-1)! 个排列,然后从 中任12.na 12.na一个与 交换,这时候再生成当前 的所有(n-1)!个排列,这样下去,每次赋给 一na个新的值,经过 N 次这样的重复就可以生成全
26、部 N!个排列。 2.2.2 代表算法第一个递归的排列生成算法是由 M.B.Wells 在 1960 年提出的,算法如下:算法 C:(Wells 算法) 3procedure permutations (N);begin c: = 1;loop:if N2 then permutatmns(N-1)endif;while c2)then PN:=:PN-celse PN:=:PN-1 endifc:=c+1repeat loopend;厦门大学本科毕业论文9图 2- 3 Wells 算法在 N=2,3,4 时的排列以图 2-3 为例,当 N=4 时,Wells 算法这样工作: 首先保持最后一个
27、字符 D 不变,生成A,B,C 的 6 中排列,在这个过程中又首先保持 C 不变,生成 A,B 的所有排列,然后交换 C,依次类推产生 A,B,C 的排列,然后交换 D,这是 B 被交换到了最后一位,保持 B 的位置不变,生成 A,C,D 的 6 中排列,这样经过 4 次这样的递归调用,最终生成了全部的 24 中排列。至今为止递归算法已经出现了很多中,在这些算法中不同的是在执行从 中任12.na一个与 交换这一步时的策略问题。na2.3 基于迭代的算法本节详细介绍迭代类排列算法,先给出其基本介绍,然后介绍代表算法 Ives 算法。厦门大学本科毕业论文102.3.1 简介In 1976, F.
28、M. Ives 发表了一种新的算法,这种算法是在 Johnson-Trotter 算法基础上的改进。后来逐渐演变成一种新的算法类型迭代。这种算法的特点就是它消除了递归结构,通过循环实现生成所有的排列。2.3.2 代表算法算法 D:(Ives 算法) 6在产生元素 1, 2, , n 的排列过程中,Ives 算法每次将第一个元素 1 向右移动一个位置。当 1 移动到最右端时再将 1 和最左端的元素对换。假设排列最开始的顺序是 1, 2, , n。经过 n 次移动后,元素 1 又回到了第一个位置。而原来在位置 2, , n 的元素进行了一次循环左移。我们把元素 1 从最左端移动到最右端再移回到最左
29、端看成是 1 的一次旅行。在元素 1完成 n-1 次旅行后,原来位置在 2,n 的 n-1 个元素也完成了 n-1 次循环左移,这时它们各proceduce Permutation( i:N )begini:=N ;loop: ci:=i; Qi:=Pi; while i1: i:=i-1 repeat;process;loopif ci Pi8 do j j + 19 do swap Pi Pj10 reverse(i-1)11 OutputPerm厦门大学本科毕业论文13ABCDBACDDABCADBCADCBDACBDCABDCBACDBACDABCADBACDBACBDCABDCBAD
30、CBDABCDABCADABDCBADCBDACBDCADBCADBAC图 2-6 当 N=4 时,基于格雷码的多重集排列算法排列产生图2.5.3 随机排列我们知道,当 N25 时,生成其所有排列将是一个相当漫长的过程,Random 排列就是来解决这一问题的,它可以产生所有种类的排列,但事实上对于大数来说短时间内不可能产生其所有的排列,但它可以根据需要产生某些排列。厦门大学本科毕业论文14第三章 TWDRI算法与模拟比较本章是全文的重点部分,将介绍原创算法 TWDRI,并提出排列算法的平均时间测试模型,然后经过大量的模拟结果比较,证明 TWDRI 算法是速度最快的算法。3.1 简介该算法能同时
31、解决一般的无重复输入的单集问题和重复输入的多重集(multiset)问题。TWDRI(Traversal with Dynamic Rest Indices)突破了以往只有采用换位思想才能达到最快速度的传统思想的束缚,以自身独特的数据结构设计为基石,充分利用递归的优势,取得远优于其他同类算法的速度和内存损耗。此外,不同于大多数排列产生算法只能处理数值的特性,本算法适用于各种不同字符的输入情况,具有通用性。图 3-1 介绍了 TWDRI 算法的流程图。图 3- 1 TWDRI 算法流程其中方法 PurePermutation()解决单集排列,方法 MultisetPermutation()解决多
32、重集排列。算法的计算时间 T(n)满足:厦门大学本科毕业论文15(3-1)123()(3)()nTCn输入规模为 n3 的问题可由 n 个输入规模为 n-1 的子问题构成。 是对子问题12*Cn结果进行分解和合并的花费,其中 、 为常数。当 n=3 求解问题的花费为 , 为常数。1C2 3. . .12()Cn12()Cn12()Cn1212121212123C. . . . . . . . . . .n b r a n c h e sn - 1 b r a n c h e s n - 1 b r a n c h e sn - 1 b r a n c h e s (1)4n(1)n1.1241
33、24C124C. . . . . . . .3 354 b r a n c h e s 4 b r a n c h e s4 b r a n c h e s图 3-2 的递归树12()Tnn3.2 平均时间测试模型时间复杂度是衡量算法优劣的一个标准,但其只是用来描述算法关键操作执行次数的变化规律。对于众多高速的排列算法来说,其时间复杂度基本上都为 X*O(n!),其中的 X 为常数或者是与输入规模相关的表达式,从渐进意义上都已达到排列问题时间复杂度的理论下界。当输入元素个数为 n 时,全排列的结果的输入规模为 n! ,这个特点决定了时间复杂度是无法逾越 O(n!) 的。从这个意义上讲,全排列算
34、法单单在时间复杂度上比较是分不出优劣的,因为它们基本上都达到了同一个时间复杂度水平。厦门大学本科毕业论文16那么该如何对全排列算法进行相对公平的比较呢?Tadao 和 Violich 在其发表的论文An O(1) Time Algorithm for Generating Multiset Permutations 8中与 Korsh 和LaFollette 在 2004 年发表的算法 15进行比较,仅仅用两个测试案例得出的结果就断言自己算法比他人算法快 31-34%。这种比较方法显然是不合理的。因为每个算法对于相同长度的字符串的不同输入,其执行的时间是不相同的。为了全面客观的比较各个算法的性
35、能,我们需要对随机输入长度为 N 的字符串的所有情况进行测试。一个输入的产生可以看成是从 N 个字符中每次抽取 1 个字符填满 N 个有序格子。每个格子都有 N 种字符可选,所有共有 NN 种输入情况。然而,当 N 的数值较大时,这样的测试数据简直可以说是天文数字,再加上每个测试用例进行全排列的耗时也是惊人的,直接输入进行比较的方法是不可行的。然而我们发现,对于 NN 种输入情况,可以进行分类,有些输入的排列时间是相同的,这样就可以大大减少我们比较测试的工作量。我们不必测试所有的 NN 种输入,因为其中有些输入产生排列的时间相同。以长度4(N4)为例,显然输入 “AAAA”和“BBBB ”进行
36、排列时间相同,输入“AABB”,“CCDD”和 “BCBC”的排列时间也是一样的。这样我们就可以对所有的输入情况进行分类,把那些排列产生时间相同的输入划分到一类中。因此我们只需测试每类中的一个输入的排列时间 t,再将时间 t 乘以该类的输入个数 cd 就可以得到该类所有输入情况的排列时间td。下面将介绍分类的过程:分类可以抽象为对正整数 N 的分拆。正整数 n 的一个分拆是 n 作为一个或多个正整数的无序和的一种表示。由于部分的顺序是不重要的,因此我们总可以排列这些部分使得它们的顺序从最大到最小。1,2,3,4 和 5 对应的分拆为:1;2,1+1 ; 3,2+1 ,1+1+1;4,3+1,2
37、+2 ,2+1+1,1+1+1+1 以及5,4+1 ,3+2,3+1+1,2+2+1,2+1+1+1,1+1+1+1+1。n 的一个分拆有时候写成(3-2)21naa其中 ai 为非负整数,该数等于值为 i 的部分的个数(这个表达式是纯符号性的:它的项既不是指数式,表达式也不是一个乘积)。当被写成式(4-1)的形式时,若 ai0,则项 通常ia被省略,使用这个记号,4 的分拆为:41,3 111,2 2,2 112,1 4 的每种 形式对应一种分类。这 5 种分拆就对应长度为 4 的随机输入的 521naa种分类:厦门大学本科毕业论文17表 3-1 长度为 4 时的分类d One instan
38、ce 1niiatd1 41 AAAA 1(A) t12 3111 AAAB 2(AB) t23 22 DDCC 2(DC) t34 2112 AABC 3(ABC) t45 14 ABCD 4(ABCD) t5某类 中如果有 项,则该类有 ai 个重复出现 i 次的字符。显然各项 ai 的和21naa iak(其中 k= )就是构成一个输入字符串的不同字符的个数。1i我们还需要计算每种分类包含的输入情况的个数。还是以长度 4 为例,不失一般性假设组成输入字符串的字符集合为A, B, C, D。每种分类各项 ai 的和 k 代表组成该类一个输入情况的字符个数,而从字符集合中选取 k 个字符有
39、种选法。表 3-1 第 4 行 2112 的 k 为kNC1+2=3,所以共有 =4 种选择 ABC,ABD,ACD ,BCD。对于一种选择如 ABC 我们还要34C考虑哪个字符重复出现 2 次,A 出现 2 次得到 AABC,B 出现 2 次得到 BBAC,C 出现 2 次得到 CCAB。所以要对每种选择的字符进行排列,有排列个数= =3。AABC,BAAC 和 BACA 也是不同的,个数为 =1!/Nika3!/(2) 1!/(!)aNijk=12。4(2)每个分类中输入情况的个数为:(3-3)11(!/)(!/(!)d aNNikdNi jkcCa至此我们可以得到平均时间的计算公式:(3
40、-4)/NdTct厦门大学本科毕业论文183.2.1平均时间测试程序平均时间测试程序作为一个框架,产生测试字符串,自动输入测试的算法,最后自动将测试过程的数据记录在文件之中。对于每种输入所需的全排列的时间,其计算原理很简单,即在排序前读取 CPU 的时间,然后调用算法进行全排列,当结束后再次读取 CPU 时间,从时间差可以得出该输入进行全排列所耗费的时间。开始读取 N分拆 、 计算各种分拆情况的概率并记录下相关数据根据分拆情况产生各个测试字符串测试字符串是否结束输出累加值 , 即平均时间是用当前字符串运行 , 测算时间 , 记录到文件中 , 将时间乘概率并累加否结束图 3- 2 非字典序平均时
41、间测试程序流程图对于字典序平均时间测试程序,其流程中在分拆后多了一个全排列的处理过程,对分拆后的每种组合进行全排列,得到有序的组合。而概率的计算也随之移到增加的全排列过程之后。由于字典序平均时间测试的测试字符串与非字典序平均时间的相比数量增加相当大,所以为了减少等待时间,将其改写成可分批运行在多台计算机上。在开始测试字符之前,读取厦门大学本科毕业论文19测试的起止测试字符串的序号,在一台计算机上只测试一部分,最后将多台运行结果相加即可得到字典序平均时间。3.3 模拟比较根据模拟比较的结果我们的算法比世界上已知的最快的算法快 2 倍,比其他大多数算法快 10 倍以上。在我们的算法之前已经存在的算
42、法有很多,这里面以 Knuth 的算法 1性能为最好,我们对 Knuth 算法做了适当的优化,将其速度提高了 100%,在此基础上产生了更好的算法,因此本节从介绍 Knuth 算法开始。3.3.1 Knuth算法Knuth 在计算机程序设计艺术一书第四卷第二册生成所有排列这一节介绍了一个经典的字典序生成所有排列的算法,这一算法产生于 14 世纪的印度。算法 L1给定 n 个元素 a1a1an 的一个序列,开始时它们按照升序排列 a1a2a3.an。在书中 Knuth 对这一算法进行了优化,提高了算法 L 速度,我们将其成为 KnuthLex08L1. Visit. Visit the perm
43、utation .12naL2. Find j. Set . If , decrease j by 1 repeatedly until . Terminate jnjj 1jjathe algorithm if j=0.L3. Increase . Set . If , decrease by 1 repeatedly until . Then jaljlal jlinterchange .jlL4. Reverse . Set and . Then, if , interchange , set 1jn 1kjlnklkla, , and repeat until . Return to
44、L1. kl厦门大学本科毕业论文20算法。算法 KnuthLex08110: Assuming that , replace steps L2-L4 by:3n我们在前两者的基础上,吸取 Sedgewick 的经验,对算法 L 做了进一步优化,将其速度又提高了 2 倍,得到 OurKnuthLex 算法。3.3.2 模拟比较环境硬件环境:Pentium 4 CPU 2.93GHz 1GB 内存。软件环境:VC+ 6.0 L2. Easiest case? Set and , If , set , , and return 1nyazayz1naznyto L1.L2.1. Next easie
45、st case? Set . If , go on to step L2.2. Otherwise set 2nxxif , if . Return to L1.21(,)(,)nnazxy z()yzL2.2. Find j. Set and . If , set , , , and 3jnjax1jxyjarepeat until . Terminate if j=0.L3. Easy increase? If , set , , , and go to 4.1.yzjz1jynaL3.1. Increase . Set ; if , repeatedly decrease by 1 un
46、til . jalnlllyaThen set and .jllyL4. Begin to reverse. Set and .1nja1jzL4.1. Reverse . Set and . Then, if , interchange 1ja 2klnkl, set , , and repeat until . Return to L1.klakl k厦门大学本科毕业论文21进行比较的其他算法: Heap63: recursive exchange algorithm from 12 Heap63: iterative exchange algorithm from 12 Ives 76:
47、 iterative exchange algorithm from 6 JT: algorithm 3b (Loopless Johnson-Trotter) from 2 JTLLC03: lexicographic algorithm from 13 KL97: constant time algorithm from 14 KL04: loopless array generation algorithm from 15 KnuthLex08: lexicographic algorithm from 1 OurKnuthLex: Our optimization algorithm
48、with lexicographic order for KnuthLex08 from subsection 5.2 OurKnuthNoLex: Our optimization algorithm without lexicographic order for KnuthLex08 from subsection 5.3 PhilLex67: lexicographic algorithm from 10 Ruskey 03: algorithm from 14 Sedgewick02: algorithm from 11 Takaoka99: O(1) algorithm from 8 TV06: algorithm from 17所有算法均遵照作者的算法原型,我们所做的改动只是加入了时间测试框架。3.3.3 多重集排列算法的时间和内存比较从表 3-2,3-3 和图 3-4 中可以看出 TWDRI 相比较其他算法的优越性。与它速度比较接近的是经过我们改进的 Knuth 算法。并且从图中可以看出 TWDRI 算法运行时间随着排列规模 N 的增大而增大的趋势相对其他算法来说是最缓和的