写得比较详尽,基本上解释清楚了,慢慢看能够看懂。
目录一、题目要求二、算法思想三、如何编程四、流程图1. 主程序2. 递归函数crossRiver五、源程序代码1. 主程序 DFS.m2. 过河函数 crossRiver.m3. 输出解的函数 showSolution.m六、结果显示七、小结
一、题目要求
问题描述:3名商人各带1名随从过河(从西岸到东岸),一只小船最多能容纳2人。随从们约定:在河的任意一岸,若随从人数多于商人人数,就杀人越货。但商人们知道了他们的约定,并且掌握着过河大权,他们该采取怎样的策略才能安全过河?
二、算法思想
这个问题实际上是一个迷宫问题,为什么这样说呢?请听我慢慢道来。
首先,我们将每次渡河前西岸的人员分布和船所在的位置统称为一个“状态”,用[u,v,1/0]表示,其中u,v表示商人、随从在西岸的人数,末分量1表示船在西岸,0表示船在东岸。人数有限,所以总的状态数是有限的,我们将符合条件的状态挑出来组成允许状态集合。
其次,船最多可容纳两个人,所以每次渡河时可供选择的方案也是有限的。我们将渡河方案用[u,v]表示,其中u,v分别表示上船的商人数和随从数,并将其称为决策变量,决策变量构成的集合称为决策变量集合。
可推得,共有20种允许状态,5个决策变量。
初始状态为[3,3,1]:3名商人、3名随从在西岸,船停靠在西岸;
终止状态为[0,0,0]:0名商人、0名随从在西岸,船停靠在东岸,此时商人和随从全部到达东岸,这样就确定了“迷宫”的入口和出口。
从一个状态到另一个状态的移动是通过决策变量实现的,这里的决策变量也就相当于“迷宫”中的一段路。
所以,我们的任务就是选择可行的路径,从“迷宫”的入口走到出口。
现在你应该觉得这好像是个迷宫问题,但心中应当还存有怀疑,因为只有入口和出口的话,并不能称得上是迷宫问题,那还有什么其他的特点呢?
想想我们是怎样解决迷宫问题的?从入口出发,沿某一方向前进,若能走通,则继续往前走;如果不能走通或是有某一分叉可以抵达出口,则沿原路退回到刚刚的分叉点,换个方向继续前进。重复这个过程,直至探索出所有可能的通路。(类似于摸着石头过河)
这个问题也是这样的,从初始状态开始,尝试某种渡河方案,若能到达未经过的允许状态,则采取该渡河方案;如果不能到达任何一种允许状态或者是能够抵达终止状态,则原路返回至刚刚的状态,尝试其他的渡河方案。重复这个过程,直到探索出所有的渡河方案。
读到这儿,你可能会感觉到,这真的就是一个迷宫问题。好,既然你认同了,咱就继续往下说。
三、如何编程
怎样利用计算机解决这类问题呢?栈+递归。
前面我们已经设定好了允许状态集合和决策变量集合。栈(什么是栈?你可以把它简单地想象成桶装薯片(只有一端开