图论——最短路径之渡河问题
渡河问题是图论(图与网络模型及方法)中求解最短路径的经典例题,也是一道很有意思的问题。
题目大致描述如下:某人带狼、羊、蔬菜渡河,有一艘船,每次渡河人只能载一物。我们都知道,狼吃羊、羊吃菜,所以当人不在场时,狼和羊不能共存、羊和菜不能共存。试述此人的最少渡河次数。
首先第一步,我们将河的两岸分为东西两岸,东岸为起始状态,西岸为最终目标状态。构造一个四维向量,分别代表人、狼、羊、菜的位置状态,1表示在东岸(起始位置),0表示在西岸(目标位置)。利用穷举法我们可以获得所有可以发生的10种情况:
- (1,1,1,1) ——都在东岸
- (1,1,1,0) ——除了菜在西岸,其余都在东岸(以此类推)
- (1,1,0,1)
- (1,0,1,1)
- (1,0,1,0) ——把狼和羊、羊和菜分开,即人和羊在一起,狼和菜在一起
- (0,1,0,1) ——同上
- (0,1,0,0)
- (0,0,1,0)
- (0,0,0,1)
- (0,0,0,0)
上述十种情况分别对应“图”中的十个顶点,本题本质为:求解当初始状态(1,1,1,1)时,经最小次数转移达到最终状态(0,0,0,0)的最短路径。
综上所述,图中的顶点已经构造好,下面要考虑如何确定哪些顶点之间可以有线,而哪些顶点之间不会存在线。
因此第二步,我们需要构造“可行转移“的四维向量。上述十个可行状态,当且仅当对应的两个可行状态之间存在一个可行转移时,两顶点之间才有边,此时我们让存在可行转移的两顶点之间的边对应的权重取1,否则取无穷大(inf)。
定义转移向量(1,0,0,0)、(1,1,0,0)、(1,0,1,0)、(1,0,0,1)分别表示人自己过河、人带狼过河、人带羊过河、人带菜过河。
状态向量与转移向量之间的运算是0+0 = 0;0+1 = 1;1+0 = 1;1+1=0。
即+0表示该物体位置保持不变,+1表示该物体过一次河。观察运算规律,其实本质上是对当前位置状态向量和可行转移操作向量之间进行异或处理,相同留0,不同留1,得到的新的四维向量若属于上述十种可行状态向量,则在先后的两种状态对应的“顶点”之间添加一条边。获得完整的“图”,利用matlab工具箱中的graphshortestpath函数求的最短路径。
具体代码如下:
clc,clear %清空当前命令行窗口和工作区变量
a = [1 1 1 1;1 1 1 0;1 1 0 1;1 0 1 1;1 0 1 0;0 1 0 1;0 1 0 0;0 0 1 0;0 0 0 1;0 0 0 0];%每一行是一个可行状态
b = [1 0 0 0;1 1 0 0;1 0 1 0;1 0 0 1]; %每一行是一个转移状态
w = zeros(10); %邻接矩阵初始化
for i = 1:9for j = i+1:10for k = 1:4if strfind(xor(a(i,:),b(k,:)),a(j,:)) %#ok<STRIFCND> % strfind(s1,pattern),因此其意思在s1中搜索pattern% xor(a,b)表示异或,当两者都是0,或两者是非零值时,xor(a,b)结果为0;否则,xor(a,b)结果为1;w(i,j) = 1;endendend
end
w = w';
c = sparse(w); %构造稀疏矩阵
[x,y,z] = graphshortestpath(c,1,10,'Directed',0); %无向图,0/false
h = view(biograph(c,[],'ShowArrows','off','ShowWeights','off')); %画出无向图
Edges = getedgesbynodeid(h); %提取句柄h中的边集
set(Edges,'LineColor',[0,0,0]); %为了打印清楚,边画成黑色
set(Edges,'LineWidth',1.5) %线型宽度设置为1.5
在matlab中运行该代码,得到的结果表明的含义如下:
x = 7; %表示最短路径要进行7次渡河
y = 1 6 3 7 2 8 5 10; %表示转移状态顺序:1-6-3-7-2-8-5-10;
图像如下:
图论——最短路径之渡河问题相关推荐
- BUAA离散数学第十章 图论 最短路径及关键通路 python解法
BUAA离散数学第十章 图论 最短路径及关键通路 python解法 前言 一.最短通路 题目描述 输入 输出 解题思路 代码 顶点 边 图 Solution 运行测试 二.关键通路 题目描述 输入 输 ...
- 数据结构与算法--图论最短路径算法应用-词阶求解
最短路径案例 词梯应用,在一个词梯中,每个单词均由前一个单词改变一个字母而得到.例如,我们通过一系列单字母替换而得到zero转换为five,如下:five:zero,hero,here,hire,fi ...
- 数学建模 图论最短路径问题
1.图的基本概念 图论中的图(Graph)是由若干给定的点及连接两点的线 所构成的图形,这种图形通常用来描述某些事物之间的某种 特定关系,用点代表事物,用连接两点的线表示相应两个事 物间具有这种关系. ...
- 矩阵和图结构(图论) 最短路径问题 学习笔记
矩阵和图是可以相互转换的,这里的图不仅仅是图片,还包括图结构(图论) 所以最短路径问题解决矩阵和结局图论均是一个问题.
- 图论-最短路径--3、SPFA算法O(kE)
SPFA算法O(kE) 主要思想是: 初始时将起点加入队列.每次从队列中取出一个元素,并对所有与它相邻的点进行修改,若某个相邻的点修改成功,则将其入队.直到队列为空时算法结束. 这个算 ...
- 数学建模学习笔记——图论最短路径
[1,2,3,4] {"你好","我好","大家好"} 无向图拥有负权重--都是负权回路 弗洛伊德算法--可以算出任意两点之间的 ...
- dijkstra邻接表_掌握算法-图论-最短路径算法-Dijkstra算法
如果图是赋权图,那么问题就变得更困难了不过我们仍然可以使用来自无权情形时的想法. 我们保留所有与前面相同的信息.因此,每个顶点或者标记为Known的,或者标记为Unknown的.像之前一样,对每一个顶 ...
- 【2018.3.10】模拟赛之四-ssl2133 腾讯大战360【SPAF,图论,最短路径】
目录地址 前言 打错了一个地方之接60,还有输出"Peace"能拿60.还有题目坑爹害得我用了哈希,可以无视 QAQ 正题 有一个n*n的图,有m条边,不知道几个城市,给出两个位置 ...
- 图论最短路径算法——Dijkstra
说实在的,这算法很简单,很简单,很简单--因为它是贪心的,而且码量也小,常数比起SPFA也小. 主要思想 先初始化,dis[起点]=0,其它皆为无限大. 还要有一个bz数组,bz[i]表示i是否确定为 ...
最新文章
- php相关扩展安装及报错总结
- python添加lxml库_7分钟,建议看完这5个Python库对比丨web抓取
- git撤消所有未提交或未保存的更改
- 【Android 内存优化】Java 内存模型 ( Java 虚拟机内存模型 | 线程私有区 | 共享数据区 | 内存回收算法 | 引用计数 | 可达性分析 )
- java程序设计计算器_Java程序设计计算器(含代码)
- 送书 | 一本针对零基础 AI 学习的书:Python入门到人工智能实战
- c语言求未知坐标,求助,有关坐标计算的
- Leetcode 32.最长有效括号
- Windows-查看系统安装时间、启停某服务、组策略、限制外部设备命令
- Maven的parent pom的依赖
- centOS 安装远程桌面
- Aptos 深度解读:机遇、挑战与风险
- 零基础小白如何转行数据分析
- linux 分区怎样缩小,如何缩小磁盘分区大小
- TreeView 右键菜单
- MATLAB中实现特定像素区域处理
- python关于 unittest的常见用法:前置条件与后置条件
- javascript-obfuscator 代码混淆
- sqlplus set linesize/pagesize等命令详解
- __construct 与 __destruct 区别