关于商人过河问题的分析

关于商人过河问题的分析
关于商人过河问题的分析

关于商人过河问题的分析

我的整个国庆假期就在紧张的课业学习与照顾家庭生活中结束了(呵呵别误会,我工作已久,只是今年又读了个在职研究生)。

在假期尾声抽出一点时间完成之前我在https://www.360docs.net/doc/d412656926.html,/thread-436739-1-1.html中对朋友的承诺,写一篇关于原贴中问题的分析。同时也算为我计划写的书积累点文字经验。表达能力有限,不到之处欢迎大家批评指正。

问题描述:

3个商人带着3个仆人过河,过河的工具只有一艘小船,只能同时载两个人过河,包括划船的人。在河的任何一边,只要仆人的数量超过商人的数量,仆人就会联合起来将商人杀死并抢夺其财物,问商人应如何设计过河顺序才能让所有人都安全地过到河的另一边。

问题分析:

构建解题模型的第一步是分析问题包含的属性。

1 有3个商人和3个仆人。从问题的描述可以认为这里商人与商人之前没有区别,仆人与仆人之前没有区别。

2 有一条河。相应的它将地理空间分隔成三部分。左岸、右岸(只是为了区分河的两侧,怎么叫没关系,也可以叫南岸、北岸,东岸、西岸,或者本岸、对岸等等)和河上。

3 有一只船。它的属性是这个问题的核心,需要详细讨论。

3.1 船无主动动力,移动需要有人在船上控制。但由谁划船并没有限制,问题的一个隐含条件是这3个商人和3个仆人谁都会划船。

3.2 船最多可载两人,包括划船的在内。但由于上一条属性,空船不能往来于两岸之间,所以要使其移动至少要载一人。

3.3 船的位置有三种停靠在左岸、停靠在右岸、载人行驶在河中。这里“行驶在河中”是一个动态属性,其它之前分析的全都是静态属性。这个动态属性的发生受其它静态属性的制约也改变其它静态属性。下面就船的这条动态属性细讨论一下。

3.3.1 船的移动只能从它之前停靠的岸边移动到对岸。

3.3.2 船可以载一个人(可以是商人或者仆人)移动到对岸。进行这个动作的前提条件是本侧至少有一个人,并且这个人离开后本侧岸边的商人数量不少于仆人数量或者干脆没有商人(否则会发生血案)。

基于以上的属性分析我们来选择解题模型。我想大部分人分析到这里想到的可用模型是图。有没有更合适的方案?我不确定,也许有。如果有人想出了更好的算法欢迎分享。

以上面讨论到的所有静态属性构成状态结点,以小船移动这个动态属性作为边连接动作前后两种状态的结点,可以构成一个无向图。而原问题要求的解就变成了在这个图中寻找一条连接初始结点(三商三仆在河左岸,船停靠在左岸)到目的结点(三商三仆在河右岸,船停靠在右岸)的路径。我们可以应用图论的相关算法来完成这件事,这也是选择图模型的主要原因。虽然问题并没有要求找最短的路径,但事实上只要是无环的路径就是最短的(无环的路径只有两条,一条是先一商一仆过河然后商人回来,另一条是两个仆人过河然后一个回来,之后的过程殊途同归)。

寻找路径的方法有两种。一种是广度优先搜索。这是在图论中寻找最短路径最常用的方法,几乎是不二选择。另一种是深度优先搜索,大部分情况下它在找路径尤其是找最短路径方面的效率不如广度优先搜索。但由于此题的特殊性,在这里应用深度优先搜索并不比广度优先差,构造上要简洁一点。原贴中21楼墨清

扬应用的就是经典的广度优先搜索,对于想学习这种算法的朋友应该好好看看。而我在原贴23楼使用的则是深度优先搜索。呵呵,其实我一开始打算用的也是广搜的,不过等我准备写代码时墨清扬的代码已经贴上来了,于是决定换一个角度给大家展示点不同的东西。这样大家可以从不同角度对比分析各种算法的优劣,为在自己的应用中选择合适的方案提供多一点的思路。至于19楼erty1001算法,不能说它错,因为它确实找到了路径,但存在大量的环,也就是做很多无用的往返。这不叫蒙特卡罗算法,充其量是在图中的随机行走,直到碰巧走到目的结点为止。这个问题的最短路径长度是11(进行11次摆渡),而erty1001代码的结果我测试了几次,最短是37,长的300+。因为步骤太多我没有实际验证结果的正确性,不过看代码应该没什么问题,至少这一方法是可行的。所以按照约定我会送erty1001 100专家分。就在这贴里吧,e rty1001麻烦在这里回个贴。

分析完问题模型和算法选择就确定了程序编码方向,但在实际动手敲代码前还需要做一件事情——问题规模分析,也可以叫解空间分析、状态空间分析等等。

就是估算计算量,用于确定数据存储空间的需量和算法的运算量,以此来确定数据结构和评估算法的效率。

先算一下图中可能的状态结点大概有多少。注意,这里我们估算的是一个上限,并不是精确值。因为计算精确值往往比较复杂耗费的精力时间较多,使用简化的模型估算一个上限比较简单。只要这个上限是可接受的那实际运算就更没问题了。

状态结点包含这么五个量:左岸商人的数量、左岸仆人的数量、右岸商人的数量、右岸仆人的数量以及船的位置。由于商人和仆人的总数量一定,所以也可以描述成商人的总数量、仆人的总数量、左岸商人的数量、右岸仆人的数量和船的位置。

应用组合数学的知识可知,商人在两岸可能的分布方法有4种,仆人在两岸可能的分布方法有4种,船的位置有2种。那么可能的状态有 4 ×4 ×2 = 32种。

这32种里包含了不应该出现的会发现血案的状态,和随然可以出现但实际不会与其它状态有连接的孤立状态。所以实际状态数会比32还小。这个规模很小,怎么算都可以,这也是erty1001的随机行走可行的主要原因。

规模分析完了,下面确定数据结构。一般来讲结构体是描述状态结点的最自然选择。原贴21楼墨清扬的结构体设计的就很好,他将两个运算中不变的量(商人和仆人的各自总数量,事实上他将这两个量合并为一个量n,这样做缺憾的一点是不能解决商人和仆人数量不等的情况,当然解决原问题已经足够了)提到了结构之外,这样缩小了结构的尺寸减少了存储空间。

现在可以开始编码了。在解释原贴23楼我的代码前,先写一个教学级的范本。

呵呵再多说两句。关于我的代码风格在这个论坛里一直存在争议。喜欢的认为它简洁,不喜欢的认为它可读性太差。这个见仁见智了,我那样写代码是因为我喜欢,我喜欢简约的美,无论是算法上还是编码上。除了分隔用的空格和缩进我不允许我的代码中有多余的字符。能用一句表达的意思我不想用两句。至于可读性,我写在这里的代码多是(偏数学的、理论的)算法相关的,阅读这类代码如果没有相关的理论基础,基本是写成什么样都读不懂的。我也常强调切勿模仿这样的代码风格,我也只应用于这类小型的算法代码,我是把它当做一件艺术品在雕琢,应用型代码写成这样就麻烦了。

下面是段工整的代码范本。主要函数和变量都使用了能表述其功能的完整单词,需要说明的大概是几个缩写,比如:

变量s表示状态(state的缩写,大概有人觉得status更合适)

ss数组是状态集(states set的缩写)

ferry_s表示摆渡一个仆人过河(ferry one servant)

ferry_ss表示摆渡两个仆人过河(ferry two servants)

ferry_m表示摆渡一个商人过河(ferry one master,这里我没有用商人这个名词,用的是主人,大家理解它代表什么就好)

其它的大家以此类推。

输出的结果状态而不是状态的转移路径。转移一共需要11步形成11个后续状态,所以包括初始的状态一共12个。左右两组花括号表示两岸,其中m后的数字表示商人的数量,s后的数字表示仆人的数量,惊叹号表示船的位置。这样输出是为了方便,改成输出转移过程也很简单,只需加个动作数组保存转移操作再改变一下输出函数即可。

具体输出结果如下:

{m:3, s:3} !~ {m:0, s:0}

{m:3, s:1} ~! {m:0, s:2}

{m:3, s:2} !~ {m:0, s:1}

{m:3, s:0} ~! {m:0, s:3}

{m:3, s:1} !~ {m:0, s:2}

{m:1, s:1} ~! {m:2, s:2}

{m:2, s:2} !~ {m:1, s:1}

{m:0, s:2} ~! {m:3, s:1}

{m:0, s:3} !~ {m:3, s:0}

{m:0, s:1} ~! {m:3, s:2}

{m:0, s:2} !~ {m:3, s:1}

{m:0, s:0} ~! {m:3, s:3}

程序代码:

#include

#define LEFT_BANK 0

#define RIGHT_BANK 1

typedef struct

{

int left_masters;

int left_servants;

int right_masters;

int right_servants;

int boat_location;

}STATE;

STATE ferry_s(STATE s)

{

if(s.boat_location == LEFT_BANK) {

s.left_servants--;

s.right_servants++;

s.boat_location = RIGHT_BANK; }

else

{

s.left_servants++;

s.right_servants--;

s.boat_location = LEFT_BANK;

}

return s;

}

STATE ferry_ss(STATE s)

{

if(s.boat_location == LEFT_BANK) {

s.left_servants -= 2;

s.right_servants += 2;

s.boat_location = RIGHT_BANK; }

else

{

s.left_servants += 2;

s.right_servants -= 2;

s.boat_location = LEFT_BANK;

}

return s;

}

STATE ferry_m(STATE s)

{

if(s.boat_location == LEFT_BANK) {

s.left_masters--;

s.right_masters++;

s.boat_location = RIGHT_BANK; }

else

{

s.left_masters++;

s.right_masters--;

s.boat_location = LEFT_BANK;

}

return s;

}

STATE ferry_mm(STATE s)

{

if(s.boat_location == LEFT_BANK) {

s.left_masters -= 2;

s.right_masters += 2;

s.boat_location = RIGHT_BANK; }

else

{

s.left_masters += 2;

s.right_masters -= 2;

s.boat_location = LEFT_BANK;

}

return s;

}

STATE ferry_ms(STATE s)

{

if(s.boat_location == LEFT_BANK) {

s.left_masters--;

s.left_servants--;

s.right_masters++;

s.right_servants++;

s.boat_location = RIGHT_BANK; }

else

{

s.left_masters++;

s.left_servants++;

s.right_masters--;

s.right_servants--;

s.boat_location = LEFT_BANK;

}

return s;

}

STATE (* ferry[])(STATE) = {ferry_s, ferry_ss, ferry_m, ferry_mm, ferry_ms};

int legal(STATE s)

{

if(s.left_masters < 0) return0;

if(s.left_servants < 0) return0;

if(s.right_masters < 0) return0;

if(s.right_servants < 0) return0;

if(s.left_masters > 0&& s.left_masters < s.left_servants) return0;

if(s.right_masters > 0&& s.right_masters < s.right_servants) return0;

return1;

}

int equal(STATE s1, STATE s2)

{

if(s1.left_masters != s2.left_masters) return0;

if(s1.left_servants != s2.left_servants) return0;

if(s1.right_masters != s2.right_masters) return0;

if(s1.right_servants != s2.right_servants) return0;

if(s1.boat_location != s2.boat_location) return0;

return1;

}

int is_end_state(STATE s)

{

return s.left_masters == 0&&

s.left_servants == 0&&

s.right_masters == 3&&

s.right_servants == 3&&

s.boat_location == RIGHT_BANK;

}

void show_state(STATE s)

{

printf("{m|%d}{s|%d} %s {m|%d}{s|%d}\n",

s.left_masters, s.left_servants, (s.boat_location == LEFT_BANK ? "!~": "~!"), s.right_masters, s.right_servants);

}

int search(STATE * existing_states, int states_index)

{

STATE s;

int length, i, j;

if(is_end_state(existing_states[states_index]))

return states_index + 1;

for(i = 0; i < 5; i++)

{

s = ferry[i](existing_states[states_index]);

if(!legal(s)) continue;

for(j = 0; j <= states_index; j++)

if(equal(s, existing_states[j]))

break;

if(j <= states_index) continue;

existing_states[states_index + 1] = s;

length = search(existing_states, states_index + 1);

if(length > 0) return length;

}

return0;

}

int main()

{

STATE ss[32] = {{3, 3, 0, 0, LEFT_BANK}};

int count, i;

count = search(ss, 0);

for(i = 0; i < count; i++)

show_state(ss[i]);

return0;

}

看完上段代码再来说说我在原贴23楼贴的代码。其实算法与上面是完全一样,之所以看起来如此不同是因为我改变了数据结构。

这里我用位来表示那些状态属性,格式是这样的

1MM1SS1mm1ssB

每一个字母或数字表示一个二进制位。

其中B表示船的位置,值0表示在左岸,1表示在右岸。

s表示左岸仆人的数量。由于个人数量最大为3,所以使用了两个二进制位。

m表示左岸商人的数量。

大写字母表示右岸的情况。

间隔的1是用来隔离各个属性值。由于状态转移过程我是用数值的加减运算来模拟的,这个过程会产生对

高位的进位和借位,通过多加一位1来防止运算入侵到别的属性,同时它也成为状态运算结果的一个判断标志。

函数search中的m数组便是转移操作数值。

以0x7E为例,它表示将一个仆人从左岸摆渡到右岸。

对于一个状态1MM1SS1mm1ssB来说,将一个仆人从左岸摆渡到右岸相当于给它加上(二进制)10000000,再减去10。即

s1 = s0 + 10000000b - 10b = s0 + (10000000b - 10b) = s0 + 1111100b = s0 + 7Eh(十六进制)

同理如果是将一个仆人从右岸摆渡到左岸则是s1 = s0 - 7Eh。

隔离位剥离出来即是1001001001000,写成十六进制就是0x1248。

十六进制是二进制最自然的简写,大家应该熟练掌握它们之间的转换,应该做到看见一种形式就能随手写出另一种形式。这个基本功非常建议大家练好。

这里写成十进制数就没有它的位的意义了,看起来会很别扭。

search函数中的f数组是用来记录已经搜索过的状态的用于消除环路。上面讨论过状态数不超过32个,但我这里数组的大小是0x40,即64个。为什么?

因为商人仆人的各自总数不变,所以只需要查看一侧岸上商仆的数量及船的位置就可以确定一个状态。所以对于我代码中的一个状态表示1MM1SS1mm1ssB来说,我只需要查看低6位的值(mm1ssB)即可确定一种状态(也是因此我将表示船的位安排在了最低位)。只是中间多了一个隔离位,所以多占去32个无用空间。也可以想办法去掉这个隔离位来节省空间。但在每次搜索都增加一次位运算与总体浪费32个整型空间的权衡上,我选择了后者。时间与空间经常呈现出一种矛盾状态,我们经常要做出取此舍彼的选择。

为了查看方面下面将原贴23楼的代码再贴一遍。

程序代码:

#include

void show(int s)

{

printf("{m:%d, s:%d} %s {m:%d, s:%d}\n",

(s>>4)&3, (s>>1)&3, (s&1?"~!":"!~"),(s>>10)&3, (s>>7)&3);

}

int search(int* ss, int es)

{

const int m[] = {0x7E,0xFC,0x3F0,0x7E0,0x46E};

static char f[0x40];

int s, c, t, i;

if(*ss == es) return1;

f[*ss & 0x3F] = 1;

for(i = 0; i < sizeof(m) / sizeof(m[0]); i++)

{

t = s = *ss + (*ss & 1? -m[i] : m[i]) ^ 1;

if((t & 0x1248) != 0x1248) continue;

t |= ((s >> 4& 3) ? 0: 0x30) | ((s >> 10& 3) ? 0: 0xC00); if(((t - ((t & 0x186) << 3)) & 0x1248) != 0x1248) continue;

if(f[s & 0x3F]) continue;

ss[1] = s;

c = search(ss + 1, es);

if(c > 0){ f[*ss & 0x3F] = 0; return c + 1;}

}

f[*ss & 0x3F] = 0;

return0;

}

int main()

{

int ss[16] = {0x127E}, es = 0x1FC9, c, i;

c = search(ss, es);

for(i = 0; i < c; show(ss[i++]));

return0;

商人过河问题数学建模修订稿

商人过河问题数学建模 WEIHUA system office room 【WEIHUA 16H-WEIHUA WEIHUA8Q8-

作业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,vu+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+1k S =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)

商人过河问题

商人过河 一、问题重述和分析 随从们密约, 在河的任一岸, 一旦随从的人数比商人多, 就杀人越货。现有4名商人各带一个随从一起渡河一只船只能容纳两个人,但如何乘船渡河的大权掌握在商人的手里,商人怎样安排才能在有限步内安全渡河? 二、模型假设 1、在商人人数多于随从时乘船渡河的大权掌握在商人的手里; 2、商人和随从都会划船; 三.符号说明 x表示商人人数; y表示随从人数; z表示划船到河的此岸与彼岸。 四、模型的建立与求解 本题为多步决策模型,每一次过河都是状态量的转移过程。 此岸四个商人用x=0、1、2、3、4表示,此岸四个随从用y=0、1、2、3、4表示,z=0时表示划船到河的此岸时,z=1时表示划船到河的彼岸时,用有序数对(x,y,z)表示每次转移的状态量。解决此问题就是状态量(4,4,0)转移至(0,0,1),以下就是状态量转移的全部情况(其中“!”表示不能再转移下去或与前面步骤重复): (4,4,0)→(3,3,1) ↓↓ (4,2,1)→(4,3,0)→(4,1,1)→(4,2,0)→(4,0,1)→(4,1,0)→! ↓ (2,2,1) ↓ ! 由以上关系可知,一只船只能容纳两个人的情况下,四名商人各带一个随从无法过河。 此外,如果船的容量增加到3人,那么商人就能以几种方式安全过河,以下

是其中一种方案: (4,4,0)→(4,2,1)→(4,3,0)→(4,1,1,)→(4,2,0)→(2,2,1) ↓ (0,1,1)←(0,3,0)←(0,2,1)←(0,4,0)←(0,3,1)←(3,3,0)↓ (0,2,0)→(0,0,1) 五、模型推广 通过以上模型的建立,若商人和随从人数增加或小船容量加大,考虑n名商人各带一随从的情况。

论文题目:过河问题

论文题目:过河问题及其扩展 姓名学号学院年级缺勤记录 朱本超2009221104120031 数计学院09级 陈凯2009221104120004 数计学院09级 张安龙2009221104120016 数计学院09级 课程论文自检报告 请回答以下问题,并在每题后打√确认。 1.除作者外,是否请过同事(同学)对论文进行挑剔性阅读? 2.“问题提出”或前言部分中的文献回顾是否完备? 3.是否对照过提供的“论文格式”逐项检查论文的各个部分? 4.文后参考文献与文中的文献引用是否一一对应? 5.文后参考文献的书写格式是否符合国家标准?(尤其注意著录符号、外国人的姓和名、有无漏项等)6.参考文献是否以近5年的文献为主? 7.作者信息是否完整?包括word文档属性中的作者与单位、学号等。 课程论文质量评价标准 评阅点评分标准分值得分 摘要基本写出论文大意且语言简练、文字组织合理20 基本写出论文大意且语言简练15 基本写出论文大意10 套话、虚话较多或字数不够或文不对题0-5 正文论证严谨、思路清晰、逻辑性强、有较强说服力,引文准确25 论证较严谨、思路较清晰、符合逻辑、有一定说服力,引文准确20 思路较清晰、引文较恰当15 有一定的说服力但论文紊乱、自相矛盾、大段抄袭他人文章0-10 结构结构严谨、逻辑严密、层次清晰20 结构合理、符合逻辑、层次分明18 结构基本合理、层次比较清楚、文理通顺15 有不合理部分,逻辑性不强0-10 深度和广度见解独特,对问题分析透彻,且非常全面25 有自主的见解,对问题的分析比较深入全面20 能提出自己的见解,分析的深度、广度一般15 分析比较深入全面10 对问题的分析既无深度,又无广度0-5 规范化格式完全符合规范,字数完全符合要求10 格式比较规范,字数偏少8 格式基本符合规范,但有个别地方不合规,字数较少 5 格式规范性尚可,但不足之处较多,字数太少0-3 备注:以上评分标准仅供参考。总分

数学建模题型

1、问题描述(问题与假设) 随从们密约, 在河的任一岸, 一旦随从的人数比商人多, 就杀人越货.乘船渡河的方案由商人决定.商人们怎样才能安全过河? 假设:1. 过河途中不会出现不可抗力的自然因素。 2. 当随从人数大于商人数时,随从们不会改变杀人的计划。 3.船的质量很好,在多次满载的情况下也能正常运作。 4. 随从会听从商人的调度。 2、问题模型与求解(公式、图、表、算法或代码等) 模型的建立: 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~允许状态集合 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) 数学模型: 模型分析: 由(2)(3)(5)可得 Yk Xk -≥-44 化简得 Yk k ≤X 关键代码:

clear clc n=3;m=3;h=2; m0=0;n0=0; tic LS=0; LD=0; for i=0:n for j=0:m if i>=j&n-i>=m-j|i==n|i==0 LS=LS+1; S(LS,:)=[i j]; end if i+j>0&i+j<=h&(i>=j|i==0) LD=LD+1; D(LD,:)=[i j]; end end end N=15; 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

商人过河问题

商人过河问题 /*************************************************** *M个商人与每人各带的一个仆人过河问题 *船每次至多运N个人,至少要有一人划船 *在任一岸,当商人数<仆人数时,仆人就杀人越货 *过河由商人安排运送人员及数目 *找出安全渡河的全部方法并打印(原问题中M=3,N=2) *2010-10-10 20时许(纪念伟大的双十) * LYP ***************************************************/ /****************************************************************** *本题为多步决策 *若考虑只针对人数为 M = 3 对,每次过河人数最多 N = 2 *可以证明路径中必须经坐标中(3,1)过至(1,1)点(过诃时), *后返回至(2,2)点,再过诃至(0,2)点(只剩2个仆人) *可以先考虑(3,3)到(3,1)点 *再经(0,2)至(0,0),完成过诃(由图形的对称性关系,可以直接将(3,1)至(3,1)路径翻转,更改对应标号即可) *当然也可以用动态规划求解 *本代码不限定M,N值,可通过修改宏M,N的值,求其他商人(仆人)数与最大过河人数的全部路径 *******************************************************************/ /********************************************************************* * *商人数x < 仆人数y时遭杀人越货,过河失败 *对应可行域为: *x = 0, y = 0…M; elements[]中编号0…M *0 < x < M, y = x; elements[]中编号M+1…2M-1 *x = M, y = 0…M; elements[]中编号2M…3M *图像上表示如下:(共 3*M+1 个点),过河即从3M点到0点 *过河为左下方1/4圆区域 *返回为右上方1/4圆区域

商人安全过河问题

讨论资金积累、国民收入与人口增长的关系 班级:2009级数学与应用数学 黄全(组长): P092314746 邱亚彪: P091712712 谢志成:P091712679 央金:P091715381 罗国庭:P091712739

讨论资金积累、国民收入与人口增长的关系 摘要 如何保证人口增长对国民收入影响的正效应和国民平均收入持续性增长,一直是全国人民所共同关注的问题。本文对资金积累、国民收入和人口增长三者之间的关系进行讨论,通过导数结合三者之间存在的基本规律,建立相应的微分方程,利用微分方程法给出方程,由matlab解得资金积累、国民收入与人口增长的关系。通过掌握该关系,确定资金积累的增长率大于人口增长率时国民收入才会增长,从而更好地调整人口出身率、控制人口的数量和人口质量,保证我国人口增长与国民收入增长之间的适当的比例关系,使得国民平均持续性增长,促进社会经济的迅速发展,提高人民的生活质量,为整个社会的长远战略需求做贡献。 关键字:资金积累状态转移律图解法微分方程决策

一、 问题重述 讨论资金积累、国民收入与人口增长的关系 (1)若国民平均收入x 与按人口平均资金积累y 成正比,说明仅当总资金积累 的相对增长率k 大于人口的相对增长率r 时,国民平均收入才是增长的. (2)作出k(x)和r(x)的示意图,说明二曲线交点是平衡点,讨论它的稳定性。 (3)分析人口激增会引起什么后果 二、符号说明 1x : t 时刻总资金累积量,2x :t 时刻人口数量, 3x :国民平均收入量 ,k :总资金的相对增长率 r :人口的相对增长率 三 、模型的假设 在一定时期后,增长的人口数量为::22x rx '=; 总资金的增长量为:11x kx '= ; 四、问题的分析 在社会主义发展的初级阶段,国民收入是指一定时期(通常为1年)内,物质生产部门劳动者新创造的价值,它是物质资料生产进一步发展和人口再生产条件改善的物质基础。在其他条件已定的情况下,国民收入总量愈多,人均消费基金和积累基金也越多,从而有利于人们生活的改善和技术装备水平的提高,也有利于人口数量的控制和人口质量的提高。人口增长从 3个方面影响国民收入的增减: ① 人口或劳动者数量的多少; ② 每个劳动者技术装备水平的高低; ③ 劳动者节省消耗和管理才能的大小。 国民收入又分为资金的累积和消费,累积资金=国民收入错误!未找到引用源。消费资金,而消费资金=基本消费资金错误!未找到引用源。人口发展速度。因此, 为增加人均国民收入,增强一国的经济实力和提高人民生活水平,要在大力发展经济、增加生产的基础上合理地调节人口增长。

基于商人过河游戏的数学建模-最新教育文档

基于商人过河游戏的数学建模 1提出问题 文献[1]给出一个智力游戏:“三名商人各带一个随从渡河,一只小船只能容纳二人,由他们自己划行。随从们密约,在河的任一岸,一旦随从的人数比商人多,就杀人越货。但是如何乘船的大权掌握在商人们手中。商人怎样才能安全渡河呢?”此类智力问题当然可以通过一番思考,拼凑出一个可行的方案来。文献[1]中通过图解法给出了解答,但是当商人数与随从数发生变化,船能容纳的人数不是二人时,图解法就会变得繁复而难以解决问题。 因此,将上述游戏改为n名商人各带一个随从过河,船每次至多运p个人,至少要有一个人划船,由他们自己划行。随从们密约,在河的任一岸,一旦随从的人数比商人多,就杀人越货。 但是如何乘船的大权掌握在商人们手中。商人怎样才能安全渡河的问题。 除此之外,考虑了随着船载人数的增多,以及商人与仆人的对数增多到多少时,会影响商人的安全渡河的问题。 2问题分析 由于这个虚拟的游戏已经理想化了,所以不必再作假设。我们希望能找出这类问题的规律性,建立数学模型,并通过计算机编程进行求解。安全渡河游戏可以看做是一个多步决策过程,分步优化,船由此岸驶向彼岸或由彼岸驶回此岸的每一步,都要对船上的商人和随从做出决策,在保证商人安全的前提下,在无限步内使全部人员过河。用状态表示某一岸的人员状况,决策表示船上的人员情况,可以找出状态随决策变化的规律。问题转化为在状态的允许范围内,确定每一步的决策,最后获取一个全局最优方案的决策方案,达到渡河的目标。 除此以外,我们还要找出,随着船载人数的增加,商人与仆人对数达到多少时,会影响到商人不能安全过河。这里要对船载人数进行限制,因为船载人数过多时,此智力游戏会变得相当繁复,就会失去作为游戏的本来意义。 3模型构成

农夫过河问题

课程设计题目:农夫过河 一.问题描述 一个农夫带着一只狼、一只羊和一箩白菜,身处河的南岸。他要把这些东西全部运到北岸。他面前只有一条小船,船只能容下他和一件物品,另外只有农夫才能撑船。过河有以下规则: (1)农夫一次最多能带一样东西(或者是狼、或者是羊、或者是白菜)过河; (2)当农夫不在场是狼会吃羊; (3)当农夫不在场是羊会吃掉白菜。 现在要求为农夫想一个方案,能将3样东西顺利地带过河。从出事状态开始,农夫将羊带过河,然后农夫将羊待会来也是符合规则的,然后农夫将羊带过河仍然是符合规则的,但是如此这般往返,搜索过程便进入了死循环,因此,在这里,采用改进的搜索算法进行搜索。 二.基本要求 (1)为农夫过河问题抽象数据类型,体会数据模型在问题求解中的重要性; (2)要求利用数据结构的方法以及C++的编程思想来完成问题的综合设 计; (3)在问题的设计中,使用深度优先遍历搜索方式,避免死循环状态; (4)设计一个算法求解农夫过河问题,并输出过河方案; (5)分析算法的时间复杂度。 三.概要设计 (1)数据结构的设计 typedef struct // 图的顶点 { int farmer; // 农夫 int wolf; // 狼 int sheep; // 羊 int veget; // 白菜 }Vertex;

设计Vertex结构体的目的是为了存储农夫、狼、羊、白菜的信息,因为在遍历图的时候,他们的位置信息会发生变化,例如1111说明他们都在河的北岸,而0000说明他们都在河的南岸。 t ypedef struct { int vertexNum; // 图的当前顶点数 Vertex vertex[VertexNum]; // 顶点向量(代表顶点) bool Edge[VertexNum][VertexNum]; // 邻接矩阵. 用于存储图中的边,其矩阵元素个数取决于顶点个数,与边数无关 }AdjGraph; // 定义图的邻接矩阵存储结构 存储图的方法是用邻接矩阵,所以设计一个简单的AdjGraph结构体是为了储图的顶点数与边数,农夫过河问题我采用的是图的深度优先遍历思想。 (2)算法的设计 深度优先遍历基本设计思想:设x是当前被访问顶点,在对x做过访问标记后,选择一条从x出发的未检测过的1/12边(x,y)。若发现顶点y已访问过,则重新选择另一条从x出发的未检测过的边,否则沿边(x,y)到达未曾访问过的y,对y访问并将其标记为已访问过;然后从y开始搜索,直到搜索完从y出发的所有路径,即访问完所有从y出发可达的顶点之后,才回溯到顶点x,并且再选择一条从x出发的未检测过的边。上述过程直至从x出发的所有边都已检测过为止。此时,若x不是源点,则回溯到在x之前被访问过的顶点;否则图中所有和源点有路径相通的顶点(即从源点可达的所有顶点)都已被访问过,若图G是连通图,则遍历过程结束,否则继续选择一个尚未被访问的顶点作为新源点,进行新的搜索过程。 程序中的深度优先遍历算法如下: void dfsPath(AdjGraph *graph, int start, int end) // 深度优先搜索从u到v的简单路径 //DFS--Depth First Search { int i = 0; visited[start] = true; //标记已访问过的顶点 if (start == end)

商人过河问题数学建模

作业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+1k S =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)可得 44k k x y -≥- 化简得 k k x y ≤

数学建模作业——实验1

数学建模作业——实验1 学院:软件学院 姓名: 学号: 班级:软件工程2015级 GCT班 邮箱: 电话: 日期:2016年5月10日

基本实验 1.椅子放平问题 依照1.2.1节中的“椅子问题”的方法,将假设中的“四腿长相同并且四脚连线呈正方形”,改为“四腿长相同并且四脚连线呈长方形”,其余假设不变,问椅子还能放平吗?如果能,请证明;如果不能,请举出相应的例子。 答:能放平,证明如下: 如上图,以椅子的中心点建立坐标,O为原点,A、B、C、D为椅子四脚的初始位置,通过旋转椅子到A’、B’、C’、D’,旋转的角度为α,记A、B两脚,C、D两脚距离地面的距离为f(α)和g(α),由于椅子的四脚在任何位置至少有3脚着地,且f(α)、g(α)是α的连续函数,则f(α)和g(α)至少有一个的值为0,即f(α)g(α)=0,f(α)≥ 0,g(α)≥0,若f(0)>0,g(0)=0,

则一定存在α’∈(0,π),使得 f(α’)=g(α’)=0 令α=π(即椅子旋转180°,AB 边与CD 边互换),则 f(π)=0,g(π)>0 定义h(α)=f(α)-g(α),得到 h(0)=f(0)-g(0)>0 h(π)=f(π)-g(π)<0 根据连续函数的零点定理,则存在α’∈(0,π),使得 h(α’)=f(α’)-g(α’)=0 结合条件f(α’)g(α’)=0,从而得到 f(α’)=g(α’)=0,即四脚着地,椅子放平。 2. 过河问题 依照1.2.2节中的“商人安全过河”的方法,完成下面的智力游戏:人带着猫、鸡、米过河,船除需要人划之外,至多能载猫、鸡、米之一,而当人不在场时,猫要吃鸡、鸡要吃米,试设计一个安全过河的方案,并使渡河的次数尽量的少。 答:用i =1,2,3,4分别代表人,猫,鸡,米。1=i x 在此岸,0=i x 在对岸,()4321,,,x x x x s =此岸状态,()43211,1,1,1x x x x D ----=对岸状态。安全状态集合为 :

商人过河问题matlab程序

商人过河functionjueche=guohe %程序开始需要知道商人和仆人数; n=input(' 输入商人数目:'); nn=input(' 输入仆人数目:'); nnn=input(' 输入船的最大容量:'); ifnn>n n=input('' 输入商人数目:'); nn=input(' 输入仆人数目:'); nnn=input(' 输入船的最大容量:'); end %决策生成 jc=1;% 决策向量放在矩阵 d 中,jc 为插入新元素的行标初始为 1 ; for i=0:nnn for j=0:nnn if(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 end j=0; end% 状态数组生成

kx=1;% 状态向量放在 A 矩阵中,生成方法同矩阵生成; for i=n:-1:0 for j=nn:-1:0 if((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; end end j=nn; end; % 将状态向量生成抽象矩阵 k=(1/2)*size(A,1); CX=zeros(2*k,2*k); a=size(d,1); for i=1:2*k for j=1:a c=A(i,:)+d( j,:); x=find((A(:,1)==c(1))&(A(:,2)==c(2))&(A(:,3)==c(3)));

商人过河问题

商人过河问题 一、三名商人各带一名随从的情况 1.问题(略) 2.模型假设 ①当一边岸满足随从数大于商人数,但商人数为0时仍为一种安全状 态; ②小船至多可容纳2人,且渡河时由随从(或者商人)来划船。 3.分析与建模 商人过河需要一步一步实现,比如第一步:两个仆人过河,第二步:一个仆人驾船回来,第三步:又是两个仆人过河,第四步:…… 其中每一步都使当前状态发生变化,而且是从一种安全状态变为另一种安全状态。如果我们把每一种安全状态看成一个点,又如果存在某种过河方式使状态a变到状态b,则在点a和点b之间连一条边,这样我们把商人过河问题和图联系起来,有可能用图论方法来解决商人过河问题。 建模步骤:⑴首先要确定过河过程中的所有安全状态,我们用二元数组(,) x y 表示一个安全状态(不管此岸还是彼岸),其中x表示留在此岸的主人数,y表示留在此岸的随从数。两岸各有十种安全状态: (0,0),(0,1),(0,2),(0,3),(2,2),(1,1),(3,0),(3,1),(3,2),(3,3) ⑵在两岸的安全状态之间,如存在一种渡河方法能使一种状态变为另一种 安全状态,则在这两种状态之间连一条边。这样,得到如下一个二部图(图1),其中下方顶点表示此岸状态,上方顶点表示彼岸状态。我们的目的是要找出一条从此岸(3,3)到彼岸(0,0)的最短路。 ⑶观察发现此岸的状态(0,0),(3,0)和彼岸的状态(0,3),(3,3)都是孤立点,在求最短路的过程中不涉及这些点,把它们删去。两岸的点用1,2, (16) 新标号。 (3,3)(3,2)(3,1)(3,0)(1,1)(2,2)(0,3)(0,2)(0,3)(0,0) ○②④⑥⑧⑩○○12○14○16 ①③⑤○⑦⑨○11○13○15○ (3,3)(3,2)(3,1)(3,0)(1,1)(2,2)(0,3)(0,2)(0,3)(0,0)

数学建模 商人过河

数学建模课程作业 论文题目: 对商人过河问题的研究 指导教师:黄光辉 小组成员:黄志宇(20156260)车辆工程04班 牛凯春(20151927)电气工程05班 文逸楚(20150382)工商管理02

一、问题重述 3名商人带3名随从乘一条小船过河,小船每次只能承载至多两人。随从们密约,在河的任一岸,一旦随从的人数比商人多,就杀人越货。乘船渡河的方案由商人决定,商人们如何才能安全渡河呢? 二、问题分析 本题针对商人们能否安全过河问题,需要选择一种合理的过河方案。对该问题可视为一个多步决策模型,通过对每一次过河的方案的筛选优化,最终得到商人们全部安全过到河对岸的最优决策方案。对于每一次的过河过程都看成一个随机决策状态量,商人们能够安全到达彼岸或此岸我们可以看成目标决策允许的状态量,通过对允许的状态量的层层筛选,从而得到过河的目标。 三、模型假设 1.过河途中不会出现不可抗力的自然因素。 2.当随从人数大于商人数时,随从们不会改变杀人的计划。 3.船的质量很好,在多次满载的情况下也能正常运作。 4.随从会听从商人的调度,所有人都到达河对岸。 四、符号说明 第k次渡河前此岸的商人数 第k次渡河前此岸的随从数 过程的状态向量 允许状态集合 第k次渡船上的商人数 第k次渡船上的随从数 决策向量 允许决策集合

x y 3322110s 1s n +1d 1d 11五、模型建立 本题为多步决策模型,每一次过河都是状态量的转移过程。 用二维向量表示过程的状态,其中分别表示对应时刻此岸的商人,仆人数以及船的行进方向,其中则允许状态集合: = 又将二维向量定义为决策,则允许的决策合集为: 因为k 为奇数时船从此岸驶向彼岸,k 为偶数时船从彼岸驶向此岸,所以状态随决策的变化规律是 该式称为状态转移律。 求决策,使,并按照转移律,由经过有限步n 到达状态 六、模型求解 本模型使用MATLAB 软件编程,通过穷举法获得决策方案如下(完整matlab 程序详见附录): 初始状态: 可用图片表示为:X0= 3 3状态为: S = 3 13 23 03 11 12 20 20 30 10 20 0决策为: D = 02

数学建模商人过河__论文

组长:王鹏道110714 组员:任利伟110713、孙祎110706 小组成员负责情况: 王鹏道:选择论文题目、设计论文版面字体、分配成员任务、总结任利伟:一、问题提出、关键、分析。二、模型假设、三、模型建立孙祎:四、模型求解、五、模型的检验、拓展及延伸 2014年11月24日 摘要 为了求解3个商人和3个随从的过河问题,用数学分析方法,建立数学模型,并且加以求解,展示动态规划思想的应用步骤。最后利用计算机蝙程进行求解,获得过河问题的完整求解过程;有效地求解类似多步决策问题的作用。 关键词:多步决策计算机求解状态转移律图解法

一、 问题的提出 随从们密约, 在河的任一岸, 一旦随从的人数比商人多, 就杀人越货,但是乘船渡河的方案由商人决定.商人们怎样才能安全过河? 二、 问题的关键 解决的关键集中在商人和随从的数量上,以及小船的容量上,该问题就是考虑过河步骤的安排和数量上。各个步骤对应的状态及决策的表示法也是关键。 三、 问题的分析 在安全的前提下(两岸的随从数不比商人多),经有限步使全体人员过河。由于船上人数限制,这需要多步决策过程,必须考虑每一步船上的人员。动态规划法正是求解多步决策的有效方法。它要求把解的问题一层一层地分解成一级一级、规模逐步缩小的子问题。直到可以直接求出其解的子问题为止。分解成所有子问题按层次关系构成一棵子问题树.树根是原问题。原问题的解依赖于子问题树中所有子问题的解。 四、 模型假设 记第k 次过河前A 岸的商人数为X K , 随从数为Y K k=1,2,? X K ,Y K =0,1,2,3,将二维向量S K =(X K ,Y K )定义为状态.把满足安全渡河条件下的状态集合称为允许状态集合。记作S 。则 S={(X K ,Y K )|(X K =0,Y K =0,1,2,3),(X K =3,Y K =0,1,2,3),(X K =Y K =1)(X K =Y K =2)} 记第k 次过河船上的商人数为U K 随从数为V K 将二维向量D K =(U K ,V K )定义为决策.由小船的容量可知允许决策集合(记作D)为 D={(U K ,V K )|U K +V K =l,2}={(O,1);(O,2);(1,O);(1,1);(2,O)} 五、 模型建立: 动态规划法正是求解多步决策的有效方法。它要求把解的问题一层一层地分解成一级一级、规模逐步缩小的子问题。直到可以直接求出其解的子问题为止。分解成所有子问题按层次关系构成一棵子问题树.树根是原问题。原问题的解依赖于子问题树中所有子问题的解。

数学建模与数学实验课后习题答案

P59 4.学校共1002名学生,237人住在A 宿舍,333人住在B 宿舍,432人住在C 宿舍。学生要组织一个10人的委员会,使用Q 值法分配各宿舍的委员数。 解:设P 表示人数,N 表示要分配的总席位数。i 表示各个宿舍(分别取A,B,C ),i p 表示i 宿舍现有住宿人数,i n 表示i 宿舍分配到的委员席位。 首先,我们先按比例分配委员席位。 A 宿舍为:A n = 365.21002 10237=? B 宿舍为:B n =323.31002 10333=? C 宿舍为:C n =311.4100210432=? 现已分完9人,剩1人用Q 值法分配。 5.93613 22372 =?=A Q 7.92404 33332 =?=B Q 2.93315 44322 =?=C Q 经比较可得,最后一席位应分给A 宿舍。 所以,总的席位分配应为:A 宿舍3个席位,B 宿舍3个席位,C 宿舍4个席位。

商人们怎样安全过河

由上题可求:4个商人,4个随从安全过河的方案。 解:用最多乘两人的船,无法安全过河。所以需要改乘最多三人乘坐的船。 如图所示,图中实线表示为从开始的岸边到河对岸,虚线表示从河对岸回来。商人只需要按照图中的步骤走,即可安全渡河。总共需要9步。

P60 液体在水平等直径的管内流动,设两点的压强差ΔP 与下列变量有关:管径d,ρ,v,l,μ,管壁粗糙度Δ,试求ΔP 的表达式 解:物理量之间的关系写为为()?=?,,,,,μρ?l v d p 。 各个物理量的量纲分别为 []32-=?MT L p ,[]L d =,[]M L 3-=ρ,[]1-=LT v ,[]L l =,[]11--=MT L μ,Δ是一个无量纲量。 ???? ??????-----=?0310100011110010021113173A 其中0=Ay 解得 ()T y 00012111---=, ()T y 00101102--=, ()T y 01003103--=, ()T y 10000004= 所以 l v d 2111---=ρπ,μρπ112--=v ,p v ?=--313ρπ,?=4π 因为()0,,,,,,=??p l v d f μρ与()0,,,4321=ππππF 是等价的,所以ΔP 的表达式为: ()213,ππψρv p =?

商人们怎样安全过河 (附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=guohe clear all clc %%%%%%%%%%程序开始需要知道商人和仆人数;%%%%%%%%%%%%% shangren=input('输入商人数目: '); puren=input('输入仆人数目: '); rongliang=input('输入船的最大容量: '); if puren>shangren shangren=input('输入商人数目:'); puren=input('输入仆人数目:'); rongliang=input('输入船的最大容量:'); end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 决策生成 jc=1; %决策向量放在矩阵d中,jc为插入新元素的行标初始为1; for i=0:rongliang for j=0:rongliang if (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要向下移动两个; end end j=0; end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 状态数组生成 kx=1; % 状态向量放在A矩阵中,生成方法同矩阵生成; for i=shangren:-1:0 for j=puren:-1:0 if ((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; end end

商人过河matlab程序以及解析

数学建模作业 班级:数学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带一只羊s,一只狼w和一筐白菜v过河。没有船,他每次游过河时只能带一件东西,当没有人管理时,狼和羊不能相处,羊和白菜不能相处。在这些条件的约束下,他怎样才能将三件东西从左岸带往右岸?试编程给出一组过河次数最少的方案。【问题分析】 用无向图描述上述问题的解法路径 用结点代表状态 例如:初始状态v1可记为 {}> Φ <, , , ,v w s m(即,人、羊、狼、 白菜皆在左岸,右岸为空,这是一种安全状态,即满足约束条件 的状态)。最终状态v10可记为 {}> Φ Φ <, , , ,v w s m ②{}{}>

⑨{}{}>Φ

商人过河优化模型

2011高教社杯全国大学生数学建模竞赛 承诺书 我们仔细阅读了中国大学生数学建模竞赛的竞赛规则. 我们完全明白,在竞赛开始后参赛队员不能以任何方式(包括电话、电子邮件、网上咨询等)与队外的任何人(包括指导教师)研究、讨论与赛题有关的问题。 我们知道,抄袭别人的成果是违反竞赛规则的, 如果引用别人的成果或其他公开的资料(包括网上查到的资料),必须按照规定的参考文献的表述方式在正文引用处和参考文献中明确列出。 我们郑重承诺,严格遵守竞赛规则,以保证竞赛的公正、公平性。如有违反竞赛规则的行为,我们将受到严肃处理。 我们参赛选择的题号是(从A/B/C/D中选择一项填写): B 我们的参赛报名号为(如果赛区设置报名号的话): 所属学校(请填写完整的全名):西京学院 参赛队员(打印并签名) :1. 邹高永 2. 张大伟 3. 钱晓东 指导教师或指导教师组负责人(打印并签名): 日期:年月日赛区评阅编号(由赛区组委会评阅前进行编号):

2011高教社杯全国大学生数学建模竞赛 编号专用页 赛区评阅编号(由赛区组委会评阅前进行编号): 赛区评阅记录(可供赛区评阅时使用): 评 阅 人 评 分 备 注 全国统一编号(由赛区组委会送交全国前编号): 全国评阅编号(由全国组委会评阅前进行编号):

商人过河 摘要 本文针对商人安全渡河的问题,采用多步决策的过程建立数学模型,求解得到了在随从没有杀人越货的情况下的渡河方案。 对于本题而言,在3名商人、3名随从、船的最大容量为2的情况下,首先定义了渡河前此岸的状态,并设安全渡河条件下的状态集定义为允许状态集合,接着得到渡河方案的允许决策集合,然后得到状态随渡河方案变化的规律,最后利用平面坐标分析法,并利用计算机进行了仿真,得到了一种商人安全渡河的方案。 但是,本文不仅仅是为了拼凑出一个可行方案,而是希望能找到求解这类问题的规律性,并建立数学模型,用以解决更为广泛的问题。基于此目的,利用了dijkstra算法,得到最短路径的最优解。但同时由于该算法遍历计算的节点很多,所以效率低,而且当有多个最短距离时,不能够将所有符合条件的情况逐一列出。 最后,从这类问题解得趣味性、合理性进行了深入讨论,得到了“传教士与野蛮人渡河”,“印度夫妻渡河”等问题通用的模型,并将其进行了推广。这也是本文的一大特色。 关键词渡河问题状态集合决策集合平面坐标dijkstra算法