前言
现代认知心理学用于研究人的问题解决过程的心理特点的一个实验。河内塔问题的初始状态有A、B、C三根柱子,在A柱上有中间带孔从大到小由下到上重叠像“塔”一样的若干圆盘。目标状态是将“塔”移到C柱上,B柱作为过渡。规则是每次只能移动最上面的一个圆盘, 大圆盘不能压在小圆盘上。要求探索从初始状态到目标状态的通路,最终解决问题,达到目标状态。被试者一边思考,一边大声报告出思考的内容。主试根据被试的口头报告, 分析其思维活动过程。
一、Hanoi塔问题是什么?
河内塔问题是问题解决研究中的经典实验。给出柱子1、2、3,在柱1上,有一系列圆盘,自上而下圆盘的大小是递增的,构成金字塔状。要求被试将柱1的所有圆盘移到柱3上去,且最终在柱3上仍构成金字塔排列,规则是每次只能移动一个圆盘,且大盘不可压在小盘之上,可以利用圆柱2。完成河内塔作业的最少移动次数为2-1次,其中n为圆盘的数目。
二、问题描述
一块板上有三根针 A、B、C。A 针上套有 64 个大小不等的圆盘,按照大的在下、小的在上的顺序排列,要把这 64 个圆盘从 A 针移动到 C 针上,每次只能移动一个圆盘,移动过程可以借助 B 针。但在任何时候,任何针上的圆盘都必须保持大盘在下,小盘在上。从键盘输入需移动的圆盘个数,给出移动的过程。
三、算法思想
当只移动一个圆盘时,直接将圆盘从 A 针移动到 C 针。
若移动的圆盘为 n(n>1),则分成几步走:
- 把 (n-1) 个圆盘从 A 针移动到 B 针(借助 C 针);
- A 针上的最后一个圆盘移动到 C 针;
- B 针上的 (n-1) 个圆盘移动到 C 针(借助 A 针)。
每做一遍,移动的圆盘少一个,逐次递减,最后当 n 为 1 时,完成整个移动过程。
因此,解决汉诺塔问题可设计一个递归函数,利用递归实现圆盘的整个移动过程,问题的解决过程是对实际操作的模拟。
四、解决策略
解决河内塔问题有以下四种常用策略:
- 循环子目标,又称目标递归策略:思路是要把最大的金字塔移到柱3,就要先把次大的金字塔移到柱 2;而要把次大的金字塔移到柱2,就要先把比它小一层的金字塔移到柱3;…依次类推,直到只需要移动最上面的盘为止。这种策略类似计算机的递归,它是内部指导的策略,被试不必看具体刺激,只是把内部目标记在脑中,然后一步步循环执行,直到解决问题。
- 知觉策略:这种策略是刺激指导的策略,根据所看到的情景与目标的关系,排除当前最大的障碍,从而一步步达到目标。
- 模式策略:也是内部指导的策略,但不涉及目标,而是按一定规则来采取行动。解决河内塔的通用规则是,当圆盘的总数为奇数时,最小的圆盘按1->3->2->1->3->2的顺序移动,当总数为偶数时,按1->2->3->1->2->3的顺序移动。
- 机械记忆策略:这种策略是将做对的一系列步骤死记硬背下来,但无法创新,不可迁移。
五、代码实现
这里我以第一种解决策略为例进行代码编写
示例代码:
#include<iostream>
using namespace std;
int m=0; //对搬动计数
void move(char A,int n,char C) //搬动操作
{
cout<<"第"<<++m<<"步,"<<"将编号为"<<n<<"的圆盘从第"<<A<<"个柱子上移到第"<<C<<"个柱子上"<<endl;
}
void hanoi(int n,char A,char B,char C) //将塔座A上的n个圆盘按规则搬到C上
{
if(n==1)
move(A,1,C);
else
{
hanoi(n-1,A,C,B); //将A上编号为1至n-1的圆盘移到B,C做辅助塔
move(A,n,C); //将编号为n的圆盘从A移到C
hanoi(n-1,B,A,C); //将B上编号为1至n-1的圆盘移到C,A做辅助塔
}
}
int main()
{
int n;
char a,b,c;
a='1';
b='2';
c='3';
cout<<"请输入初始第一个柱子上的圆盘个数:"<<endl;
cin>>n;
cout<<"将第一个柱子上的圆盘全部移动到第三个柱子上的过程为:"<<endl;
hanoi(n,a,b,c);
return 0;
}