汉诺塔 最优算法设计商量

article/2025/9/18 0:10:27

2019独角兽企业重金招聘Python工程师标准>>> hot3.png


引言


汉诺塔算法一向是算法设计科目标最具代表性的研究题目,本文存眷于如何设计多柱汉诺塔最优算法的商量。最简单的汉诺塔是三个柱子(ABC),是以多柱汉诺塔的柱子个数M≥3。下面从三柱汉诺塔说起,慢慢深切我们要关怀的题目。


1. 三柱汉诺塔


三柱汉诺塔是经典的汉诺塔题目,在算法设计中是递归算法的典范题目。其算法是如许的起首把柱上方的n- 1 个碟子经由过程柱移到柱上【T(n-1)步】然后把柱剩下的一个碟子移到柱上【1步】, 最后把柱上所有的碟子经由过程柱移到柱上【T(n-1)步】。很轻易获得算法的递归方程为:T(n)=2*T(n-1)+1,是以,不难算出步数是T(n)=2^n-1。对于三柱汉诺塔的算法的正确性天然是毫无争议的,我们须要的是从三柱汉诺塔的设计中引申出多柱汉诺塔的设计办法。


2. 四柱汉诺塔


四柱汉诺塔并不是仅仅是多了一根柱子那么简单,所以我们先测验测验从正常的思维出发来商量如何使移动步数起码。


起首我们会想到,三柱汉诺塔须要借助另一个柱子存放前n-1个盘子,再把第n个盘子移动到目标地位。天真烂漫的,四柱汉诺塔因为多了一个柱子,所以移动起来就更便利了,我们可以多留下一个盘子n-2,而不让它借位到其他柱子直接移动到目标地位。如许我们就得出算法的根蒂根基流程:


(1)       A借助CD n-2个盘子移动到B上。


(2)       n-2移动到C上。


(3)       n-1移动到D上。


(4)       n-2移动到D上。


(5)       B借助AC n-2个盘子移动到D上。


别的,这么设计是合适正常思维原则的。认为跟着柱子的个数增多,我们欲望每次移动的时辰盘子尽可能不产生折叠,也就是说我们欲望除了须要借助存放n-2个盘子的柱子。那么剩下的两个柱子可以容许至多两个盘子不产生折叠就能直接移动到目标地位,如许才使得移动起来斗劲便利,步调也会斗劲少。事实真的是如此吗?我们具体解析一下算法。


遵守以上设计的算法流程,我们获得递归方程:F(n)=2*F(n-2)+3。是以获得移动步数为:F(n)=4*2^(n/2)-3n为奇数;F(n)=6*2^(n/2-1)-3n为偶数。下边列出6个盘子的移动步数:


n      1     2     3     4     5     6


F(n)  1     3     5     9     13    21


       到这里,我们已经看出我们的设计的算法已经和经典的汉诺塔算法几乎千篇一律了,甚至是如此的对称调和!基于此我们甚至可以推广到M(M≥3)个柱子的景象,来获得我们欲望的最优解,假设柱子编号为123…M算法主题框架流程应当如下:


(1)       1柱借助3…M柱子将n-(M-2)个盘子移动到2柱上。


(2)       M-2个经由过程3…M-1柱简单的移动到M柱上【2*(M-2)-1步调】。


(3)       2柱借助13…M-1柱子将n-(M-2)个盘子移动到M柱上。


具体步调和四柱类似,不再做具体解析。如许我们看到我们本身亲手构建的算法模式如此完美,我们甚至不忍心去破损它。然则我很遗憾的告诉本身,这种算法固然正确,却不是最优!!!比如,对于6个盘子4个柱子的汉诺塔,遵守我们的设法是保存2个盘子进行移动。如今假如我们保存3个盘子,是以上边的三个盘子遵守4柱汉诺塔规矩移动到B,步数应当是5(已经算出,可以验证),剩下三个盘子遵守3柱汉诺塔规矩移动到D上,步数应当是2^3-1=7步,然后B上的三个盘子移动到D上仍然是5步,总步数为5+7+5=17步<21步!如今我们可以确信的告诉本身,我们的设法太“天真”了。固然我们想到让盘子尽量不产生重叠来包管步数的起码,然则这并不克不及绝对包管。或许在盘子较少的景象下是可行的,然则盘子增多时,那些多余的只有一个盘子的柱子是可以加以哄骗的。固然这么做加多了每次的移动步数,然则却从另一个侧面削减了递归的数量,是以我们须要从这里边找一个均衡点。


从上边的例子中,我们获得一个启发:在递归法度中残剩盘子的个数并不必然是M-2,也有可能是M-1,我们假设残剩盘子是M-r,那么r到底取得几许才合适呢?其实,早在1941年,一位名叫J. S. Frame的人在《美国数学月刊》上提出了一种解决四柱汉诺塔题目的算法,这是人们熟知的Frame算法:


1)用4柱汉诺塔算法把A柱上项目组的n- r个碟子经由过程C柱和D柱移到B柱上【F( n- r )步】。


2)用3柱汉诺塔经典算法把A柱上残剩的r个碟子经由过程C柱移到D柱上【2^r-1步】。


3)用4柱汉诺塔算法把B柱上的n-r个碟子经由过程A柱和C柱移到D柱上【F(n-r)步】。


4)根据上边规矩求出所有r1≤r≤n)景象下步数f(n),取最小值得终极解。


是以Frame算法的递归方程如下:


F(n)=min(2*F(n-r)+2^r-1),(1≤r≤n)。


经由过程这个方程我们能获得所有4柱汉诺塔的步调个数,同时也有人证实[1]了,对于四柱汉诺塔,当r=(sqrt(8*n+1)-1)/2时,能包管f(n)取得最小值F(n)=(n-(r^2-r+2)/2)*2^r+1。所以算法的错杂度是F(n)=O(sqrt(2*n)*2^ sqrt(2*n))。从这这个方程中也可以看出,在n<6的时辰,我们可以验证是和我们起先的构思的布局是雷同的,然则当n再增多时就不是当初想的那样了。


3. 多柱汉诺塔


基于四柱汉诺塔的Frame算法,我们可以引申到多柱(M汉诺塔的景象,我们简称M柱汉诺塔算法:


1)用M柱汉诺塔算法把1柱上项目组的n-r个碟子经由过程3&#8230;M柱移到2柱上【M( n- r )步】。


2)用M-1柱汉诺塔算法把1柱上残剩的r个碟子经由过程3&#8230;M-1柱移到M柱上【<M-1>(r)步】。


3)用M柱汉诺塔算法把2柱上的n-r个碟子经由过程1柱和3&#8230;M柱移到M柱上【M( n- r )步】。


4)根据上边规矩求出所有r1&#8804;r&#8804;n)景象下步数m(n),取最小值得终极解M(n)


4柱汉诺塔的递归方程和成果公示中我们可以看出,跟着柱子数量的增长,算法的错杂程度也是络续地增长。对于解决M柱汉诺塔题目须要应用M-1柱汉诺塔的算法,是以除了算法解决题目须要递归外,算法的流程本身也须要递归,这种递归布局已经远远地错杂于当前所接触的递归算法。若是有爱好可以测验测验去设计这种算法,算法所涉及的参数应当有盘子的个数n、柱子的个数m、算法的编号num、参数r等信息。因为须要按照不合柱子景象下经由过程轮回和递归找出最合适的r值,所以这种算法的错杂度必然相当高。不过我们仅仅是为了商量如何取得最优算法,所以具体实现就不再赘述了。


总结


经由过程以上的评论辩论,我们从一般的思维&#8212;&#8212;不折叠盘子,出发去找多柱汉诺塔的最优解,然则成果并没有成功&#8212;&#8212;盘子多时有可能柱子没有充沛哄骗。后来经由过程前人提出的Frame算法引申出多柱汉诺塔算法,并大致描述了多柱汉诺塔算法的双重嵌套递归布局&#8212;&#8212;算法题目的递归以及算法本身的递归实现。这种罕有的递归法度布局给我们在算法设计方面坦荡了新的视野,欲望不久的将来能找到更好地算法设计办法来解决多柱汉诺塔的题目。


参考文献


1.《四柱汉诺塔之初步商量》杨楷 徐川( 北京大学策画机科学与技巧系, 北京, 100871) 北京大学学报( 天然科学版) , 40 , , 2004 


 

Admin


转载于:https://my.oschina.net/dianpaopao/blog/74516


http://chatgpt.dhexx.cn/article/8mtPeAsu.shtml

相关文章

函数递归与汉诺塔

C初阶之函数递归 函数递归基本原理 什么是递归&#xff1f;程序调用自身的编程技巧称为递归recursion。一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法&#xff0c;它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解&#xff0c;…

分治算法的解和幂乘算法及其优化以及汉诺塔算法的介绍

分治算法就是分成若干个和原问题一样性质的子问题&#xff0c;然后逐步递归这些子问题&#xff0c;直到遇到规模很小的子问题&#xff0c;求出子问题的解&#xff0c;归结成原问题的解的算法就是分治算法 分治算法为递归问题&#xff0c;可以用来解决快排、二分归并、斐波那契数…

递归求解汉诺塔问题(详细解答)

汉诺塔移动步数的计算 具体汉诺塔的规则大家自行百度吧&#xff0c;就不介绍了&#xff0c;这里介绍一下如何求解汉诺塔移动步数的计算思想。 当汉诺塔层数为一层时&#xff0c;很显然只需要一步&#xff0c;直接从A杆移动到C杆 当层数为两层时&#xff0c;则需要三步&#x…

汉诺塔算法

2019独角兽企业重金招聘Python工程师标准>>> 有A、B和C 3跟柱子&#xff0c;在A上从下往上按照从小到大的顺序放着64个圆盘&#xff0c;以B为中介&#xff0c;把盘子全部移动到C上。移动过程中&#xff0c;要求任意盘子的下面要么没有盘子&#xff0c;要么只能有比它…

汉诺塔算法的理解

2019独角兽企业重金招聘Python工程师标准>>> 当盘子数为两个时&#xff0c;移动图如下&#xff1a; 移动规律为&#xff1a; 步骤盘子编号源柱子目标柱子11AB22AC31BC 当盘子数为3个时&#xff1a; 移动规律为&#xff1a; 步骤盘子编号源柱子目标柱子11AC22AB31CB4…

汉诺塔递归算法

2019独角兽企业重金招聘Python工程师标准>>> import java.util.Scanner;/*** 汉诺塔* * author JayChang* */ public class HanoiResolve {/*** 移动位置* * param positionA* param positionB*/public static void move(String positionA, String positionB) {Syst…

数据结构——树和二叉树 6-1 求二叉树高度 (20 分)

本题要求给定二叉树的高度。 函数接口定义&#xff1a; int GetHeight( BinTree BT ); 其中BinTree结构定义如下&#xff1a; typedef struct TNode *Position; typedef Position BinTree; struct TNode{ElementType Data;BinTree Left;BinTree Right; }; 要求函数返回给定…

PTA 函数题 求二叉树高度(C语言)

本题要求给定二叉树的高度。 函数接口定义&#xff1a; int GetHeight( BinTree BT ); 其中BinTree结构定义如下&#xff1a; typedef struct TNode *Position; typedef Position BinTree; struct TNode{ElementType Data;BinTree Left;BinTree Right; }; 要求函数返回给定…

6-1 求二叉树高度

6-1 求二叉树高度 (15 分) 本题要求给定二叉树的高度。 函数接口定义&#xff1a; int GetHeight( BinTree BT );其中BinTree结构定义如下&#xff1a; typedef struct TNode *Position; typedef Position BinTree; struct TNode{ElementType Data;BinTree Left;BinTree Rig…

二叉树的构造及求解二叉树高度

题目描述 1、参考题目解释构造一棵二叉树&#xff1b; 2、求解二叉树的高度 3、有余力同学尝试打印这棵二叉树&#xff08;以树的形态&#xff0c;非必须&#xff09; 输入 A(B(E,C(D(F(,G),),) 输出 二叉树高度为: 6 代码实现 #include <iostream> //#include &l…

二叉树4:二叉树求树高度(超级详细)

一、思路 什么是树高&#xff1f; 树的高度(或深度)就是树中结点的最大层数。 在这里使用后序遍历的递归算法。 对每一个结点都进行如下操作&#xff1a; 后序遍历其左子树求树高后序遍历其右子树求树高对这个结点进行下面操作&#xff1a; 比较其左右子树的高度大小若左&g…

二叉树的高度和深度

二叉树的高度和深度定义 &#xff08;对某个节点来说&#xff09; 深度是指从根节点到该节点的最长简单路径边的条数&#xff1b; 高度是指从最下面的叶子节点到该节点的最长简单路径边的条数&#xff1b; &#xff08;对二叉树&#xff09; 深度是从根节点数到它的叶节点&…

关于360提示发现木马—HEUR/QVM.Malware.Gen

今天用Visual Studio写的关于三层架构的程序 在启动运行时&#xff0c;弹出了360关于"检测到木马程序"的提示框&#xff1a; 虽然知道自己写的是正规程序&#xff0c;但初看时还是被吓了一跳&#xff0c;于是立马上网查阅相关资料和解答&#xff0c;结论是&#xff…

WebRTC 之 RTX

AbstractWebRTC RTX 笔记AuthorsWalter FanCategorylearning noteStatusv1.0Updated2020-08-28LicenseCC-BY-NC-ND 4.0 什么是 RTX RTX 就是重传 Retransmission, 将丢失的包重新由发送方传给接收方。 Webrtc 默认开启 RTX (重传)&#xff0c;它一般采用不同的 SSRC 进行传输&a…

红与蓝:现代Webshell检测引擎免杀对抗与实践

上半年Webshell话题很火,业界举办了数场对抗挑战赛,也发布了多篇站在安全产品侧,着重查杀思路的精彩文章,但鲜有看到以蓝军视角为主的paper。 作为多场挑战赛的参赛者及内部红蓝对抗的参与者,笔者试着站在蓝军角度,聊聊现代Webshell对抗的一些思路,也以PHP Webshell为例…

堪比熊猫烧香!中国新型蠕虫病毒大爆发!电脑瞬间报废

堪比熊猫烧香&#xff01;中国新型蠕虫病毒大爆发&#xff01;电脑瞬间报废 近日&#xff0c;深信服安全团队监测到一种名为incaseformat的病毒&#xff0c;全国各个区域都出现了被incaseformat病毒删除文件的用户。 经调查&#xff0c;该蠕虫正常情况下表现为文件夹蠕虫&#…

Dreh zelle acht hoch

Android6.0权限和SharedPreferences存储 static class MyTask extends AsyncTask<String,String,String> { Override protected String doInBackground(String... strings) { FileOutputStream outnull; InputStream inputStreamnull;//网络连接的输入流 HttpURLConnecti…

json.cp37-win32.pyd HEUR/QVM30.2.223F.Malware...

问题 使用pyinstaller导出exe,运行时候会被360杀毒报木马. 病毒类型是HEUR/QVM30.2.223F.Malware.Gen 木马文件是 pandas库下的一个文件 \Python\Python37-32\Lib\site-packages\pandas\_libs\json.cp37-win32.pyd 原因 32位的pandas文件是 json.cp37-win32.pyd (32位的,3…

Herm Chart

参考链接 https://blog.csdn.net/QianLiStudent/article/details/111872100 https://www.jianshu.com/p/4bd853a8068b 1 概念 1.1 Helm 1.1.1 Helm是什么&#xff1f; Helm 是 Kubernetes 的包管理器。包管理器类似于我们在 Ubuntu 中使用的apt、Centos中使用的yum 或者Pyt…

关于桌面程序被安全软件误判为HEUR:Trojan.Win32.Generic的解决方案

最近写了一个桌面程序&#xff0c;里面用了些读取系统环境变量、提取文件图标、启动外部程序之类的操作。 然后…………卡巴斯基就把它识别成了HEUR:Trojan.Win32.Generic………… 咱遵纪守法好程序&#xff0c;怎么说是木马就是木马了呢&#xff1f;&#xff1f;&#xff1f; …