基于数学推导&编程递归解决珐露珊角色邀约任务“堆栈塔”(汉诺塔)最少步数问题 您所在的位置:网站首页 汉诺塔公式规律 基于数学推导&编程递归解决珐露珊角色邀约任务“堆栈塔”(汉诺塔)最少步数问题

基于数学推导&编程递归解决珐露珊角色邀约任务“堆栈塔”(汉诺塔)最少步数问题

2024-07-12 05:31| 来源: 网络整理| 查看: 265

    珐露珊角色邀约任务中,有段分支提到了前辈发现的一种益智机关“堆栈塔”。现实当中,堆栈塔的原型其实就是汉诺塔问题(Hanoi Tower),先来看看游戏剧情里是如何介绍堆栈塔的

珐露珊任务分支【玩具与玩法】中对堆栈塔的介绍

    用汉诺塔的模型来解释玩法:给定3根柱子A,B,C,初始有n个圆环(记为1至n号,由小到大排序)在A上,最终目标是通过若干步移动,将所有圆环都移动到B上,且移动的规则为:

    ①1次移动只能1个圆环(且应当是A/B/C最上面的圆环)

    ②始终要求小号圆环堆叠在大号圆环上(形如金字塔形,例如不能将2号圆环移动到1号圆环之上)

图1:初始状态(以n=7为例):圆环1-7号都在A上

    下面UP将使用数学推导来解释最少步数的解法,并用编程解递归问题进行验证,最后阐述下本人的一些想法。

一. 数学推导

    我们设圆环数为n,将n个圆环从A全部移到B所需的最少步数为an

    首先,最简单的情况,就是仅1个圆环(n=1)时,只需要把A上的1号环移动到B即可,最少移动步数为1,a1=1,如下图:

图2:n=1的情形

    接下来我们考虑n>1的情形:

    如果我们要将所有圆环移到B,必经的一步当然是把n号圆环从A移到B,前提是要把1至n-1号圆环全部移走,并留出A、B两个柱子让第n号圆环进行移动操作。因此,1到n-1号圆环就只能按金字塔顺序堆叠在C上了。如下图3所示:

图3:将1至n-1号圆环从A移动到C

    那么怎么从初始状态图1变到图3的情形呢?不难发现,从图1到图3本质上只是将第1至n-1号圆环从A全部移动到C而已,这需要的最少步数是an-1。说明如果你每步都走最优路线,那么图3就是第an-1步。

    接着上面的操作,我们将第n号圆环从A移到B,这是第(an-1)+1步,得到下面的图4:

图4:将第n号圆环从A移动到B

    到达图4的情形后,我们下一步要将剩下的n-1个圆环全部叠到B上,细心的同学已经发现,这本质上也是将第1至n-1号圆环从C全部移动到B而已,需要的最少步数仍然是an-1。完成以后,就达到我们的目标啦↓

图5:所有圆环均排列在B上,目标达成

    通过上述描述,我们将n层汉诺塔解法分解为3个步骤:

    ①将n-1层汉诺塔整体从A移动到C,最少步数为an-1

    ②将第n个圆环从A移动到B,所需步数为1

    ③将n-1层汉诺塔整体从C移动到B,最少步数为an-1

    将上述三点的步数相加,由此求得所需最少步数的递推公式:

最少步数递推公式

    根据递推公式,可以解得an的表达式:

最少步数表达式

    我们不妨代入前8个正整数试试:

所需最少步数(n从1至8)

    回到邀约任务的剧情,可见前面几位小盆友在玩n=4和5的堆栈塔时,都没能实现最少步数。而前辈向旅行者提问的是n=7的情形,运用数学推导不难得到答案是127步↓

最少127步,136步可行但不是最优,100和108步有点扯了…

    众所周知,2×(2^(n-1)-1) + 1 = 2^(n) - 1,所以公式是没有问题的↓

珐前辈解读时刻

    这个游戏还是蛮有趣的,作为益智玩具(机关)都是不错的想法,只能说不愧是前辈😅

二. 程序编写(递归问题)

    对于进修过编程类课程的大学生来说,汉诺塔应该是再经典不过的递归问题了。上文已经通过数学推导掌握了规律,那么就可以通过递归算法重构汉诺塔模型,然后丢给计算机来思考就行。

    实现过程也很简单,我们先构建2个函数↓

    ①move函数

move函数定义

    该函数表示单独1次移动的操作,形参src和dest分别表示拿出圆环和放入圆环的两根柱子,也就是将src最上方的圆环移动到dest上,同时用count记录1次移动次数。

    ②hanoi函数

hanoi函数定义

    hanoi函数是递归函数,其算法原理就是先前讨论过的三个步骤。当输入层数n,初始柱src,中间柱medium,目标柱dest后,如果n=1,就只需调用一次move函数。否则就要拆分成三个步骤:

    (1)把1至n-1号的圆环从初始柱src移动到medium(注:此时递归函数hanoi中的目标柱变成了medium,而中间柱变成了dest)。

    (2)把第n号圆环从src移动到dest(调用一次move函数即可)。

    (3)将剩下的在medium里的n-1层圆环全部移动到dest(此时递归函数hanoi中初始柱为medium,目标柱为dest)

    最后来个实例,我们利用上述2个函数编写n=4时的输出代码:

输出实例

    运行一下,可以得到n=4的最少步数以及每一步的移动方法:

运行结果(以n=4为例)

    当然,也可以略微修改代码来输出每个n对应的最少步数:

最少移动步数结果(n从1至16)

    任取正整数n,只需要跟着计算机的每一步走,就能以最少的步数完成目标。当然,hanoi塔毕竟是一款益智游戏,还是自己动手玩比较有意思🤗

三、对“堆栈塔”命名的一些想法

    原神的文案策划是懂命名的,因为汉诺塔每根柱子处理圆环的方式和计算机术语中的“堆栈”是相似的,可以了解下【栈】的定义:

栈的定义—图源百度

      说简单些,就是将若干个元素依次存进一个列表里,但是只允许对栈顶元素(最新存入的元素)进行插入、删除等操作,那么这个受限制的线性表就称为【栈】。

    对于汉诺塔的三根柱子,可以视为三个堆栈,每根柱子最上面的圆环就是所谓的栈顶元素。因为如果要想移动A柱子上的圆环,有且仅有最上面的圆环可以取走,同时,如果想要把新的圆环放进A,有且仅有最上面的位置可以堆叠(而不能从中间插入)。

    严格上讲,汉诺塔的存放方式比堆栈更加严格,因为汉诺塔还要求大圆环(高值元素)不能堆叠在小圆环(低值元素)之上…

    这么一看,用“堆栈塔”来命名,确实是挺合理的嘛 (o゜▽゜)o



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有