过河问题(图论方法)
农夫过河问题
问题描述
一个农夫带着一头狼、一头羊、一颗白菜过河。他面前只有一条船,只能容纳他和一件物品,只有农夫会划船。如果农夫不在场,狼会吃羊、羊会吃白菜,农夫在场则不会。求将所有物品运到对岸的方案。
解题思路
根据物品的位置定义状态,若在左岸记为1,右岸记为0,于是最终方案就是(1,1,1,1)-->(0,0,0,0)所经过的路径。
1、定义状态
2、列举所有状态(人、狼、羊、菜)
3、删除不合理的状态(狼和羊、羊和菜)
4、连边(模拟一次渡河)
5、寻找路径
寻找(1111)-->(0000)的边,可以用寻路算法如bfs、dfs,如果要求最短路可以用最短路算法如bfs、Dijsktra等,当然这里图很简单,可直接观察出来。
(1111)-->(0101)-->(1101)-->(0001)-->(1011)-->(0010)-->(1010)-->(0000)(两条最短路之一)左岸 右岸 1、人 狼 羊 花 空 2、狼 花 人 羊 3、人 狼 花 羊 4、花 人 狼 羊 5、人 羊 花 狼 6、羊 人 花 狼 7、人 羊 狼 花 8、空 狼 花 人 羊
传教士与吃人恶魔的问题
问题描述
有三个传教士和三个吃人恶魔要渡过一条河,河中有一条船,只能装下两个人。在任何地方(无论是岸边还是船上),如果吃人恶魔数量多于传教士数量,吃人恶魔就会吃掉传教士。问:怎么才能让这些都安全过河?
解题思路
1、定义状态
2、列举所有状态
3、删除不合理状态
4、连边(模拟依次渡河变化)
5、寻找路径
寻找(33 L 00)-->(00 R 33)的路径
其中一条路径 (33 L 00)-->(31 R 01)-->(32 L 01)-->(30 R 03)-->(31 L 02)-->(11 R 22)-->(22 L 01)-->(02 R 31)-->(03 L 30)-->(01 R 32)-->(02 L 31)-->(00 R 33) 1、两个吃人恶魔过河 2、一个吃人恶魔回来 3、两个吃人恶魔过河 4、一个吃人恶魔回来 5、两个传教士过河 6、一个传教士和一个吃人恶魔回来 7、两个传教士回来 8、一个吃人恶魔回去 9、两个吃人恶魔过河 10、一个吃人恶魔回去 11、两个吃人恶魔过河
四人过桥问题
问题描述
在一个漆黑的夜里,四位旅游者来到一座狭窄而没有护栏的桥边,如果不借助手电筒的话,大家是无论也不敢过去。不幸的是四个人中只有一只手电筒,而桥窄得只够两个人同时通过。如果各自单独过桥得话,四个人所需要的时间分别是1、2、5、10分钟,如果两个人同时过桥,所需要的时间是较慢的那个人单独行动时的时间。问:如何设计一个方案,让四个人尽快过桥。
解题思路
与前面两个相比,这次不仅要求方案,同时要求时间最短。
同样需要定义状态,四个人+手电筒的位置
1、定义状态
2、建图
分为每次通过一个人和每次两个人,都是带权无向边。
(下面只连接了与(01111)的边)
3、寻找最短路
寻找(L 1111)-->(R 0000)的最短路,即最短路算法中(01111)-->(10000)的最短路,以下是利用Dijstra算法的解决方法。
最终答案为(2 + 1 + 10 + 2 + 2) = 17.
1 #include<stdio.h> 2 #include<iostream> 3 #include<string> 4 #include<queue> 5 #include<algorithm> 6 using namespace std; 7 8 //定义图中结点 9 struct Node 10 { 11 int u, d; //该节点的编号与距离 12 bool operator < (const Node x) const 13 { 14 return d > x.d; 15 } 16 }; 17 18 //边结构体的定义 19 struct Edge 20 { 21 int to; 22 int w; 23 int next; 24 }; 25 26 const int INF = 0x3f3f3f3f; 27 const int V = 32 + 10; 28 const int E = 32 * 32 + 10; 29 int dis[V]; //源到各顶点的最短距离 30 int vis[V]; //记录是否被收录,用来代替集合S 31 int head[V]; //head[i]表示顶点i的第一条边的数组下标,"-1"表示顶点i没有边 32 Edge edge[E]; 33 34 inline void AddEdge(int a, int b, int w, int id) 35 { 36 edge[id].to = b; 37 edge[id].w = w; 38 edge[id].next = head[a]; 39 head[a] = id; 40 return; 41 } 42 43 //s为起点 44 void Dijsktra(int s) 45 { 46 priority_queue<Node>q; //取出集合T中的最小值 47 memset(vis, 0, sizeof(vis)); 48 memset(dis, INF, sizeof(dis)); 49 50 dis[s] = 0; 51 q.push(Node{ s, dis[s] }); 52 while (!q.empty()) 53 { 54 Node x = q.top(); q.pop(); 55 int u = x.u; 56 57 if (vis[u]) continue; 58 59 vis[u] = true; 60 for (int i = head[u]; i != -1; i = edge[i].next) //松弛与u直接相邻的顶点 61 { 62 int v = edge[i].to; 63 int w = edge[i].w; 64 if (!vis[v] && dis[u] + w < dis[v]) 65 { 66 dis[v] = dis[u] + w; 67 q.push(Node{ v,dis[v] }); 68 } 69 } 70 } 71 } 72 73 const int score[] = { 1,2,5,10 }; //每个人单独行动的时间 74 75 int main() 76 { 77 //建图 78 memset(head, -1, sizeof(head)); 79 int id = 0; 80 for (int i = 0; i < (1 << 4); i++) 81 { 82 int bits[4]; 83 for (int j = 0; j < 4; j++) bits[j] = (i >> j) & 1; 84 //一次走一个人 85 for (int j = 0; j < 4; j++) if (bits[j]) 86 { 87 int tmp = i - (1 << j) + 16; 88 int w = score[j]; 89 AddEdge(i, tmp, w, id++); 90 AddEdge(tmp, i, w, id++); 91 } 92 //一次走两个人 93 for(int j = 0;j < 3;j++) 94 for (int k = j + 1; k < 4; k++) if (bits[j] && bits[k]) 95 { 96 int tmp = i - (1 << j) - (1 << k) + 16; 97 int w = max(score[j],score[k]); 98 AddEdge(i, tmp, w, id++); 99 AddEdge(tmp, i, w, id++); 100 } 101 } 102 Dijsktra(15); 103 printf("%d\n", dis[16]); 104 105 return 0; 106 }
此类问题很多,但大多可用图论的思想做(虽然不一定是速度最快的),后续在补充吧,有问题直接留言!
参考链接:中国大学mooc 刘铎老师 离散数学
转载于:https://www.cnblogs.com/lfri/p/9866992.html
过河问题(图论方法)相关推荐
- [ 多智能体网络中的图论方法汉化 ] (一)前言第一章
前言 能够进行短程通信和本地决策的(相对)廉价的传感和驱动节点的出现,提出了许多关于如何协调和控制这种系统的新的系统级问题.可以说,这一新的研究领域面临的最大挑战是本地交互规则如何导致所需的全局属性, ...
- 图论在计算机应用,图像分割的图论方法综述-计算机应用与软件.pdf
第31卷第9期 计算机应用与软件 Vol31No.9 2014年9月 ComputerApplicationsandSoftware Sep.2014 图像分割的图论方法综述 王 梅 李玉砲 全笑梅 ...
- 图论方法在大脑网络中的应用
网络神经科学是一个蓬勃发展且迅速扩展的领域.从分子到行为尺度的大脑网络的数据的规模和复杂性都在不断增加.这些数据的发展对建模和分析大脑网络数据的合适工具和方法具有强烈的需求,例如由图论提供的工具和方法 ...
- 数模国赛备赛(6)数学建模中的图论方法
图论中的许多问题都是NP问题,目前找不到多项式时间内的解决方法. 涉及图论的数学建模题目 涉及到线路,网点等概念的问题,天生就有了图. 图论的很多问题都可以转化成线性规划问题. 例题引入 灾情巡视问题 ...
- JAVA 寻找-人鬼过河游戏的方法
题目: 有三个人和三只鬼在一条河的一岸,需要过河,河中有一条小船,最多可以同时容纳两位,过河的过程中,河岸的任意一边如果,鬼的数目多于人的数目的时候,鬼就会乘机吃掉人,请用程序找出能使人和鬼都能安全过 ...
- 运筹学那些事,专科学生学习运筹学之图论方法,No.7
文章目录 图的基本概念 树和树的逐步生成法 最小枝杈树问题 最短路线问题 最大流量问题 自考说明 图的基本概念 图的最基本要素是: 点以及点之间的一些连线(简称线或者边) 带箭头的线(有向线) 在图的 ...
- 运筹学基础【八】 之 图论方法
感谢内容提供者:金牛区吴迪软件开发工作室 接上一篇:运筹学基础[七] 之 网络计划技术 文章目录 一.图的基本概念 二.树和树的逐步生成法 三.最小枝杈树 四.最短路线问题 五.最大流量问题 一.图的 ...
- 商人渡模型matlab及模型假设,商人过河问题
商人过河问题 一.三名商人各带一名随从的情况 1. 问题(略) 2. 模型假设 ① 当一边岸满足随从数大于商人数,但商人数为0时仍为一种安全状态: ② 小船至多可容纳2人,且渡河时由随从(或者商人)来 ...
- 【转】主要空间数据挖掘方法
Source: http://jerry429.bokee.com/2993629.html 张新长 马林兵等,<地理信息系统数据库>[M],科学出版社,2005年2月 第二章第二节 空间 ...
最新文章
- 部署基于嵌入的机器学习模型的通用模式
- 60. Permutation Sequence
- 正则高级用法-分组group+替换
- 【aviator】aviator 报错 EOF while reading string at index
- 如果人生只剩最后一天,你想在这天干什么?
- 两个凸多边形的公共面积
- 一个经典约瑟夫问题的分析与解答
- 哪些计算机的应用需采用多媒体技术,计算机多媒体技术的应用现状与发展前景...
- 使用springboot自带 MD5加密
- VSTO安装卸载方法
- DOS命令:color
- flash spi w25q128 w25q64 w25q32 w25q16 verilog fpga程序代码
- 【前端工具】实用的代码生成器
- 近几年美国人口数据matlab,2010-2019年美国人口数量及人口性别、年龄、城乡结构分析...
- 推荐书籍:网络系统建设与运维(中级)
- 【文科生带你读JavaScript数据结构与算法】2. 双向链表与LRU缓存算法原理与实现(下)
- 电脑只有一个c盘怎么办?看我怎么一招解决!
- python eel 无边框_荐帮你解剖Python的一个轻量级桌面GUI开发第三方库:Eel,让它体无完肤...
- 记第一次编译Linux内核
- 深入理解CAS算法原理
热门文章
- 导热硅胶片硬度是什么?导热硅胶片硬度测试及选择标准解析
- SD3077、SD3078时钟芯片数据手册、例程
- vmware桥接模式-无法内网通-克隆机要删除的文件-ssl
- python爬取文献代码_使用python爬取MedSci上的影响因子排名靠前的文献
- 【电子杂志设计制作】云展网教程 | 编辑杂志的删除和停用功能
- LeetCode 488 Zuma Game 解题报告
- 10862 - Connect the Cable Wires
- 【mba市场营销论文】金元证券海口营业部市场营销战略分析(节选)
- 服务器性能指标(二)-- 线上服务器内存分析及问题排查
- wegame登录cf显示服务器人数已满,《永恒之塔》Wegame区火爆 老端游焕发新生