数学建模——图论

适用对象

图论是为了解决包含二元关系的离散系统所提出的数学模型,并可对该模型进行求解。
基本问题:

  1. 最短路问题
  2. 最大流问题
  3. 最小费用流问题
  4. 匹配问题

基本理论

1. 图

无向图有向图
元素无序对集合
G = ( V , E ) G=(V,E) G=(V,E)
顶点集&边集
有序对集合
G = ( V , A ) G=(V,A) G=(V,A)
顶点集&弧集

顶点数: ∣ V ∣ |V| V \qquad 边数: ∣ E ∣ |E| E

顶点的度:与顶点关联的边数,记作 d ( v ) d(v) d(v)

相关结论:

  1. ∑ v ∈ V d ( v ) = 2 ϵ \sum_{v\in V}d(v)=2\epsilon vVd(v)=2ϵ
  2. 任意一个图的奇顶点的个数是偶数

计算机描述图与网络的表示方法

  1. 邻接矩阵表示法
  2. 关联矩阵表示法
  3. 弧表表示法
  4. 邻接表表示
  5. 星形表示法

相关补充:

链表:
物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的
比如有其他大神写的:
什么是链表——武培轩


2. 树——T

连通的无圈图称之为树,若 G G G 满足 V ( G ) = V ( T ) , E ( T ) ⊂ E ( G ) V(G) = V(T), E(T)\subset E(G) V(G)=V(T),E(T)E(G)
顶点相同,边包含


经典算法

求最短路:迪克斯特拉算法

基本思想:
按按距 u 0 u_0 u0 从近到远为顺序,依次求得 u 0 u_0 u0 G G G 的各顶点的最短路和距离,直至 v 0 v_0 v0 (或直至 G G G 的所有顶点),算法结束。

例:根据从 c i c_i ci c j c_j cj 的航程票价矩阵
[ 0 50 ∞ 40 25 10 50 0 15 20 ∞ 25 ∞ 15 0 10 20 ∞ 40 20 10 0 10 25 25 ∞ 20 10 0 25 10 25 ∞ 25 55 0 ] \begin{bmatrix} 0 & 50 & \infty & 40 & 25 & 10 \\ 50 & 0 &15 & 20 & \infty & 25 \\ \infty & 15 & 0 & 10 & 20 & \infty \\ 40 & 20 & 10 & 0 & 10 & 25 \\ 25 & \infty & 20 &10 & 0 & 25 \\ 10 & 25 & \infty & 25 & 55 & 0 \end{bmatrix} 050402510500152025150102040201001025252010055102525250求第一个城市到其它城市的最短路径的Matlab程序如下:

% 变量说明
% pb:P标号信息,1:已标号;0:未标号	
% index1:标号顶点顺序	index2:存放起始点到第i顶点前一顶点的序号	
% d:最短通路的值

clc,clear
%构造初始票价矩阵
a=zeros(6);
a(1,2)=50;a(1,4)=40;a(1,5)=25;a(1,6)=10;
a(2,3)=15;a(2,4)=20;a(2,6)=25;
a(3,4)=10;a(3,5)=20;
a(4,5)=10;a(4,6)=25;
a(5,6)=55;
a=a+a';
a(a==0)=inf;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% 将第一座城市标1,其余标0
pb(1:length(a))=0;
pb(1)=1;

% 将顶点1写入路径集合S
index1=1;

% 路径从起始点至i点时,i点前一顶点的序号
index2=ones(1,length(a));

% d(i)为所求路径距离,初始值:起始点为0,其余置无穷
d(1:length(a))=inf;
d(1)=0;

temp=1;

% 遍历所有的点
while sum(pb)<length(a)
	tb=find(pb==0);								% 找到标号为0的点
	% 更新距离,取原来的距离与经标记点距离的最小值
	d(tb)=min(d(tb),d(temp)+a(temp,tb));	
	tmpb=find(d(tb)==min(d(tb)));				% 求d(tb)数列最小值的下标
	% temp:下一个点,empb可能为数列,取其中第一个
	temp=tb(tmpb(1));							
	pb(temp)=1;									% 将所找点标记为1
	% 将之前找到的最小路径终点标号存入集合S
	index1=[index1,temp];						
	% 对下两行意义理解不是很深刻
	temp2=find(d(index1)==d(temp)-a(temp,index1));
	index2(temp)=index1(temp2(1));
end
d, index1, index2


通用算法封装成函数如下:
function [mydistance,mypath]=dijkstra(a, sb, db);
% 输入:a—邻接矩阵(aij)是指i到j之间的距离,可以是有向的
% sb—起点的标号, db—终点的标号
% 输出:mydistance—最短路的距离, mypath—最短路的路径

n=size(a,1);
visited(1:n) = 0;		% 是否被访问,1-访问,0-未访问
distance(1:n) = inf; 	% 保存起点到各顶点的最短距离
distance(begin) = 0; 
parent(1:n) = 0;

for i = 1: n-1
	temp=distance;
	id1=find(visited==1); 	%查找已经标号的点
	temp(id1)=inf; 			%已标号点的距离换成无穷
	[t, u] = min(temp); 	%找标号值最小的顶点,t-最小值,u-索引
	visited(u) = 1; 		%标记已经标号的顶点
	id2=find(visited==0); 	%查找未标号的顶点
	for v = id2
		if a(u, v) + distance(u) < distance(v)
			distance(v) = distance(u) + a(u, v); %修改标号值
			parent(v) = u;
		end
	end
end
mypath = [];
if parent(db) ~= 0 %如果存在路!
	t = db; mypath = [db];
	while t ~= sb
		p = parent(t);
		mypath = [p mypath];
		t = p;
	end
end
mydistance = distance(db);
return

求最短路 弗洛伊德算法

可以解决任意两点间的最短路径问题(一次性计算出),可以正确处理无向图或有向图(可以有负权重,但不可存在负权回路)的最短路径问题。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

清上尘

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值