商人过河matlab程序以及解析

合集下载

商人过河问题数学建模

商人过河问题数学建模

做业1、2:之阳早格格创做商人过河一、问题沉述问题一:4个商人戴着4个随从过河,过河的工具惟有一艘小船,只可共时载二部分过河,包罗划船的人.随从们稀约, 正在河的任一岸, 一朝随从的人数比商人多, 便杀人越货.乘船渡河的规划由商人决断.商人们何如才搞仄安过河?问题二:假若小船不妨容3人,请问最多不妨有几名商人各戴一名随从仄安过河.二、问题分解问题不妨瞅搞一个多步计划历程.每一步由此岸到此岸或者此岸到此岸船上的人员正在仄安的前提下(二岸的随从数没有比商人多),经有限步使部分人员过河.用状态变量表示某一岸的人员情景,计划变量表示船上的人员情况,不妨找出状态随计划变更的顺序.问题便变换为正在状态的允许变更范畴内(即仄安渡河条件),决定每一步的计划,达到仄安渡河的目标.三.问题假设1. 过河途中没有会出现没有成抗力的自然果素.2. 当随从人数大于商人数时,随从们没有会改变杀人的计划.3.船的品量很佳,正在多次谦载的情况下也能仄常运做.4. 随从会听从商人的调动.四、模型形成x(k)~第k 次渡河前此岸的商人数 x(k),y(k)=0,1,2,3,4; y(k)~第k 次渡河前此岸的随从数 k=1,2,…..s(k)=[ x(k), y(k)]~历程的状态 S~允许状态集中 S={(x,y)|x=0,y=0,1,2,3,4; x=4,y=0,1,2,3,4;x=y=1,2,3} u(k)~第k 次渡船上的商人数 u(k), v(k)=0,1,2;v(k)~ 第k 次渡船上的随从数 k=1,2…..d(k)=( u(k), v(k))~历程的计划 D~允许计划集中 D={u,v|u+v=1,2,u,v=0,1,2}状态果计划而改变s(k+1)=s(k)+(-1)^k*d(k)~状态变化律供d(k)ÎD(k=1,2,….n),使s(k)ÎS 并按变化律s(k+1)=s(k)+(-1)^k*d(k)由(4,4)到达(0,0)数教模型: k+1kS =S +k k D (-1)(1)'4k k x x += (2)'4k k y y +=(3)k.k x y ≥ (4)''k k x y ≥(5)模型分解:由(2)(3)(5)可得化简得概括(4)可得k k x y =战 {}(,)|0,0,1,2,3,4k k k k k S x y x y ===(6) 还要思量{}'(',')|'0,'0,1,2,3,4k k k k k S x y x y === (7)把(2)(3)戴进(7)可得化简得{}(,)|4,0,1,2,3,4k k k k k S x y x y === (8)概括(6)(7)(8)式可得谦脚条件的情况谦脚下式 {}(,)|0,4,0,1,2,3,4;k k k k k k k S x y x y x y ====(9) 所以咱们知讲谦脚条件的面如上图所示:面移动由{}(,)|4,0,1,2,3,4k k k k k S x y x y === (8)到达{}(,)|0,0,1,2,3,4k k k k k S x y x y ===(6)时,不妨认为完毕渡河.果为移动的格数小于等于2,惟有核心面(2,2)到(6)面战(8)面的距离为2,所以核心面(2,2)成为渡河的闭键面.当咱们移动到(2,2)面时,便无法举止下去.故4个商人,4个随从,船容量为2人时,无法仄安渡河. 对付于问题二,咱们不妨修坐模型为:k+1k S =S +k k D (-1)(10)'k k x x M += (11)'k k y y M += (12)k.k x y ≥(13)''k k x y ≥ (14)u(k), v(k)=0,1,2,3; (15)通过类似于问题一的步调不妨知讲:坐标上的闭键面是(3,3),最多不妨五名商人戴五名随从往日.需要决定五名商人戴五名随从的规划可止再决定六名商人戴六名随从的规划没有成止1、五名商人戴五名随从的情况:(1)最先没有成能有三名商人先过河,二名商人一名随从过河,一名商人二名随从过河(2)三个随从先过河(5,2),回去一个随从(5,3),往日二个随从(5,1)回去一个随从(5,2),再往日三个商人(2,2),回去一个商人一个随从(3,3),再往日三个商人(0,3),回去一个随从(0,4),往日三个随从(0,1),回去一个随从(0,2)再往日二个随从(0,0)综上可知:五名商人戴五名随从,小船不妨载三部分不妨过河2、六名商人戴六名随从的情况:(1)最先没有成能有三名商人先过河,二名商人一名随从过河,一名商人二名随从过河(2)三个随从先过河(6,3),回去一个随从(6,4),往日二个随从(6,2)回去一个随从(6,3),往日三个商人(3,3),此时二岸皆是(3,3),由坐标法分解知,那是最交近末面的临界面,然而是如果回去的时间一定是回去一个商人战一个随从,如果那一步可止,后里便举止没有去综上所述,六个商人戴六个随从,小船载三部分的情况下没有克没有及渡河分离1、2知,当小船最多载三部分的时间,最多五名商人各戴一个随从不妨过河.五、模型的考验取评介由少量人的过河问题推广到了更普遍人的过河问题,使得问题变得明白有顺序.六、参照文件[1]章胤,2014年燕山大教世界大教死数教修模竞赛训练ppt,2014年4月17日。

数学建模:研究商人过河问题

数学建模:研究商人过河问题

数学建模实验一陈说之吉白夕凡创作实验题目:研究商人过河问题一、实验目的:编写一个法式(可以是C,C++或Mathlab )实现商人平安过河问题.二、实验环境:Turbo c 2.0、、Matlab 6.0以上三、实验要求:要求该法式不单能找出一组平安过河的可行方案, 还可以获得所有的平安过河可行方案.而且该法式具有一定的可扩展性, 即不单可以实现3个商人, 3个随从的过河问题.还应能实现n 个商人, n 个随从的过河问题以及n 个分歧对象且每个对象有m 个元素问题(说明:对3个商人, 3个随从问题分别对应于n=2,m=3)的过河问题.从而给出课后习题5(n=4,m=1)的全部平安过河方案.四、实验步伐:第一步:问题分析.这是一个多步决策过程, 涉及到每一次船上的人员以及要考虑彼岸和彼岸上剩余的商人数和随从数, 在平安的条件下(两岸的随从数不比商人多), 经有限步使全体人员过河. 第二步:分析模型的构成.记第k 次渡河前彼岸的商人数为k x , 随从数为k y , 2,1=k , n y x k k 2,1,=, (具有可扩展性), 将)(k k y x ,界说为状态, 状态集合成为允许状态集合(S ).S={2,1;3,2,1,0,3;3,2,1,0,0|,======y x y x y x y x )(}记第k 次渡船的商人数为k u , 随从数为k v , 决策为),(k k v u , 平安渡河条件下, 决策的集合为允许决策集合.允许决策集合记作D, 所以D={2,1,0,,21|,=<+<v u v u v u )(|1<u+v<2,u,v=0,1,2},因为k 为奇数时船从彼岸驶向彼岸, k 为偶数时船由彼岸驶向彼岸, 所以状态k s 随决策k d 变动的规律是k k k k d s s )1(1-+=-, 此式为状态转移律.制定平安渡河方案归结为如下的多步决策模型:求决策)2,1(n k D d k =∈, 使状态S s k ∈依照转移律, 由初始状态)3,3(1=s 经有限n 步达到)0,0(1=+n s第三步:模型求解.#include "stdio.h"#include "string.h"#include <memory>#include <stdlib.h>#include <iostream>using namespace std;#include "conio.h"FILE *fp;/*设立文件指针, 以便将它用于其他函数中*/struct a{long m,s;struct a *next;};/*数组类型a :记录各种情况下船上的商人和仆人数, m :代表商人数 s :代表仆人数*/struct a *jj,head;/*head为头指针的链表单位(船上的人数的各种情况的链表)*/int n,total=0,js=0;/*total暗示船上各种情况总数*/struct aim {long m1,s1,m2,s2;int n;struct aim *back,*next;};/*用于建立双向的指针链表, 记入符合的情况, m1, s1暗示要过岸的商人数和仆人数;m2, s2暗示过岸了的商人数和仆人数, n暗示来回的次数*/int k1,k2;void freeit(struct aim *p){struct aim *p1=p;p1=p->back;free(p);if(p1!=NULL)p1->next=NULL;return;}/*释放该单位格, 并将其上的单位格的next指针还原*/int determ(struct aim *p){ struct aim *p1=p;if(p->s1>k2)return -1;/*仆人数不能超越总仆人数*/if(p->m1>k1)return -1;/*商人数不能超越总商人数*/if(p->s2>k2)return -1;/*对岸, 同上*/if(p->m2>k1)return -1;/*对岸, 同上*/if(p->s1<0)return -1;/*仆人数不能为负*/if(p->s2<0)return -1;/*商人数不能为负*/if(p->m1<0)return -1;/*对岸, 同上*/if(p->m2<0)return -1;/*对岸, 同上*/if(p->m1!=0)if(p->s1>p->m1)return -1;if(p->m2!=0)if(p->s2>p->m2)return -1;/*两岸商人数均不能小于仆人数*/ while(p1!=NULL){p1=p1->back;if(p1!=NULL)if(p1->n%2==p->n%2)if(p1->s1==p->s1)if(p1->s2==p->s2)if(p1->m1==p->m1)if(p1->m2==p->m2)return -1;}/*用于解决重复, 算法思想:即将每次算出的链表单位与以前的相比力, 若重复, 则暗示呈现循环*/if(p->s1==0&&p->m1==0)if(p->n%2==0)return 1;else return -1;/*显然如果达到条件就说明ok了*/return 0;}/*判断函数*/int sign(int n){if(n%2==0)return -1;return 1;}/*符号函数*/void copyit(struct aim *p3,struct aim *p){p3->s1=p->s1;p3->s2=p->s2;p3->m1=p->m1;p3->m2=p->m2;p3->n=p->n+1;p3->back=p;p3->next=NULL;p->next=p3;}/*复制内容函数, 将p中的内容写入p3所指向的链表单位中*/ void print(struct aim *p3){struct aim *p=p3;js++;while(p->back){p=p->back;}printf("\n第%d种方法:\n",js);fprintf(fp,"\n第%d种方法:\n",js);int count=0;while(p){ printf("%ld,%ld::%ld,%ld\t",p->m1,p->s1,p->m2,p->s2);fprintf(fp,"%ld,%ld::%ld,%ld\t",p->m1,p->s1,p->m2,p->s2); p=p->next;count++;}cout<<"一共有"<<count<<"步完成"<<endl;}/*打印函数, 将p3所指的内容打印出来*/void trans(struct aim *p){struct aim *p3;/*p3为申请的结构体指针*/struct a *fla;int i,j,f;fla=&head;p3=(struct aim *)malloc(sizeof(struct aim));f=sign(p->n);for(i=0;i<total;i++){fla=fla->next;copyit(p3,p);p3->s1-=fla->m*f;p3->m1-=fla->s*f;p3->s2+=fla->m*f;p3->m2+=fla->s*f;/*运算过程, 即过河过程*/j=determ(p3);/*判断, j记录判断结果*/ if(j==-1){if(i<total-1){continue;}else{freeit(p3);break;}}int count1=0;if(j==1){if(i<total-1){print(p3); count1++;continue;}else{print(p3);freeit(p3);break;}//cout<<cout1<<endl;printf("%d",count1);printf("\n");}if(j==0)trans(p3);}return;}/*转移函数, 即将人转移过河*//*n=0*/void main(){ struct aim *p,*p1;int j,a,e,f;struct a *flag;/*flag是用与记录头指针*/FILE*fpt;if((fpt=fopen("c:result.dat","w+"))==0){printf("can't creat it\n");exit(0);}fp=fpt;system("cls");printf("问题描述:三个商人各带一个随从搭船过河, 一只小船只能容纳X人, 由他们自己划船.三个商人窃听到随从们密谋, 在河的任意一岸上, 只要随从的人数比上人多, 就杀失落商人.可是如何搭船渡河的决策权在商人手里, 商人们如何安插渡河计划确保自身平安?\n");printf("\n");p=(struct aim *)malloc(sizeof(struct aim));p->back=NULL;p->next=NULL;p->s2=0;p->m2=0;p->n=1;/*设立初始头指针*/printf("please input the total of people on the board\n");fprintf(fp,"\n请输入船上的人数\n");scanf("%d",&n);fprintf(fp,"\n%d\n",n);flag=&head;for(e=0;e<=n;e++)for(f=0;f<=n;f++)if(e+f>0&&e+f<=n){ total++;jj=(struct a*)malloc(sizeof(struct a));jj->m=e;jj->s=f;flag->next=jj;jj->next=NULL;flag=jj;}/*********************************/printf("please input the total of merchant and salvent as follow: mechant,salvent;\n");fprintf(fp,"\nplease input the total of merchant and salvent as follow: mechant,salvent;\n");scanf("%ld,%ld",&p->m1,&p->s1);fprintf(fp,"\n%ld,%ld\n",p->m1,p->s1);/**********************************/k1=p->m1;k2=p->s1;trans(p);fclose(fpt);getch();}第一步:三个商人, 三个随从的模型求解谜底为:运行后的结果为:第 1 种方案:(3,3) 到 (0,0)、(3,1) 到 (0,2)、(3,2) 到(0,1)、(3,0) 到 (0,3)、(3,1) 到 (0,2)、(1,1) 到 (2,2)、(2,2) 到 (1,1)、(0,2) 到 (3,1)、(0,3) 到 (3,0)、(0,1) 到(3,2)、(0,2) 到 (3,1)、(0,0) 到 (3,3)第 2 种方案:(3,3) 到 (0,0)、(3,1) 到 (0,2)、(3,2) 到(0,1)、(3,0) 到 (0,3)、(3,1) 到 (0,2)、(1,1) 到 (2,2)、(2,2) 到 (1,1)、(0,2) 到 (3,1)、(0,3) 到 (3,0)、(0,1) 到(3,2)、(1,1) 到 (2,2)、(0,0) 到 (3,3)第 3 种方案:(3,3) 到 (0,0)、(2,2) 到 (1,1)、(3,2) 到(0,1)、(3,0) 到 (0,3)、(3,1) 到 (0,2)、(1,1) 到 (2,2)、(2,2) 到 (1,1)、(0,2) 到 (3,1)、(0,3) 到 (3,0)、(0,1) 到(3,2)(、0,2) 到 (3,1)、(0,0) 到 (3,3)第 4 种方案:(3,3) 到 (0,0)、(2,2) 到 (1,1)、(3,2) 到(0,1)、(3,0) 到 (0,3)、(3,1) 到 (0,2)、(1,1) 到 (2,2)、(2,2) 到 (1,1)、(0,2) 到 (3,1)、(0,3) 到 (3,0)、(0,1) 到(3,2)、(1,1) 到 (2,2)(0,0) 到 (3,3)第二步:四个商人三个随从, 其结果为:第1种方法:4,3::0,0 3,2::1,1 4,2::0,1 2,2::2,1 3,2::1,12,1::2,2 2,2::2,1 0,2::4,1 0,3::4,0 0,1::4,21,1::3,2 0,0::4,3 一共有12步完成第2种方法:4,3::0,0 3,2::1,1 4,2::0,1 2,2::2,1 3,2::1,12,1::2,2 2,2::2,1 0,2::4,1 0,3::4,0 0,1::4,22,1::2,2 1,0::3,3 1,1::3,2 0,0::4,3一共有14步完成第3种方法:4,3::0,0 3,2::1,1 4,2::0,1 2,2::2,1 3,2::1,12,1::2,2 2,2::2,1 0,2::4,1 0,3::4,0 0,1::4,20,2::4,1 0,0::4,3 一共有12步完成第4种方法:4,3::0,0 3,2::1,1 4,2::0,1 2,2::2,1 3,2::1,12,1::2,2 2,2::2,1 1,1::3,2 2,1::2,2 0,1::4,21,1::3,2 0,0::4,3 一共有12步完成第5种方法:4,3::0,0 3,2::1,1 4,2::0,1 2,2::2,1 3,2::1,12,1::2,2 2,2::2,1 1,1::3,2 2,1::2,2 0,1::4,20,2::4,1 0,0::4,3 一共有12步完成第6种方法:4,3::0,0 3,2::1,1 4,2::0,1 2,2::2,1 3,2::1,12,1::2,2 2,2::2,1 1,1::3,2 2,1::2,2 1,0::3,31,1::3,2 0,1::4,2 0,2::4,1 0,0::4,3 一共有14步完成第7种方法:4,3::0,0 3,2::1,1 4,2::0,1 2,2::2,13,2::1,12,1::2,2 2,2::2,1 1,1::3,2 2,1::2,2 1,0::3,31,1::3,2 0,0::4,3 一共有12步完成第8种方法:4,3::0,0 3,2::1,1 4,2::0,1 4,0::0,3 4,1::0,22,1::2,2 2,2::2,1 0,2::4,1 0,3::4,0 0,1::4,21,1::3,2 0,0::4,3 一共有12步完成第9种方法:4,3::0,0 3,2::1,1 4,2::0,1 4,0::0,3 4,1::0,22,1::2,2 2,2::2,1 0,2::4,1 0,3::4,0 0,1::4,22,1::2,2 1,0::3,3 1,1::3,2 0,0::4,3一共有14步完成第10种方法:4,3::0,0 3,2::1,1 4,2::0,1 4,0::0,3 4,1::0,22,1::2,2 2,2::2,1 0,2::4,1 0,3::4,0 0,1::4,20,2::4,1 0,0::4,3 一共有12步完成第11种方法:4,3::0,0 3,2::1,1 4,2::0,1 4,0::0,3 4,1::0,22,1::2,2 2,2::2,1 1,1::3,2 2,1::2,2 0,1::4,21,1::3,2 0,0::4,3 一共有12步完成第12种方法:4,3::0,0 3,2::1,1 4,2::0,1 4,0::0,3 4,1::0,22,1::2,2 2,2::2,1 1,1::3,2 2,1::2,2 0,1::4,20,2::4,1 0,0::4,3 一共有12步完成第13种方法:4,3::0,0 3,2::1,1 4,2::0,1 4,0::0,3 4,1::0,22,1::2,2 2,2::2,1 1,1::3,2 2,1::2,2 1,0::3,31,1::3,2 0,1::4,2 0,2::4,1 0,0::4,3一共有14步完成第14种方法:4,3::0,0 3,2::1,1 4,2::0,1 4,0::0,34,1::0,22,1::2,2 2,2::2,1 1,1::3,2 2,1::2,2 1,0::3,31,1::3,2 0,0::4,3 一共有12步完成第15种方法:4,3::0,0 3,2::1,1 3,3::1,0 2,2::2,1 3,2::1,12,1::2,2 2,2::2,1 0,2::4,1 0,3::4,0 0,1::4,21,1::3,2 0,0::4,3 一共有12步完成第16种方法:4,3::0,0 3,2::1,1 3,3::1,0 2,2::2,1 3,2::1,12,1::2,2 2,2::2,1 0,2::4,1 0,3::4,0 0,1::4,22,1::2,2 1,0::3,3 1,1::3,2 0,0::4,3一共有14步完成第17种方法:4,3::0,0 3,2::1,1 3,3::1,0 2,2::2,1 3,2::1,12,1::2,2 2,2::2,1 0,2::4,1 0,3::4,0 0,1::4,20,2::4,1 0,0::4,3 一共有12步完成第18种方法:4,3::0,0 3,2::1,1 3,3::1,0 2,2::2,1 3,2::1,12,1::2,2 2,2::2,1 1,1::3,2 2,1::2,2 0,1::4,21,1::3,2 0,0::4,3 一共有12步完成第19种方法:4,3::0,0 3,2::1,1 3,3::1,0 2,2::2,1 3,2::1,12,1::2,2 2,2::2,1 1,1::3,2 2,1::2,2 0,1::4,20,2::4,1 0,0::4,3 一共有12步完成第20种方法:4,3::0,0 3,2::1,1 3,3::1,0 2,2::2,1 3,2::1,12,1::2,2 2,2::2,1 1,1::3,2 2,1::2,2 1,0::3,31,1::3,2 0,1::4,2 0,2::4,1 0,0::4,3一共有14步完成第21种方法:4,3::0,0 3,2::1,1 3,3::1,0 2,2::2,13,2::1,12,1::2,2 2,2::2,1 1,1::3,2 2,1::2,2 1,0::3,31,1::3,2 0,0::4,3 一共有12步完成第22种方法:4,3::0,0 3,2::1,1 3,3::1,0 2,2::2,1 4,2::0,14,0::0,3 4,1::0,2 2,1::2,2 2,2::2,1 0,2::4,10,3::4,0 0,1::4,2 1,1::3,2 0,0::4,3一共有14步完成第23种方法:4,3::0,0 3,2::1,1 3,3::1,0 2,2::2,1 4,2::0,14,0::0,3 4,1::0,2 2,1::2,2 2,2::2,1 0,2::4,10,3::4,0 0,1::4,2 2,1::2,2 1,0::3,3 1,1::3,20,0::4,3 一共有16步完成第24种方法:4,3::0,0 3,2::1,1 3,3::1,0 2,2::2,1 4,2::0,14,0::0,3 4,1::0,2 2,1::2,2 2,2::2,1 0,2::4,10,3::4,0 0,1::4,2 0,2::4,1 0,0::4,3一共有14步完成第25种方法:4,3::0,0 3,2::1,1 3,3::1,0 2,2::2,1 4,2::0,14,0::0,3 4,1::0,2 2,1::2,2 2,2::2,1 1,1::3,22,1::2,2 0,1::4,2 1,1::3,2 0,0::4,3 一共有14步完成第26种方法:4,3::0,0 3,2::1,1 3,3::1,0 2,2::2,1 4,2::0,14,0::0,3 4,1::0,2 2,1::2,2 2,2::2,1 1,1::3,22,1::2,2 0,1::4,2 0,2::4,1 0,0::4,3一共有14步完成第27种方法:4,3::0,0 3,2::1,1 3,3::1,0 2,2::2,1 4,2::0,14,0::0,3 4,1::0,2 2,1::2,2 2,2::2,12,1::2,2 1,0::3,3 1,1::3,2 0,1::4,2 0,2::4,10,0::4,3 一共有16步完成第28种方法:4,3::0,0 3,2::1,1 3,3::1,0 2,2::2,1 4,2::0,14,0::0,3 4,1::0,2 2,1::2,2 2,2::2,1 1,1::3,22,1::2,2 1,0::3,3 1,1::3,2 0,0::4,3 一共有14步完成第29种方法:4,3::0,0 4,1::0,2 4,2::0,1 3,2::1,1 3,3::1,02,2::2,1 3,2::1,1 2,1::2,2 2,2::2,1 0,2::4,10,3::4,0 0,1::4,2 1,1::3,2 0,0::4,3一共有14步完成第30种方法:4,3::0,0 4,1::0,2 4,2::0,1 3,2::1,1 3,3::1,02,2::2,1 3,2::1,1 2,1::2,2 2,2::2,10,3::4,0 0,1::4,2 2,1::2,2 1,0::3,3 1,1::3,20,0::4,3 一共有16步完成第31种方法:4,3::0,0 4,1::0,2 4,2::0,1 3,2::1,1 3,3::1,02,2::2,1 3,2::1,1 2,1::2,2 2,2::2,1 0,2::4,10,3::4,0 0,1::4,2 0,2::4,1 0,0::4,3一共有14步完成第32种方法:4,3::0,0 4,1::0,2 4,2::0,1 3,2::1,1 3,3::1,02,2::2,1 3,2::1,1 2,1::2,2 2,2::2,1 1,1::3,22,1::2,2 0,1::4,2 1,1::3,2 0,0::4,3 一共有14步完成第33种方法:4,3::0,0 4,1::0,2 4,2::0,1 3,2::1,1 3,3::1,02,2::2,1 3,2::1,1 2,1::2,2 2,2::2,12,1::2,2 0,1::4,2 0,2::4,1 0,0::4,3一共有14步完成第34种方法:4,3::0,0 4,1::0,2 4,2::0,1 3,2::1,1 3,3::1,02,2::2,1 3,2::1,1 2,1::2,2 2,2::2,1 1,1::3,22,1::2,2 1,0::3,3 1,1::3,2 0,1::4,2 0,2::4,10,0::4,3 一共有16步完成第35种方法:4,3::0,0 4,1::0,2 4,2::0,1 3,2::1,1 3,3::1,02,2::2,1 3,2::1,1 2,1::2,2 2,2::2,1 1,1::3,22,1::2,2 1,0::3,3 1,1::3,2 0,0::4,3一共有14步完成第36种方法:4,3::0,0 4,1::0,2 4,2::0,1 2,2::2,1 3,2::1,12,1::2,2 2,2::2,1 0,2::4,1 0,3::4,01,1::3,2 0,0::4,3 一共有12步完成第37种方法:4,3::0,0 4,1::0,2 4,2::0,1 2,2::2,1 3,2::1,12,1::2,2 2,2::2,1 0,2::4,1 0,3::4,0 0,1::4,22,1::2,2 1,0::3,3 1,1::3,2 0,0::4,3 一共有14步完成第38种方法:4,3::0,0 4,1::0,2 4,2::0,1 2,2::2,1 3,2::1,12,1::2,2 2,2::2,1 0,2::4,1 0,3::4,0 0,1::4,20,2::4,1 0,0::4,3 一共有12步完成第39种方法:4,3::0,0 4,1::0,2 4,2::0,1 2,2::2,1 3,2::1,12,1::2,2 2,2::2,1 1,1::3,2 2,1::2,2 0,1::4,21,1::3,2 0,0::4,3 一共有12步完成第40种方法:4,3::0,0 4,1::0,2 4,2::0,1 2,2::2,1 3,2::1,12,1::2,2 2,2::2,1 1,1::3,2 2,1::2,2 0,1::4,20,2::4,1 0,0::4,3 一共有12步完成第41种方法:4,3::0,0 4,1::0,2 4,2::0,1 2,2::2,1 3,2::1,12,1::2,2 2,2::2,1 1,1::3,2 2,1::2,2 1,0::3,31,1::3,2 0,1::4,2 0,2::4,1 0,0::4,3 一共有14步完成第42种方法:4,3::0,0 4,1::0,2 4,2::0,1 2,2::2,1 3,2::1,12,1::2,2 2,2::2,1 1,1::3,2 2,1::2,2 1,0::3,31,1::3,2 0,0::4,3 一共有12步完成第43种方法:4,3::0,0 4,1::0,2 4,2::0,1 4,0::0,3 4,1::0,22,1::2,2 2,2::2,1 0,2::4,1 0,3::4,00,1::4,21,1::3,2 0,0::4,3 一共有12步完成第44种方法:4,3::0,0 4,1::0,2 4,2::0,1 4,0::0,3 4,1::0,22,1::2,2 2,2::2,1 0,2::4,1 0,3::4,0 0,1::4,22,1::2,2 1,0::3,3 1,1::3,2 0,0::4,3 一共有14步完成第45种方法:4,3::0,0 4,1::0,2 4,2::0,1 4,0::0,3 4,1::0,22,1::2,2 2,2::2,1 0,2::4,1 0,3::4,0 0,1::4,20,2::4,1 0,0::4,3 一共有12步完成第46种方法:4,3::0,0 4,1::0,2 4,2::0,1 4,0::0,3 4,1::0,22,1::2,2 2,2::2,1 1,1::3,2 2,1::2,2 0,1::4,21,1::3,2 0,0::4,3 一共有12步完成第47种方法:4,3::0,0 4,1::0,2 4,2::0,1 4,0::0,3 4,1::0,22,1::2,2 2,2::2,1 1,1::3,2 2,1::2,2 0,1::4,20,2::4,1 0,0::4,3 一共有12步完成第48种方法:4,3::0,0 4,1::0,2 4,2::0,1 4,0::0,3 4,1::0,22,1::2,2 2,2::2,1 1,1::3,2 2,1::2,2 1,0::3,31,1::3,2 0,1::4,2 0,2::4,1 0,0::4,3 一共有14步完成第49种方法:4,3::0,0 4,1::0,2 4,2::0,1 4,0::0,3 4,1::0,22,1::2,2 2,2::2,1 1,1::3,2 2,1::2,2 1,0::3,31,1::3,2 0,0::4,3 一共有12步完成。

n-m-k商人渡河问题解的存在性及算法实现

n-m-k商人渡河问题解的存在性及算法实现
典例 子【 5 — 8 1 .
到 目前为 止 ,几个 商 人 n个 随从船 满 载 人 的渡 河 问题 【 ] ( 以下简称 n— n一 尼商 人渡 河 问题) 的程序 实现 虽 已给 出 了,但 佗一佗一 商人 渡河 问题解 的存在性 问题 还不 存在 相关 的结 论 .针 对 上面 的情 况 ,本 文将渡 河 问题推 广 到最 一股 的情况 ,给 出了 n个商 人 m 个 随

旦随从 的人 数 比商人 多 ,就 杀人越 货 .针对 这个 问题 ,建 立 多步决 策模 型 ,其具 体建模
本 文把 商 人渡 河 问题 视 为一 个 多步 决策 过程 ,每~ 步 f 即船 由此 岸驶 向彼岸 或彼 岸 驶
过程 如下 :
向此岸) 都要对船上的人员作出决策 ( 即决定船载几个商人与几个随从) ,在保证安全 的前
文章编号: 1 0 0 5 — 3 0 8 5 ( 2 0 1 3 ) 0 4 . 0 5 6 1 0 8
佗一m 一 商人 渡河 问题解 的存在性 及算法 实现冰
付艳玲 , 刘高峰。 , 张 伟0
( 1 一 河南财政税务高等专科学校信息工程系 ,郑州 4 5 1 4 6 4 ; 2 西安 电子科技大学雷达信号处理 国家重点实验室 ,西安 7 1 0 0 7 1 3 一 河南理 工大 学万方科技学 院,郑州 4 5 1 4 0 0 1

要:本文将商人渡 河 问题推 广到最一般 情况 ,即 n—m 一 商人渡河 问题 ,建立 了该 问题 的多步决策数 学模 型 .首先 ,根据 该数学模型得到 一棵状 态空问树 ,设计 了采用 递归 和 回溯方法遍历 该状 态空 间树 的算 法步骤 .其次 ,根据 部分运行结果 ,分析 了该 问题 的算 法复杂度 .最 后 ,分析 了该 问题解的存在性 ,并给 出了若干定理及其证 明。本文 已将 商人渡河 问题扩展成 为广泛 的经典例子,有利于解 决实际生活 中的问题 .

商人们怎样安全过河-(附MATLAB程序完整)

商人们怎样安全过河-(附MATLAB程序完整)

商人们怎样安全过河随从们密约, 在河的任一岸, 一旦随从的人数比商人多, 就杀人越货.但是乘船渡河的方案由商人决定.商人们怎样才能安全过河?问题分析:决策~ 每一步(此岸到彼岸或彼岸到此岸)船上的人员要求~在安全的前提下(两岸的随从数不比商人多),经有限步使全体人员过河. 建立模型xk~第k次渡河前此岸的商人数 xk, yk=0,1,2,3;yk~第k次渡河前此岸的随从数 k=1,2,|....sk=(xk , yk)~过程的状态 S ~ 允许状态集合S={(x , y) x=0, y=0,1,2,3; x=3, y=0,1,2,3; x=y=1,2}uk~第k次渡船上的商人数 uk, vk=0,1,2;vk~第k次渡船上的随从数 k=1,2,.....dk=(uk , vk)~决策 D={(u , v) u+v=1, 2} ~允许决策集合~状态转移律多步决策问题求dk D(k=1,2, n), 使sk S, 并按转移律由s1=(3,3)到达 sn+1=(0,0).模型求解穷举法~ 编程上机S={(x , y) x=0, y=0,1,2,3;x=3, y=0,1,2,3;x=y=1,2}图解法状态s=(x,y) ~ 16个格点允许状态~ 10个点允许决策 ~ 移动1或2格; k奇,左下移; k偶,右上移.d1,.......,d11给出安全渡河方案评注和思考规格化方法,易于推广考虑4名商人各带一随从的情况程序%%%%%%%%%%%%%%%% 开始 %%%%%%%%%%%%%%%%%%%%%%function jueche=guoheclear allclc%%%%%%%%%%程序开始需要知道商人和仆人数;%%%%%%%%%%%%%shangren=input('输入商人数目: ');puren=input('输入仆人数目: ');rongliang=input('输入船的最大容量: ');if puren>shangrenshangren=input('输入商人数目:');puren=input('输入仆人数目:');rongliang=input('输入船的最大容量:');end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 决策生成jc=1; %决策向量放在矩阵d中,jc为插入新元素的行标初始为1;for i=0:rongliangfor j=0:rongliangif (i+j<=rongliang)&(i+j>0) % 满足条D={(u,v)|1<=u+v<=rongliang,u,v=0,1,2}d(jc,1:3)=[i,j ,1]; %生成一个决策向量立刻扩充为三维;d(jc+1,1:3)=[-i,-j,-1]; % 同时生成他的负向量;jc=jc+2; % 由于生成两个决策向量,则jc要向下移动两个;endendj=0;end%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 状态数组生成kx=1; % 状态向量放在A矩阵中,生成方法同矩阵生成;for i=shangren:-1:0for j=puren:-1:0if ((i>=j)&((shangren-i)>=(puren-j)))|((i==0)|(i==shangren))% (i>=j)&((shangren-i)>=(puren-j)))|((i==0)|(i==shangren))为可以存在的状态的约束条件 A(kx,1:3)=[i,j,1]; %生成状态数组集合D `A(kx+1,1:3)=[i,j,0];kx=kx+2;endj=puren;end;%%%%%%%%%%%%%%% 将状态向量生成抽象矩阵%%%%%%%%%%%%%%%%%%%k=(1/2)*size(A,1);CX=zeros(2*k,2*k);a=size(d,1);for i=1:2*kfor j=1:ac=A(i,:)+d(j,:) ;x=find((A(:,1)==c(1))&(A(:,2)==c(2))&(A(:,3)==c(3))) ; v(i,x)=1; %x为空不会改变v值endend%%%%%%%%%%%%%%%%%%%%%%dijstra算法%%%%%%%%%%%%%%%%%%%%%%%%%%x=1; y=size(A,1);m=size(v,1);T=zeros(m,1);T=T.^-1;lmd=T;P=T;S=zeros(m,1);S(x)=1;P(x)=0; lmd(x)=0;k=x;while(1)a=find(S==0);aa=find(S==1);if size(aa,1)==mbreak;endfor j=1:size(a,1)pp=a(j,1);if v(k,pp)~=0if T(pp)>(P(k)+v(k,pp))T(pp)=(P(k)+v(k,pp));lmd(pp)=k;endendendmi=min(T(a));if mi==infbreak;d=find(T==mi);d=d(1);P(d)=mi;T(d)=inf;k=d;S(d)=1;endendif lmd(y)==infjueche='can not reach(不能过河)';return;endjueche(1)=y;g=2; h=y;while(1)if h==xbreak;endjueche(g)=lmd(h);g=g+1;h=lmd(h);endjueche=A(jueche,:);jueche(:,3)=[]; %%%%%%%%%%%%%%%%%% 程序完 %%%%%%%%%%%%%%%%%%欢迎您的下载,资料仅供参考!致力为企业和个人提供合同协议,策划案计划书,学习资料等等打造全网一站式需求。

商人过河模型问题的求解

商人过河模型问题的求解

《数学建模实验》课程考试试题----商人安全过河数学建模与求解一.问题提出:4名商人带4名随从乘一条小船过河,小船每次自能承载至多两人。

随从们密约, 在河的任一岸, 一旦随从的人数比商人多, 就杀人越货.乘船渡河的方案由商人决定,商人们如何才能安全渡河呢二.模型假设:商人和随从都会划船,天气很好,无大风大浪,且船的质量很好,可以保证很多次安全的运载商人和随从。

三.问题分析:商随过河问题可以视为一个多步决策过程,通过多次优化,最后获取一个全局最优的决策方案。

对于每一步,即船由此岸驶向彼岸或由彼岸驶向此岸,都要对船上的人员作出决策,在保证两岸的商人数不少于随从数的前提下,在有限步内使全部人员过河。

用状态变量表示某一岸的人员状况,决策变量表示船上的人员状况,可以找出状态随决策变化的规律,问题转化为在状态的允许变化范围内(即安全渡河条件),确定每一步的决策,达到安全渡河的目标。

四.模型构成:k x ~第k 次渡河前此岸的商人数,k y ~第k 次渡河前此岸的随从数 k x , k y =0,1,2,3,4; k =1,2,… …k S =(k x , k y )~过程的状态,S ~ 允许状态集合,S={(x , y )| x =0, y =0,1,2,3,4; x =4 ,y =0,1,2,3,4; x =y =1,2,3} k u ~第k 次渡船上的商人数k v ~第k 次渡船上的随从数k d =(k u , k v )~决策,D={(u , v )| 21≤+≤v u ,k u , k v =0,1,2} ~允许决策集合 k =1,2,… …因为k 为奇数时船从此岸驶向彼岸,k 为偶数时船从彼岸驶向此岸,所以状态k S 随决策k d 的变化规律是1+k S =k S +k )1(-k d ~状态转移律求k d ∈D(k =1,2, …n), 使k S ∈S, 并按转移律由1S =(4,4)到达状态1+n S =(0,0)。

数学模型实验商人过河

数学模型实验商人过河

《数学模型实验》实验报告姓名:王佳蕾学院:数学与信息科学学院地点:主楼402学号:20151001055 专业:数学类时间:2017年4 月16日一、实验名称:商人和仆人安全渡河问题的matlab实现二、实验目的:1.熟悉matlab基础知识,初步了解matlab程序设计;2.研究多步决策过程的程序设计方法;3.(允许)状态集合、(允许)决策集合以及状态转移公式的matlab表示;三、实验任务:只有一艘船,三个商人三个仆人过河,每一次船仅且能坐1-2个人,而且任何一边河岸上仆人比商人多的时候,仆人会杀人越货。

怎么在保证商人安全的情况下,六个人都到河对岸去,建模并matlab实现。

要求:代码运行流畅,结果正确,为关键语句加详细注释。

四、实验步骤:1.模型构成2.求决策3.设计程序4.得出结论(最佳解决方案)五、实验内容:(一)构造模型并求决策设第k次渡河前此岸的商人数为xk,随从数为yk,k=1,2,...,xk,yk=0,1,2,3.将二维向量sk=(xk,yk)定义为状态,安全渡河条件下的状态集合称为允许状态集合,记作S,S 对此岸和彼岸都是安全的。

S={(x,y)|x=0,y=0,1,2,3;x=3,y=0,1,2,3;x=y=1,2}设第k次渡船上的商人数为uk,随从数vk,将二维变量dk=(uk,vk)定义为决策,允许决策集合记为D,由小船的容量可知,D={(u,v)|1<=u+v<=2,u,v=0,1,2}k为奇数时,船从此岸驶向彼岸,k为偶数时,船从彼岸驶向此岸,状态sk随决策变量dk的变化规律为sk+1=sk+(-1)^k*dk(状态转移律)这样制定安全渡河方案归结为如下的多步决策模型:求决策dk∈D(k=1,2,...,n),使状态sk∈S,按照转移律,由初始状态s1=(3,3)经有限步n到达状态sn+1=(0,0)。

(二)程序设计(三)运行结果、六、 结论体会:安全渡河问题可以看成一个多步决策过程。

数学建模:研究商人过河问题

数学建模:研究商人过河问题

数学建模实验一报告实验题目:研究商人过河问题一、实验目的:编写一个程序(可以是C,C++或Mathlab )实现商人安全过河问题。

二、实验环境:Turbo c 2.0、Microsoft Visual C++ 6.0、Matlab 6.0以上 三、实验要求:要求该程序不仅能找出一组安全过河的可行方案,还可以得到所有的安全过河可行方案。

并且该程序具有一定的可扩展性,即不仅可以实现3个商人,3个随从的过河问题。

还应能实现 n 个商人,n 个随从的过河问题以及n 个不同对象且每个对象有m 个元素问题(说明:对于3个商人,3个随从问题分别对应于n=2,m=3)的过河问题。

从而给出课后习题5(n=4,m=1)的全部安全过河方案。

四、实验步骤:第一步:问题分析。

这是一个多步决策过程,涉及到每一次船上的人员以及要考虑此岸和彼岸上剩余的商人数和随从数,在安全的条件下(两岸的随从数不比商人多),经有限步使全体人员过河。

第二步:分析模型的构成。

记第k 次渡河前此岸的商人数为k x ,随从数为k y ,2,1=k ,n y x k k 2,1,=,(具有可扩展性),将)(k k y x ,定义为状态,状态集合成为允许状态集合(S )。

S={2,1;3,2,1,0,3;3,2,1,0,0|,======y x y x y x y x )(}记第k 次渡船的商人数为k u ,随从数为k v ,决策为),(k k v u ,安全渡河条件下,决策的集合为允许决策集合。

允许决策集合记作D ,所以D={2,1,0,,21|,=<+<v u v u v u )(|1<u+v<2,u,v=0,1,2},因为k 为奇数时船从此岸驶向彼岸,k 为偶数时船由彼岸驶向此岸,所以状态k s 随决策k d 变化的规律是k k k k d s s )1(1-+=-,此式为状态转移律。

制定安全渡河方案归结为如下的多步决策模型:求决策)2,1(n k D d k =∈,使状态S s k ∈按照转移律,由初始状态)3,3(1=s 经有限n 步到达)0,0(1=+n s第三步:模型求解。

商人们怎样安全过河-(附MATLAB程序完整)培训讲学

商人们怎样安全过河-(附MATLAB程序完整)培训讲学

商人们怎样安全过河建立模型xk~第k次渡河前此岸的商人数yk~第k次渡河前此岸的随从数sk=(xk , yk)~过程的状态S={(x , y) x=0, y=0,1,2,3; x=3, y=0,1,2,3; x=y=1,2} uk~第k次渡船上的商人数vk~第k次渡船上的随从数dk=(uk , vk)~ 决策多步决策问题求dk到达sn+仁(0,0).模型求解穷举法~ 编程上机S={(x , y) x=0, y=0,1,2,3;x=3, y=0,1,2,3; x=y=1,2}图解法状态s=(x,y) ~ 16个格点允许状态~ 10个“专点允许决策~移动1或2格;k奇,左下移;k偶右上移.d1,•……,d11给出安全渡河方案xk, yk=0,1,2,3;k=1,2,|....S~允许状态集合uk, vk=0,1,2;k=1,2,..…u+v=1,2} ~允许决策集合~状态转移律n),使sk S,并按转移律由s仁(3,3)要求~在安全的前提下(两岸的随从数不比商人多),经有限步使全体人员过河D={(u , v)D(k=1,2,评注和思考规格化方法 ,易于推广考虑 4 名商人各带一随从的情况 程序%%%%%%%%%%%%%%%% 开始 %%%%%%%%%%%%%%%%%%%%%% function jueche=guohe clear all clc%%%%%%%%%% 程序开始需要知道商人和仆人数; %%%%%%%%%%%%% shangren=input(' 输入商人数目 : '); puren=input(' 输入仆人数目 : ');rongliang=input(' 输入船的最大容量 : ');if puren>shangren shangren=input(' 输入商人数目 :'); puren=input(' 输入仆人数目 :'); rongliang=input(' 输入船的最大容量 :');end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 决 策 生成jc=1; %决策向量放在矩阵 fori=0:rongliangfor j=0:rongliangif (i+j<=rongliang)&(i+j>0)d(jc,1:3)=[i,j ,1];d(jc+1,1:3)=[-i,-j,-1];jc=jc+2;endendj=0; end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 状态数 组生成kx=1; % 状态向量放在 A 矩阵中,生成方法同矩阵生成;for i=shangren:-1:0for j=puren:-1:0if ((i>=j)&((shangren-i)>=(puren-j)))|((i==0)|(i==shangren))% (i>=j)&((shangren-i)>=(puren-j)))|((i==0)|(i==shangren)) 为可以存在的状态的约束条件A(kx,1:3)=[i,j,1];%生成状态数组集合 D 'A(kx+1,1:3)=[i,j,0];kx=kx+2;endend 中, jc 为插入新元素的行标初始为 1; % 满足条 D={(u,v)|1<=u+v<=rongliang,u,v=0,1,2} %生成一个决策向量立刻扩充为三维; % 同时生成他的负向量; 由于生成两个决策向量,则 jc。

数学建模:研究商人过河问题

数学建模:研究商人过河问题

数学建模实验一报告实验题目:研究商人过河问题一、实验目的:编写一个程序(可以是C,C++或Mathlab )实现商人安全过河问题。

二、实验环境:Turbo c 2.0、Microsoft Visual C++ 6.0、Matlab 6.0以上 三、实验要求:要求该程序不仅能找出一组安全过河的可行方案,还可以得到所有的安全过河可行方案。

并且该程序具有一定的可扩展性,即不仅可以实现3个商人,3个随从的过河问题。

还应能实现 n 个商人,n 个随从的过河问题以及n 个不同对象且每个对象有m 个元素问题(说明:对于3个商人,3个随从问题分别对应于n=2,m=3)的过河问题。

从而给出课后习题5(n=4,m=1)的全部安全过河方案。

四、实验步骤:第一步:问题分析。

这是一个多步决策过程,涉及到每一次船上的人员以及要考虑此岸和彼岸上剩余的商人数和随从数,在安全的条件下(两岸的随从数不比商人多),经有限步使全体人员过河。

第二步:分析模型的构成。

记第k 次渡河前此岸的商人数为k x ,随从数为k y ,2,1=k ,n y x k k 2,1,=,(具有可扩展性),将)(k k y x ,定义为状态,状态集合成为允许状态集合(S )。

S={2,1;3,2,1,0,3;3,2,1,0,0|,======y x y x y x y x )(}记第k 次渡船的商人数为k u ,随从数为k v ,决策为),(k k v u ,安全渡河条件下,决策的集合为允许决策集合。

允许决策集合记作D ,所以D={2,1,0,,21|,=<+<v u v u v u )(|1<u+v<2,u,v=0,1,2},因为k 为奇数时船从此岸驶向彼岸,k 为偶数时船由彼岸驶向此岸,所以状态k s 随决策k d 变化的规律是k k k k d s s )1(1-+=-,此式为状态转移律。

制定安全渡河方案归结为如下的多步决策模型:求决策)2,1(n k D d k =∈,使状态S s k ∈按照转移律,由初始状态)3,3(1=s 经有限n 步到达)0,0(1=+n s第三步:模型求解。

商人过河的MATLAB程序

商人过河的MATLAB程序

商人过河的MATLAB程序n=4;m=4;h=2; %初始状态及数据m0=0;n0=0;ticLS=0; % 允许的状态集合S与个数LSLD=0; %允许的决策集合D与个数LDfor i=0:nfor j=0:mif i>=j&n-i>=m-j|i==n|i==0LS=LS+1;S(LS,:)=[i j];endif i+j>0&i+j<=h&(i>=j|i==0)LD=LD+1;D(LD,:)=[i j];endendend%用搜寻法找出符合条件的渡河方案N=18;Q1=inf*ones(2*N,2*N);Q2=inf*ones(2*N,2*N);t=1;le=1;q=[m n];f0=0; %判断循环终止标记while f0~=1&t<="" p="">k=1;sa=[];sb=[];for i0=1:le %第n次允许的策略集逐次搜索s0=q(i0,:);breakendfor i=1:LD %由s0搜索D后得到允许的状态s1=s0+(-1)^t*D(i,:); if s1==[m0,n0]sa=[m0,n0];sb=D(i,:);f0=1;breakendfor j=2:LS-1 %搜索对比S后允许状态if s1==S(j,:)if k==1sa(k,:)=s1;sb(k,:)=D(i,:);k=k+1;breakendif k>1 %对重复状态删除处理f1=0;for ii=1:k-1if s1==sa(ii,:)f1=1;breakendendend %……if f1==0sa(k,:)=s1;sb(k,:)=D(i,:);breakendendend %…………………end %………………………………end %……………………………………………q=sa; le=size(q,1);Q1(1:le,t*2-1:t*2)=q;Q2(1:le,t*2-1:t*2)=sb;t=t+1;endif length(q)==6tr=t-1;saa1=sa;SA=zeros(tr,2);SB=zeros(tr,2);for k=tr:-1:2k1=k-1;f0=0;sbb=Q2(:,k*2-1:k*2);saa=Q1(:,k1*2-1:k1*2);for i=1:2*Nsaa2=saa1-(-1)^k*sbb(i,:);for j=1:2*Nif saa2==saa(j,:)saa1=saa2;sbb1=sbb(i,:);f0=1;breakendendif f0==1endendSA(k1,:)=saa1;SB(k,:)=sbb1;endSA(tr,:)=[m0 n0];SB(1,:)=[m,n]-SA(1,:); %………………………………………………………………………………………………¥¥disp '初始状态:'X0=[m,n]disp '状态为:'SAdisp '决策为:'SBtocendif length(q)~=6disp '没有可行的方法过河'enddisp '可以走的状态为:';q。

n-m-k商人渡河问题解的存在性及算法实现

n-m-k商人渡河问题解的存在性及算法实现

n-m-k商人渡河问题解的存在性及算法实现付艳玲;刘高峰;张伟【摘要】We extend the businessmen-crossing-river problem into the most general case,i.e.the n-m-k businessmen-crossing-river problem,and establish the multi-step-decision mathematical model for this problem.Firstly,a state space tree corresponding to this mathematical model is created and an algorithm for traversing the state space tree by recursion and backtracking methods is designed.Secondly,the analysis of algorithm complexity is evaluated based on experimental results.Finally,the existence of solution for this problem is analyzed,and some theorems and proofs are introduced.The obtained results are potentially beneficial to some real life problems.%本文将商人渡河问题推广到最一般情况,即n-m-k商人渡河问题,建立了该问题的多步决策数学模型.首先,根据该数学模型得到一棵状态空间树,设计了采用递归和回溯方法遍历该状态空间树的算法步骤.其次,根据部分运行结果,分析了该问题的算法复杂度.最后,分析了该问题解的存在性,并给出了若干定理及其证明.本文已将商人渡河问题扩展成为广泛的经典例子,有利于解决实际生活中的问题.【期刊名称】《工程数学学报》【年(卷),期】2013(030)004【总页数】8页(P561-568)【关键词】商人渡河问题;算法实现;解的存在性【作者】付艳玲;刘高峰;张伟【作者单位】河南财政税务高等专科学校信息工程系,郑州451464;西安电子科技大学雷达信号处理国家重点实验室,西安710071;河南理工大学万方科技学院,郑州451400【正文语种】中文【中图分类】O2441 引言渡河问题[1,2]始于公元8世纪,至今它仍是一个逻辑难题.这个问题指的是:有不同的对象或生物,他们其中一些相互不共存,逐步地让一小群体从河的一岸到另一岸,经过有限步后,该群体全部从一岸达到另一岸,并且要求没有任何损失.渡河问题有不同的版本,如传教士和食人族难题,猜疑的丈夫问题,人狼羊菜问题,商人和随从渡河问题等,但是解决方法是类似的.商人和随从渡河问题通常指三名商人各带一个随从乘船渡河,一只小船只能容纳二人,由他们自己划行.随从们秘约:在河的任一岸,一旦随从的人数比商人多,就杀人越货.乘船渡河的大权掌握在商人们手中[3,4],商人们需要安排合理的渡河方案,以确保安全渡河.这类问题常作为数理逻辑、数学建模、图论以及算法设计的经典例子[5-8].到目前为止,n个商人n个随从船满载k人的渡河问题[1](以下简称n−n−k商人渡河问题)的程序实现虽已给出了,但n−n−k商人渡河问题解的存在性问题还不存在相关的结论.针对上面的情况,本文将渡河问题推广到最一般的情况,给出了n个商人m个随从船满载k人的渡河问题(以下简称n−m−k商人渡河问题)程序实现的方法,最后详细讨论了n−m−k商人渡河问题解的存在性问题并对相关结论进行了严格的证明.2 n−m−k商人渡河问题的数学模型本文考虑的商人渡河问题是最一般的情况,即n个商人与m个随从渡河,其中n≥m,渡河的小船至多可以容纳k人,并且n,m,k的取值互不影响.游戏的规则是在岸边一旦随从的人数比商人多,就杀人越货.针对这个问题,建立多步决策模型,其具体建模过程如下:本文把商人渡河问题视为一个多步决策过程,每一步(即船由此岸驶向彼岸或彼岸驶向此岸)都要对船上的人员作出决策(即决定船载几个商人与几个随从),在保证安全的前提下(即在两岸都不会发生杀人越货),经过有限步后使人员全部过河.用状态变量表示此岸的人员状况,决策变量表示船上的人员状况,可以找出状态随决策变化的规律,这样商人渡河问题就转化为在状态允许的变化范围内(即满足安全渡河的条件下)确定每一步的决策,达到安全渡河的目的.记第i次渡河前此岸的商人数为xi,随从数为yi,xi∈ {0,1,···,n},yi∈ {0,1,···,m}.将二维向量si=(xi,yi)定义为状态.将满足安全渡河条件下的状态集合称为允许状态集合,记为记第i次渡河时船上的商人数为ui,随从数为vi,将二维向量di=(ui,vi)定义为第i 次渡河决策.将所有允许决策(考虑到:小船有容量限制并且在船上商人数同样不得少于随从数)构成的集合称为允许决策集合,记为其中允许决策集合D的元素个数当i为奇数时,船从此岸驶向彼岸.当i为偶数时,船从彼岸驶向此岸,所以状态si随决策dj变化的规律是称这个规律为状态转移律.于是,确定安全渡河方案就归结为如下的多步决策问题:求每一步渡河的决策dj∈D,使得状态si∈S按照状态转移律由初始状态s1=(n,m),经有限步到达状态(0,0).至此,我们已经把n−m−k商人渡河问题用数学模型描述出来了.3 n−m−k商人渡河问题的算法求解3.1 算法思想n−m−k商人渡河问题的算法基本思想是:通过遍历状态空间树来搜索可行的渡河方案.在搜索过程中,用到了回溯法和剪枝法,针对渡河期间的某一步,当从允许决策集合S中选取所有决策方案都不能安全渡河时,说明这一步往下渡河是行不通的,那么这一步下面的状态空间树就不用搜索了(即剪枝),并且要求回溯到这一步的上一步,重新选择渡河决策.在搜索的过程中当此岸的商人和随从数一旦为0和0,表示已经找到了一个可行解,就输出这种渡河方案,然后继续搜索状态空间树的剩余部分,直至状态空间树被搜索完为止.这种算法思想可以求解出所有的渡河方案.n−m−k商人渡河问题状态空间树的每一个支点的分支数目与k有直接的联系,因为直接决定每一步渡河时的决策,即决定允许决策集合D,例如k=2时,可选的渡河决策就有5个,它们分别为(1,1),(2,0),(0,2),(1,0),(0,1).这样状态空间树就形如图1样子.因为渡河中的每一个状态往下有5种决策进行选择,所以状态空间树的每一支点有5个分支.图1 :状态空间树其次n−m−k商人渡河问题的关键问题是在当前此岸状态下怎样合理地选择允许决策集合D中的决策.设此岸的当前状态为si=(xi,yi),决策dj=(uj,vj)∈D,下一步此岸的状态si+1=si+(−1)idj.合理地选择允许决策集合D中的决策应满足的条件是:1) 满足渡河的规则:对此岸而言要求要么xi+1=0,要么xi+1̸=0,并且xi+1≥yi+1.对彼岸而言,要么n−xi+1=0,要么n−xi+1̸=0,并且n−xi+1≥m−yi+1;2) 不可重复性:如果当前是第i次渡河,那么下一步的状态si+1不能与前面的同奇偶次渡河后的状态相同.比如,前面第3次渡河后此岸状态为(1,1),后面第9次渡河后的此岸状态仍为(1,1),这就出现了重复,也就是说第9次渡河时选择的渡河决策是错误的,因为它出现了重复.不可重复性用来避免程序进行递归调用时出现无穷递归,或者说在遍历状态空间树时,避免了状态空间树的层数出现无穷大.3.2 算法描述n−m−k商人渡河问题的算法描述如下(采用了递归算法):算法的主体是:递归调用渡河子函数f(si,i,V),其中参数si表示当前准备渡河时此岸的商人与随从数,参数i表示当前状态是第几步状态,V表示从最开始到目前为止渡河过程中此岸所经历状态的集合.1) 初始化数据.设定商人数n,随从数m,船满载量k,允许决策集合D,允许状态集S,状态变量i=0,此岸初始状态si=(n,m),彼岸状态sp=(0,0),V={s0};2) 调用渡河子函数f(si,i,V).渡河子函数f(si,i,V)的执行步骤如下:设当前还没有渡河时的此岸人数为si,当前是第i步状态设j=1;(a) 若j>|D|,则结束当前的渡河子函数f(si,i,V)运行;若j≤|D|,则从允许决策集合D中选择允许决策向量dj;(b) 利用状态转移律计算si+1=si+(−1)idj;(c) 判断si+1和(n,m)−si+1是否在允许状态集S中,si+1是否与前面的状态不重复.如果都满足条件,则执行(d);如果存在一个条件不成立,则j=j+1,转到(a);(d) 将si+1添加到记录V中的第i+1位置,判断si+1=sp是否成立,如果成立,则说明找到了一种渡河方案,输出渡河方案(记录V中从1到i+1的元素);若不成立,则递归调用渡河子函数f(si+1,i+1,V);3) 第2)步结束以后,若有输出,则说明渡河问题有解,并且输出的解是渡河问题的所有可行解;若没有输出,则说明渡河问题无解.3.3 n−m−k商人渡河问题的算法复杂度分析n−m−k商人渡河问题的算法建立在状态空间树图1上.该算法的复杂度取决于算法在状态空间树上搜索时所遍历的树枝个数.算法在当前节点往下层搜索的树枝个数取决于当前的此岸与彼岸状态以及船满载人数.另外为了不让算法的状态出现重复情况,往下层搜索的树枝个数同样取决于以往所有出现的状态,所以该算法所搜索的状态空间树的树枝个数很难用一个解析式来表达,但我们可以分析出本文的n−m−k商人渡河问题是一个NP难问题.因为船满载人数k决定状态空间树节点的分支数目,公式为随着k的增加,状态空间树每个节点的分支数目为以k2数量级增加,另外随着n,m或k的增加,状态空间树的层数也会增加,于是算法所遍历的状态空间树枝个数会以指数复杂度形式增加.为了方便显示遍历树枝个数增长的情况,图2至图4的纵坐标采用了自然对数ln(·).在图2中,横坐标表示商人数(其中商人数=随从数,船满载人数固定为4人),纵坐标表示遍历树枝个数的自然对数,图2的曲线接近于一条斜率较小的直线,又因为纵坐标采取了自然对数的运算,这说明遍历树枝个数随着商人数(其中商人数=随从数,船满载人数固定为4人)的增加是成指数形式增加的.在图3中,横坐标表示商人数(其中商人数=随从数=船满载人数),纵坐标表示遍历树枝个数的自然对数,同样说明了遍历树枝个数随着商人数(其中商人数=随从数=船满载人数)的增加是成指数形式增加的.又因为图3的斜率略大于图2的斜率,所以在图3中遍历树枝个数随着商人数的增加而增长地更加剧烈.图2 : 当船满载人数为4时,遍历的树枝个数与商人数的关系(商人数=随从数)图3 : 人数与遍历树枝个数的关系(其中人数=商人数=随从数=船满载人数)图4 :船满载人数与遍历树枝个数的关系,其中商人数=随从数=4另外,当商人数n与随从数m都固定时,随着船满载人数k的增加,遍历的树枝个数也成指数增长.但当k>n+m后,随着船满载人数的增加,遍历树枝个数不会增长,这是因为此时船每次过河的决策方案与k=n+m时的决策方案相同,不会再随k的增加而变化,状态空间树每一个节点的分枝数目不再变化了.图4验证了上面的分析.当商人数与随从数固定时,即商人数=随从数=4,船满载人数从2到4这一段,遍历树枝个数的自然对数图形为一斜直线,说明在这一段,遍历树枝个数随船满载人数成指数增长.另外,后一段图形基本是一条水平直线,说明当船满载人数≥5时,遍历树枝个数的变化不大,并且定量结果显示:当k=8与9时,遍历的树枝个数是相同的,不再随着k的增加而变化.4 n−m−k商人渡河问题解的存在性根据3.3节的算法复杂度分析,得到n−m−k商人渡河问题在某些情况下解存在性的结论:1) 若k=2,n=m=1,2,3,n−m−k商人渡河问题有解;2) 若k=3,n=m=1,2,3,4,5,n−m−k商人渡河问题有解;3) 若k=2,n=m≥4,n−m−k商人渡河问题无解;4) 若k=3,n=m≥6,n−m−k商人渡河问题无解.下面给出除了上面情况之外的n−m−k商人渡河问题解的存在性定理及其证明.定理1 对任意的k≥2以及任意的n>m,n−m−k商人渡河问题有解.证明首先采用数学归纳法证明:开始时刻此岸为(n,m),彼岸为(0,0),船在此岸,经过有限步渡河后,总可以变成此岸为(n−m,0),彼岸为(m,m),船在此岸.1) 下面推导(n,m)和(0,0)变成(n−1,m−1)和(1,1),如表1.表1 :初时刻状态转移过程状态序号此岸状态彼岸状态商人数随从数商人数随从数1 n m 0 02 n−1 m−1 1 13 n−1 m 1 04 n−2 m−1 2 15 n−1 m−1 1 12) 假设满足定理条件的n−m−k商人渡河问题存在着状态(n−i,m−i)和(i,i),并且船在此岸,下面证明在此状态的基础上可以推导出状态(n−i−1,m−i−1)和(i+1,i+1),船在此岸,如表2.表2 :i时刻状态转移过程状态序号此岸状态彼岸状态商人数随从数商人数随从数x1 n−i m−i i i x2 n−i−1 m−i−1 i+1 i+1 x3 n−i−1 m−i i+1 i x4 n−i−2 m−i−1 i+2 i+1 x5 n−i−1 m−i−1 i+1 i+1综合以上1)和2),并且n>m,由数学归纳法得到开始时刻此岸为(n,m),彼岸为(0,0),船在此岸,经过有限步渡河后,总可以变成此岸为(n−m,0),彼岸为(m,m),船在此岸.设开始状态为:此岸状态为(n−m,0),彼岸状态为(m,m)以及船停在此岸;结束状态为:此岸状态为(0,0),彼岸状态为(n,m),船停在彼岸.下面给出如何从开始状态推导到结束状态.当n−m=1或2时,船直接将余下的商人载过河即可;若n−m>2,只需要重复过程:每次从此岸到彼岸时,船载2个商人.回来时,即从彼岸到此岸,船载1个商人.经过有限步总可以将余下的商人安全渡过河.证毕定理2 对任意的k≥4以及任意的n,m(n≥m),n−m−k商人渡河问题有解.证明假设商人数n大于随从数m,根据定理1,商人渡河问题有解.因此,只需考虑商人数n等于随从数m的情形.当k≥4且n=m时,要求船从此岸到彼岸始终载2个商人和2个随从过河,船从彼岸到此岸始终载1个商人和1个随从过河.交替重复以上过程,这样在任意时刻,两岸始终满足游戏规则,即商人数不会少于随从数,并且一个来回以后,此岸的人数在减少,彼岸人数在增加.当n和m是奇数时,则最后一步从此岸到彼岸,船载1个商人和1个随从过河,就可以载完所有的人;当n和m是偶数时,则最后一步从此岸到彼岸,船载2个商人和2个随从,就可以载完所有的人.证毕参考文献:[1]储理才.用Mathematica求解商人渡河问题[J].大学数学,2005,21(3):117-122 Chu L ing Mathematica to solve the businessmen-crossing-river problem[J].College Mathematics,2005,21(3):117-122[2]Ascher M.A river-crossing problem in cross-culturalperspective[J].Mathematics Magazine,1990,63(1):26-29[3]李天瑞.安全渡河问题的计算机求解和模拟[J].工科数学,1999,15(1):119-123 Li T R.Safe crossing river problem solving by computer andsimulation[J].Journal of Mathematics for Technology,1999,15(1):119-123 [4]王家华,王湘波.安全渡河问题的图解新法[J].西安石油大学学报(自然科学版),2007,22(4):103-105 Wang J H,Wang X B.A new graphic method for safe crossing river problem[J].Journal of Xi’an Shiyou Unive rsity(Natural Science Edition),2007,22(4):103-105[5]Lampis M,Mitsou V.Generalizing Alcuin’s river crossingproblem[C]//11th Panhellenic Conference in Informatics,2007:617-626 [6]Garey M R,Johnson D puters and Intractability:a Guide to the Theory of NP-completeness[M].New York:Freeman Company Press,1979 [7]Wells D G.The Penguin Book of Curious and InterestingPuzzles[M].London:Penguin Books,1992[8]Kraitchik M.Mathematical Recreations[M].New York:DoverPublications,1953。

商人过河数学模型

商人过河数学模型

商人过河数学模型专业信息与计算科学班级113010102姓名罗彪学号11301010229一、问题重述3名商人各带一名随从乘船渡河,一只小船只能容纳二人,由他们自己划行。

随从们密约,在河的任一岸,一旦随从的人数比商人多,就杀人越货。

但是如何乘船渡河的大权掌握在商人们手中。

商人们怎样才能安全过河呢?二、问题分析商随过河问题可以视为一个多步决策过程,通过多次优化,最后获取一个全局最优的决策方案。

对于每一步,即船由此岸驶向彼岸或由彼岸驶向此岸,都要对船上的人员作出决策,在保证两岸的商人数不少于随从数的前提下,在有限步内使全部人员过河。

用状态变量表示某一岸的人员状况,决策变量表示船上的人员状况,可以找出状态随决策变化的规律,问题转化为在状态的允许变化范围内(即安全渡河条件),确定每一步的决策,达到安全渡河的目标。

三、模型假设1.每个商人和随从都会划船;2.只有一条船,且每条船上最多只能乘坐两个人;3.所有商人与随从之间没有矛盾,不会出现两人不愿意坐一条船的现象;4.船在渡河的过程中不受外界环境的影响。

四、模型的建立与求解 1.模型建立k x ~第k 次渡河前此岸的商人数,k y ~第k 次渡河前此岸的随从数k x , k y =0,1,2,3; k =1,2,… …k S =(k x , k y , c k )~过程的状态,其中k x , k y , c k 分别表示对应时刻此岸的商人,仆人数以及船的行进方向,其中c 取值1表示即将向彼岸运行,为0表示即将向此岸运行S ~ 允许状态集合,S={(x , y )| x =0, y =0,1,2,3; x =3 ,y =0,1,2,3; x =y =1,2}k u ~第k 次渡船上的商人数 k v ~第k 次渡船上的随从数k d =(k u , k v )~决策,D={(u , v )| 21≤+≤v u ,k u , k v =0,1,2} ~允许决策集合k =1,2,… …因为k 为奇数时船从此岸驶向彼岸,k 为偶数时船从彼岸驶向此岸,所以状态k S 随决策k d 的变化规律是1+k S =k S +k )1(-k d ~状态转移律求k d ∈D(k =1,2, …n), 使k S ∈S, 并按转移律由1S =(3,3,1)到达状态1+n S =(0,0,0(1))。

商人过河问题

商人过河问题

商人过河问题摘要:为了求解3个商人和3个随从的过河问题,用数学分析方法,建立数学模型,并且加以求解,展示动态规划思想的应用步骤。

最后利用计算机编程进行求解,获得过河问题的完整求解过程;有效地求解类似多步决策问题的作用。

关键词:多步决策计算机求解状态转移律图解法 MATLAB程序一.问题提出S个商人各带一个随从乘船过河,一只小船只能容纳K人,由他们自己划船。

商人们窃听到随从们密谋,在河的任意一岸上,只要随从的人数比商人多,就杀掉商人。

但是如何乘船渡河的决策权在商人手中,商人们如何安排渡河计划确保自身安全?二.问题的关键解决的关键集中在商人和随从的数量上,以及小船的容量上,该问题就是考虑过河步骤的安排和数量上。

各个步骤对应的状态及决策的表示法也是关键。

三.问题的分析在安全的前提下(两岸的随从数不比商人多),经有限步使全体人员过河。

由于船上人数限制,这需要多步决策过程,必须考虑每一步船上的人员。

动态规划法正是求解多步决策的有效方法。

它要求把解的问题一层一层地分解成一级一级、规模逐步缩小的子问题。

直到可以直接求出其解的子问题为止。

分解成所有子问题按层次关系构成一棵子问题树.树根是原问题。

原问题的解依赖于子问题树中所有子问题的解。

四.模型假设记第k次过河前A岸的商人数为XK,随从数为YK k=1,2,⋯ XK ,YK=0,1,2,3,将二维向量SK=(XK,YK)定义为状态.把满足安全渡河条件下的状态集合称作为允许状态集合。

记作S。

则 S={(XK ,YK)|(XK =0,YK =0,1,2,3),(XK =3,YK =0,1,2,3),(XK =YK =1)(XK =YK =2)}记第k次过河船上的商人数为UK,随从数为VK将二维向量DK=(UK ,VK)定义为决策。

由小船的容量可知允许决策集合(记作D)为D={(UK ,VK)|UK +VK=l,2}={(O,1);(O,2);(1,O);(1,1);(2,O)}五.模型建立:动态规划法正是求解多步决策的有效方法。

商人过河问题程序

商人过河问题程序
return;
end;
function jueche=guohe
%%%%%%%%%%%%%%%%%%%%%%
程序开始需要知道商人和仆人数;
n=input(‘输入商人数目:’,’12’);
nn=input(‘输入仆人数目:’,’12’);
nnn=input(‘输入船的最大容量:’,’20’);
if nn>n
return 0;
pointer=pointer-> next;
}
return 1;
}
}
int judge(int a,int b,int c,int d,int n) /*判断这个状态是否可行,其中使用了history函数*/
{
if(history(a,b,n)==0) return 0;
if(a> =0&&b> =0&&a <=3&&b <=3&&c> =0&&d> =0&&c <=3&&d <=3&&a+c==3&&b+d==3)
c=A(i,:)+d(j,:) ;
x=find((A(:,1)==c(1))&(A(:,2)==c(2))&(A(:,3)==c(3))) ;
v(i,x)=1; %x为空不会改变v值
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% dijstra算法
{
int x;
int y;

商人随从过河

商人随从过河

数学建模作业题目:商人随从过河队员:姓名:***姓名:***姓名:王*2011年08月25日商人过河问题摘要本文针对商人渡河的问题,建立分步决策模型,采用Dijkstra算法解决了商人和随从渡河问题。

根据题意用三维向量表示商人、随从和船的状态,并且定义此岸允许状态集合、彼岸允许状态集合及决策变量集合。

然后把此岸允许状态集合和彼岸允许状态集合中的每个元素视为节点,按照状态转移规律连接这些节点构成了一个连通图,寻找安全的渡河方案最终转化为从起始状态(节点)到最终状态(节点)的路径,用图论的Dijkstra算法找出所有路径,每一条路径对应一种渡河方案,整体方案如图1(实心点代表此岸,空心点代表彼岸,人数均为此岸人数),由图可知共有四种渡河方案。

图1 整体渡河方案关键词:分步决策 Dijkstra算法三维向量连通图1 问题重述三名商人各带一名随从过河,随从们密约, 在河的任一岸, 一旦随从的人数比商人多, 就杀人越货.但是乘船渡河的方案由商人决定.商人们怎样才能安全过河?(如果推广到四名商人四个随从又如何?)2 模型假设(1)商人和仆人都会划船,并且仆人听从商人的调度 (2)商人和仆人每次渡船都能安全到达(3)船的质量很好,在多次满载情况也能正常运作3 符号说明(1) k s 第k 次渡河前此岸商人和仆人的数量称为状态向量;(2) ks '第k 次渡河前彼岸商人和仆人的数量称为状态向量; (3) S 所有安全渡河条件下状态向量的集合; (4) S '所有安全渡河条件下状态向量的集合; (5) k d 第k 次渡河船上商人和仆人的数称为决策向量; (6) D 所有安全渡河条件下决策向量的集合; (7) k x 第k 次渡河前此岸的商人数;(8) kx ' 第k 次渡河前彼岸的商人数; (9) k y 第k 次渡河前此岸的仆人数;(10) ky ' 第k 次渡河前此岸的仆人数; (11) k u 第k 次渡船上的商人数; (12) k v 第k 次渡船上的仆人数。

商人过河问题matlab程序只是分享

商人过河问题matlab程序只是分享

商人过河functionjueche=guohe%程序开始需要知道商人和仆人数;n=input('输入商人数目:');nn=input('输入仆人数目:');nnn=input('输入船的最大容量:');ifnn>nn=input(''输入商人数目:');nn=input('输入仆人数目:');nnn=input('输入船的最大容量:');end%决策生成jc=1;%决策向量放在矩阵d中,jc为插入新元素的行标初始为1;for i=0:nnnfor j=0:nnnif(i+j<=nnn)&(i+j>0)%满足条D={(u,v)|1<=u+v<=nnn,u,v=0,1,2}d(jc,1:3)=[i,j,1];%生成一个决策向量立刻扩充为三维;d(jc+1,1:3)=[-i,-j,-1];%同时生成他的负向量;jc=jc+2;%由于生成两个决策向量,则jc要向下移动两个;end endj=0;end%状态数组生成kx=1;%状态向量放在A矩阵中,生成方法同矩阵生成;for i=n:-1:0for j=nn:-1:0if((i>=j)&((n-i)>=(nn-j)))|((i==0)|(i==n))%(i>=j)&((n-i)>=(nn-j)))|((i==0)|(i==n))为可以存在状态的约束条件A(kx,1:3)=[i,j,1];%生成状态数组集合D`A(kx+1,1:3)=[i,j,0];kx=kx+2;endendj=nn;end; %将状态向量生成抽象矩阵k=(1/2)*size(A,1);CX=zeros(2*k,2*k);a=size(d,1);for i=1:2*kfor j=1:ac=A(i,:)+d(j,:);x=find((A(:,1)==c(1))&(A(:,2)==c(2))&(A(:,3)==c(3)));v(i,x)=1;%x为空不会改变v值endend%dijstra算法x=1;y=size(A,1);m=size(v,1);T=zeros(m,1);T=T.^-1;lmd=T;P=T;S=zeros(m,1);S(x)=1;P(x)=0;lmd(x)=0;k=x;while(1)a=find(S==0);aa=find(S==1);if size(aa,1)==mbreak;endfor j=1:size(a,1)pp=a(j,1);if v(k,pp)~=0if T(pp)>(P(k)+v(k,pp))T(pp)=(P(k)+v(k,pp));lmd(pp)=k;endendendmi=min(T(a));if mi==infbreak;elsed=find(T==mi);d=d(1);P(d)=mi;T(d)=inf;k=d;S(d)=1;endendif lmd(y)==infjueche='cannotreach'; return;endjueche(1)=y;g=2;h=y;while(1)if h==xbreak;endjueche(g)=lmd(h);g=g+1;h=lmd(h);endjueche=A(jueche,:); jueche(:,3)=[];。

商人过河matlab程序以及解析

商人过河matlab程序以及解析

商人过河m a t l a b程序以及解析The latest revision on November 22, 2020数学建模作业班级:数学131姓名:丁延辉学号:(二)商人过河Matlab代码三个商人三个随从z=zeros(30,3);%z为由(a,b,c)的列向量组成的3行30列数组,初始化为0矩阵,a,b,c代表此刻此岸的商人,仆人数量以及船的运行状态,c=1表示即将向彼岸运行m=zeros(1,20);%m为一维行向量,初始化为1矩阵,用于在后面的程序中判断第k次选择的乘船方案d=[0,1,1;0,2,1;1,0,1;1,1,1;2,0,1];%共有5种可以选择的乘船方案,最后面一列全为1,即用于在后面表示使得z(k,3)的取值保持随着k的奇偶性保持着0-1变换.z(1,:)=[3,3,1];%初始状态为[3,3,1]k=1;m(k)=1;%第一次默认的乘船方案为决策1——d(1)flag=1;%用于在后面判断是否成功找到方案answer=0;%用于在后面判断是否找到答案whilek>0%保持k>0ifm(k)>5flag=0;break;endp=0;z(k+1,:)=z(k,:)+(-1)^k*d(m(k),:);%每一次的运算规则都是z(k+1)=z(k)-(-1)^k*d(m(k),:),d(m(k),:)表示决策方案a=z(k+1,1);%将当前情况的矩阵数值复制给a商人,b仆人b=z(k+1,2);c=z(k+1,3);if(a==3&&(b==0||b==1||b==2||b==3))||(a==1&&b==1)||(a==2&&b= =2)||(a==0&&(b==0||b==1||b==2||b==3))%判断(a,b)是否符合限定情况forj=1:k%判断是否此岸a,b,c与之前有重复,如果是,结束此次循环,重新选择乘船方案ifa==z(j,1)&&b==z(j,2)&&c==z(j,3)ifm(k)~=5%决策方案只有5种,所以m(k)<=5,m(k)=m(k)+1;%因为有重复,所以换下一种决策方案elsewhile(m(k)==5)&&(k>1)k=k-1;%回溯,这一步骤已经把所有决策取尽,无可用解法,于是将后退一步,同时换下一种决策方案end%while循环的目的是防止前面几步的决策都是5,导致k=k-1,m(k)=m(k)+1后数组越界,一直找到前面不是m(k)=5的步骤m(k)=m(k)+1;endp=1;break;elsep=0;endendifp==1%程序在跳出内层for循环之后,因为要换成决策方案,所以同时跳出,直接进入下一次while循环,continue;endifa==0&&b==0%判断是否达到目标情况answer=1;fprintf('Successfullyfound!\n每一次的此岸人员分布:商人仆人\n')fori=1:100fprintf('第%2d次%d%d\n',i,z(i,1),z(i,2))ifz(i,1)==0&&z(i,2)==0break;endend%如果不是,进入下一步骤,计算z(k+2)ifm(k)~=5m(k)=m(k)+1;%这是正常的进入下一次,所以仍从d1乘船决策1开始elsewhile(m(k)==5)&&(k>1)k=k-1;end;m(k)=m(k)+1;endcontinue;elsek=k+1;%如果不是,进入下一步骤,计算z(k+2)m(k)=1;%这是正常的进入下一次,所以仍从d1乘船决策1开始continue;endelseifm(k)~=5m(k)=m(k)+1;%如果没有符合限定情况,结束该次循环,改变上一次的乘船方案elsewhile(m(k)==5)&&(k>1)k=k-1;endm(k)=m(k)+1;%回溯,这一步骤已经把所有决策取尽,无可用解法,于是将后退一步,同时换下一种决策方案continue;endendendifanswer==0&&flag==0fprintf('NoAnswer!\n')end。

商人带工人过河matlab程序

商人带工人过河matlab程序

商人带工人过河matlab程序function boat(m,k)%输入变量m表示商人或工人数,k表示小船的最大容量.%%本程序编程思路是用单元型变量B和C分别表示允许状态集合S和决策d.%将S中的每一个元素用所有决策d按照状态转移律迭代.%对于每一步中每一个元素的迭代结果,剔除掉不符合事实的情况.%当某一个迭代结果是[0,0]时,说明当商人或工人个数是m个,小船的最大容量是k时可以在有限的步骤下安全过河.%当所有迭代结果都被剔除时,说明当商人或工人个数是m个,小船的最大容量是k个时不可以在有限的步骤下安全过河.%%本程序的优点是可以计算出小船最大容量超过2时的情况.%%下面三个for语句是根据参数m算出所有允许状态集合S中的元素,用B表示.for i=1:m+1A=[m,i-1];B{i}=A;endfor i=m+2:2*mA=[i-(m+1),i-(m+1)];B{i}=A;endfor i=2*m+1:3*m+1A=[0,i-(2*m+1)];B{i}=A;end%下面的for语句是根据参数k算出所有决策d,用C表示. t=1;for u=0:1:kfor v=0:1:kif u+v>=1&u+v<=kC{t}=[u,v];t=t+1;endendendD{1,1}=[m,m];% D{1,1}表示初始状态.w=1;% w控制是否能够迭代成功.h=1;% h控制元素的个数.j=2;% j表示迭代的次数.x=0;% x是用来剔除掉不在允许状态集合中的元素.y=0;% y是防止重复剔除同一个元素.l=0;% l使用来标记元素是否被剔除.z(1)=0;z(2)=1;% z(j)表示上一步迭代后所剩下的所有元素.while w>0% p表示可以进行下一步迭代的所有元素.for p=z(j-1)+1:z(j)% q表示每一个元素要经过k*(k+3)/2种决策迭代.for q=1:k*(k+3)/2D{h+1,j}=D{p,j-1}+(-1)^(j-1).*C{q};h=h+1;l=1;%下面的for语句是核查迭代结果是否在允许状态集合B 中.for e=1:3*m+1if D{h,j}==B{e}x=1;break;endendif x==0h=h-1;y=1;l=0;end%下面的if语句是剔除掉本次迭代过程中出现的重复元素.if j>2&y==0for i=z(j)+1:h-1if D{h,j}==D{i,j};h=h-1;l=0;break;endendend%下面的if语句是剔除掉以前重复的元素.if j>2&y==0if j==3for i=z(1)+1:z(2)if D{h,j}==D{i,j-2} h=h-1;l=0;break;endendelsefor i=z(j-2)+1:z(j-1)if D{h,j}==D{i,j-2} h=h-1;l=0;break;endendendendif l==1for g=1:j-1D{h,g}=D{p,g};endendif l==1&D{h,j}==[0,0]w=-1;%w=-1表示商人和工人可以在有限的步骤下安全过河.break;endx=0;y=0;l=0;endif w==-1;%w=-1表示商人和工人可以在有限的步骤下安全过河.break;endendj=j+1;z(j)=h;if z(j)==z(j-1)w=-2;%w=-2表示商人和工人不可以在有限的步骤下安全过河.break;endendif w==-1disp('商人和工人可以在有限的步骤下安全过河') disp('步骤如下:')for g=1:j-1D{h,g}endendif w==-2disp('商人和工人不可以在有限的步骤下安全过河') end。

商人过河的数学模型及编程解决

商人过河的数学模型及编程解决

摘要:M对商仆过河,一只船最多载N人,船上和岸上的仆人数都不能多于商人数,否则商人有危险。

安排合理的渡河方案,保证商人能安全渡河。

(可利用向量,矩阵,图解等方法)一.问题提出:有M对商仆乘船过河,一只船最多载N人,由商人和仆人自己划船渡河,在河的任意一岸,一旦仆人数多于商人数,仆人就可将商人杀死,谋取利益,但是乘船渡河的主动权掌握在商人们手中,商人们如何安排渡河方案,才能安全渡河?二.假设:商人和仆人都会划船,天气很好,无大风大浪,船的质量很好,船桨足够很多次的运载商人和仆人。

三.参数:1.设(x,y)是状态向量,表示任一岸的商人和仆人数,并且x,y分别要大于等于0,小于等于M。

2.设(m,n)是运载向量,表示运载的商人数和仆人数,0<=m<=N,0<=n<=N,0<=m+n<=N。

3.设用s表示所有的可取状态向量的集合。

4.设用d表示所有运载向量的集合。

5.设用表示从此岸到彼岸,作减;用表示从彼岸到此岸,作加。

Sk:表示第k步可取状态向量(sk属于s);dk:表示第k步可取转移向量(dk属于d);四.问题分析:商仆安全渡河问题可以视为一个多步决策过程,多步决策是指决策过程难以一次完成,而是多步优化,最后获取一个全局最优方案的决策方法。

对于每一步,即船由此岸驶向彼岸,或者船由彼岸驶向此岸的决策,不仅会影响到该过程的效果,而且还会影响到下一步的初始状态,从而对整个过程都会有影响。

所以,在每一次过河时,就不能只从这一次过河本身考虑,还要把它看成是整个过河过程中的一个部分。

在对船上的人员做决策时,要保证两岸的商人数不能少于仆人数,用最少的步伐是人员全部过河。

应用状态向量和运载向量,找出状态随运载变化的规律,此问题就转化为状态在允许范围内(即安全渡河条件),确定每一次该如何过河,从而达到渡河的目标。

现在我们都把它们数量化:即用数学语言来表示。

我们以3名商人为例设第k次渡河前此岸的商人数为x k,随从数为y k,k=1,2,…,x k,y k =0,1,2,3,将二维向量S k =(x k,y k)定义为状态。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

数学建模作业
班级:数学131
姓名:丁延辉
学号:13190122
(二)商人过河Matlab代码
三个商人三个随从
z=zeros(30,3); %z为由(a,b,c)的列向量组成的3行30列数组,初始化为0矩阵,a,b,c代表此刻此岸的商人,仆人数量以及船的运行状态,c=1表示即将向彼岸运行
m=zeros(1,20); %m为一维行向量,初始化为1矩阵,用于在后面的程序中判断第k次选择的乘船方案
d=[0,1,1;0,2,1;1,0,1;1,1,1;2,0,1]; %共有5种可以选择的乘船方案,最后面一列全为1,即用于在后面表示使得z(k,3)的取值保持随着k的奇偶性保持着0-1变换.
z(1,:)=[3,3,1]; %初始状态为[3,3,1]
k=1;
m(k)=1; %第一次默认的乘船方案为决策1——d(1)
flag=1; %用于在后面判断是否成功找到方案
answer=0; %用于在后面判断是否找到
答案
while k>0 %保持k>0
if m(k)>5
flag=0;
break;
end
p=0;
z(k+1,:)=z(k,:)+(-1)^k*d(m(k),:); %每一次的运算规则都是z(k+1)=z(k)-(-1)^k*d(m(k),:),d(m(k),:)表示决策方案
a=z(k+1,1); %将当前情况的矩阵数值复制给a商人,b仆人
b=z(k+1,2);
c=z(k+1,3);
if
(a==3&&(b==0||b==1||b==2||b==3))||(a==1&&b==1)||(a==2&&b==2 )||(a==0&&(b==0||b==1||b==2||b==3)) %判断(a,b)是否符合限定情况
for j=1:k %判断是否此岸a,b,c与之前有重复,如果是,结束此次循环,重新选择乘船方案
if a==z(j,1)&&b==z(j,2)&&c==z(j,3)
if m(k)~=5 %决策方案只有5种,所以m(k)<=5,
m(k)=m(k)+1; %因为有重复,所以换下一种决策方案
else
while (m(k)==5)&&(k>1)
k=k-1; %回溯,这一步骤已经把所有决策取尽,无可用解法,于是将后退一步,同时换下一种决策方案
end %while循环的目的是防止前面几步的决策都是5,导致k=k-1,m(k)=m(k)+1后数组越界,一直找到前面不是m(k)=5的步骤
m(k)=m(k)+1;
end
p=1;
break;
else
p=0;
end
end
if p==1 %程序在跳出内层for循环之后,因为要换成决策方案,所以同时跳出,直接进入下一次while循环,
continue;
end
if a==0&&b==0 %判断是否达到目标情况
answer=1;
fprintf('Successfully found!\n每一次的此岸人员分布:商人仆人\n')
for i=1:100
fprintf(' 第%2d次 %d %d
\n',i,z(i,1),z(i,2))
if z(i,1)==0&&z(i,2)==0
break;
end
end %如果不是,进入下一步骤,计算z(k+2) if m(k)~=5
m(k)=m(k)+1; %这是正常的进入下一次,所以仍从d1乘船决策1开始
else
while (m(k)==5)&&(k>1)
k=k-1;
end;
m(k)=m(k)+1;
end
continue;
else
k=k+1; %如果不是,进入下一步骤,计算z(k+2) m(k)=1; %这是正常的进入下一次,所以仍从d1乘船决策1开始
continue;
end
else
if m(k)~=5
m(k)=m(k)+1; %如果没有符合限定情况,结束该次循环,改变上一次的乘船方案
else
while (m(k)==5)&&(k>1)
k=k-1;
end
m(k)=m(k)+1; %回溯,这一步骤已经把所有决策取尽,无可用解法,于是将后退一步,同时换下一种决策方案
continue;
end
end
end
if answer==0&&flag==0
fprintf(' No Answer!\n')
end。

相关文档
最新文档