数学建模|图与网络模型
图论的基本介绍
由于博主专业,在此不再赘述图论的基本知识算法。 想了解基础知识,请参考图论(一)基本概念与邻接矩阵
顺带一提:
- 对于有向图,只要写出邻接矩阵,直接使用Matlab命令:sparse,可以将邻接矩阵转化为稀疏矩阵的表示方式。
- 对于无向图,由于邻接矩阵是对称的,Matlab中只需要使用邻接矩阵的下三角元素
- 稀疏矩阵可以使用full命令变成普通矩阵。
最短路径问题
两个顶点之间的最短问题
Dijkstra算法
基本步骤:
- 首先,定义一个数组 D,D[v] 表示从源点 s 到顶点 v 的边的权值,如果没有边则将 D[v] 置为无穷大。
- 把图的顶点集合划分为两个集合 S 和 V-S。第一个集合 S 表示距源点最短距离已经确定的顶点集,即一个顶点如果属于集合 S 则说明从源点 s 到该顶点的最短路径已知。其余的顶点放在另一个集合 V-S 中。
- 每次从尚未确定最短路径长度的集合 V-S 中取出一个最短特殊路径长度最小的顶点 u,将 u 加入集合 S,同时修改数组 D 中由 s 可达的最短路径长度。若加入集合 S 的 u 作为中间顶点时,vi 的最短路特殊路径长度变短,则修改 vi 的距离值(即当D[u] + W[u, vi] < D[vi]时,令D[vi] = D[u] + W[u, vi])。
- 重复第 3 步的操作,一旦 S 包含了所有 V 中的顶点,D 中各顶点的距离值就记录了从源点 s 到该顶点的最短路径长度。
Matlab代码及例子

Matlab代码实现
1 | clc,clear all |
Java代码实现
1 | public class DijkstraAlgorithm { |
每个顶点之间的最短路径
迭代使用n-1次Dijkstra算法
Floyd算法
Floyd算法是一个经典的动态规划算法。用通俗的语言来描述的话,首先我们的目标是寻找从点i到点j的最短路径。从动态规划的角度看问题,我们需要为这个目标重新做一个诠释(这个诠释正是动态规划最富创造力的精华所在)。 从任意节点i到任意节点j的最短路径不外乎两种可能:
- 一是直接从i到j,
- 二是从i经过若干个节点k到j。
所以,我们假设Dis(i,j)为节点u到节点v的最短路径的距离,对于每一个节点k,我们检查Dis(i,k) + Dis(k,j) < Dis(i,j)是否成立。 如果成立,证明从i到k再到j的路径比i直接到j的路径短,我们便设置Dis(i,j) = Dis(i,k) + Dis(k,j),这样一来,当我们遍历完所有节点k,Dis(i,j)中记录的便是i到j的最短路径的距离。

c语言实现
1 |
|
运行结果:

最小生成树
连通的无圈图叫作树,度为1的叫作叶子结点。
应用问题例子:欲修筑连接
Prim算法(以点为主,每次选择下一个中最小权重)
基本思想

例子:

Matlab实现:
1 | clc;clear; |
Kruskal算法(以边为主,每次选最小)
基本思想
将图的n个顶点看作n个分离的部分树,每个树具有一个顶点,算法的每一步就是选择连接两个分离树的具有最小权值的边,将两个树合二为一,直到只有一个树为止(进行n-1步)得到最小生成树。
例子:
我们使用边权矩阵进行存储数据,边权矩阵就是按列写入,每列由出发顶点、接收顶点和边的权值组成,如下所示:

1 | %边权矩阵,每一列都表示一条边,从上到下分别为两个顶点以及它们边的权值 |
网络最大流
何为最大流问题?
参考博客网络流——最大流(全)
Matlab实现
最大流问题(maximum flow problem),一种组合最优化问题,就是要讨论如何充分利用装置的能力,使得运输的流量最大,以取得最好的效果。管道网络中每条边的最大通过能力(容量)是有限的,实际流量不超过容量。
在数学建模的过程中时长会遇到这种问题,存在专门的算法去解决这一问题,但其实现较为复杂。
MATLAB提供了解决这一问题所使用的函数,即maxflow函数。
语法:
1 | mf = maxflow(G,s,t) |
符号说明:
- mf = maxflow(G,s,t) 返回节点 s 和 t 之间的最大流。如果图 G 未加权(即 G.Edges 不包含变量 Weight),则 maxflow 将所有图边的权重视为 1。
- mf = maxflow(G,s,t,algorithm) 指定要使用的最大流算法。此语法仅在 G 为有向图时可用。
- [mf,GF] = maxflow(___) 还使用上述语法中的任何输入参数返回有向图对象 GF。GF 仅使用 G 中具有非零流值的边构造。
- [mf,GF,cs,ct] = maxflow(___) 还返回源和目标节点 ID cs 和 ct,表示与最大流相关联的最小割。
创建并绘制一个加权图。加权边表示流量。
1 | s = [1 1 2 2 3 4 4 4 5 5]; |

确定节点1到6的最大流:
1 | mf = maxflow(G,1,6) |
结果:
1 |
|
Matlab图论工具箱
