- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
多对商人过河数学建模
多对商仆过河问题
12对商人过河
——(算法中多少对可以改变,此为N=12的时候,稍加修改便可以成为你需要的对数解决方案)
摘要
本文针对商人安全渡河的问题,采用多步决策的过程建立数学模型,求解得到了在随从没有杀人越货的情况下的渡河方案。
对于本题而言,在12名商人、12名随从、船的最大容量为2的情况下,首先定义了渡河前此岸的状态,并设安全渡河条件下的状态集定义为允许状态集合,接着得到渡河方案的允许决策集合,然后得到状态随渡河方案变化的规律,最后利用 dijkstra算法 ,并利用Microsoft Visual C++ 6.0软件,编译运行程序得到了一种商人安全渡河的方案。
但是,本文不仅仅是为了拼凑出一个可行方案,而是希望能找到求解这类问题的规律性,并建立数学模型,用以解决更为广泛的问题。基于此目的,利用了dijkstra算法,得到最短路径的最优解。但同时由于该算法遍历计算的节点很多,所以效率低,而且当有多个最短距离时,不能够将所有符合条件的情况逐一列出。我们通过对程序的改善,使可以运行比较多的将符合条件的情况列出来。
1 问题重述
十二名商人各带一个随从乘船渡河,一只小船只能容纳二人,由他们自己划行。在河的任意一岸,一旦随从的人数比商人多,商人就有危险.但是如何乘船渡河的大权掌握在商人们手中。商人们怎样才能安全渡河呢?同时,推广到M名商人带M名随从又如何?
2 问题分析
安全渡河问题可以看成一个多步决策过程。每一步,即船由此岸驶向彼岸或从彼岸驶回此岸,都要对船上的人员(商人随从各几人)作出决策,在保证安全的前提下(两岸的商人数都不比随从数少),在有限步内使人员全部过河。用状态(变量)表示某一岸的人员状况,决策(变量)表示船上的人员状况,可以找出状态随决策变化的规律。问题转化为在状态的允许变化范围内(即安全渡河条件),确定每一步的决策,达到渡河的目的。
此类智力问题经过思考,可以拼凑出一个可行方案。但是,我们现在希望能找到求解这类问题的规律性,并建立数学模型,用以解决更为广泛的问题。
3 模型假设及符号说明
3.1 模型假设
(1)每个商人和随从都会划船;
(2)只有一条船,且每条船上最多只能乘坐两个人;
(3)所有商人与随从之间没有矛盾,不会出现两人不愿意坐一条船的现象;
(4)船在渡河的过程中不受外界环境的影响。
3.2 符号说明
初始状态下,商人和随从所在的一岸;
初始状态下,商人和随从欲到达的一岸;
S 商仆对数
K 船最多载人的数目
4 模型的建立与求解
4.1 模型的建立
根据题意,可以作出商人渡河初始状态的示意图:
渡河目的:——(选择岸为参考点)
4.2 C++程序解决
根据(1)(2)(3)式,通过利用matlab编写一段程序来求解多步决策问题是可行的,但是当商人和随从数都不多的情况下还可以用平面坐标法解此模型更为方便。接下来,我们先用平面坐标法求解此模型,最后再使用计算机仿真,对求解的结果进行验证,并给予推广。
4.2.1 C++程序代码
//约束条件:岸上仆人不能多于商人数
#include iostream
using namespace std;
struct Node
{ int nMer;
int nSer;
int length;
};
class A
{
public:
A();
~A();
void Tspt(); //过河的动作
void doLeft(int nhead,int ntail,int nlength);
private:
bool islegal(int nm,int ns); //判断是否满足约束条件,满足为true
Node *funTspt(int nm,int ns,bool flag);//添加STEP[head]可以向后延伸的节点
bool noRepeat(int nm,int ns);//没有重复返回TRUE
void funshow(int a[][2],int ntail);
bool funLeft(Node nd,int b1,int b2,int n);
void show(int s[],int p[][2],int top,int count,int a[]);
int head;
int tail;
int n; //商仆的对数
int nB; //船最多的载人数目
Node *STEP;
};
A::~A()
{
free(STEP);
}
A::A()
{
cout请输入商仆的对数S=;
F: cinn;
if(n==1)
{
nB=2;
cout船最多载人的数目K=nB;
}
else if(n==2)
{
文档评论(0)