没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
图论算法及其 MATLAB 程序代码
求赋权图 G = (V, E , F )中任意两点间的最短路的 Warshall-Floyd 算法:
设 A = (a
ij
)
n
×
n
为赋权图 G = (V, E , F )的矩阵, 当 v
i
v
j
∈E 时 a
ij
= F (v
i
v
j
), 否则取 a
ii
=0, a
ij
= +∞(i≠j ), d
ij
表示从 v
i
到 v
j
点的距离, r
ij
表示从 v
i
到 v
j
点的最短路中一个点的编号.
① 赋初值. 对所有 i, j, d
ij
= a
ij
, r
ij
= j. k = 1. 转向②
② 更新 d
ij
, r
ij
. 对所有 i, j, 若 d
ik
+ d
k j
<d
ij
, 则令 d
ij
= d
ik
+ d
k j
, r
ij
= k, 转向③.
③ 终止判断. 若 d
ii
<0, 则存在一条含有顶点 v
i
的负回路, 终止; 或者 k = n 终止; 否则
令 k = k + 1, 转向②.
最短路线可由 r
ij
得到.
例 1 求图 6-4 中任意两点间的最短路.
解:用 Warshall-Floyd 算法, MATLAB 程序代码如下:
n=8;A=[0 2 8 1 Inf Inf Inf Inf
2 0 6 Inf 1 Inf Inf Inf
8 6 0 7 5 1 2 Inf
1 Inf 7 0 Inf Inf 9 Inf
Inf 1 5 Inf 0 3 Inf 8
Inf Inf 1 Inf 3 0 4 6
Inf Inf 2 9 Inf 4 0 3
Inf Inf Inf Inf 8 6 3 0]; % MATLAB 中, Inf 表示∞
D=A; %赋初值
for(i=1:n)for(j=1:n)R(i,j)=j;end;end %赋路径初值
for(k=1:n)for(i=1:n)for(j=1:n)if(D(i,k)+D(k,j)<D(i,j))D(i,j)=D(i,k)+D(k,j); %更新 dij
R(i,j)=k;end;end;end %更新 rij
k %显示迭代步数
D %显示每步迭代后的路长
R %显示每步迭代后的路径
pd=0;for i=1:n %含有负权时
if(D(i,i)<0)pd=1;break;end;end %存在一条含有顶点 vi 的负回路
if(pd)break;end %存在一条负回路, 终止程序
end %程序结束
图 6-4
Kruskal 避圈法:将图 G 中的边按权数从小到大逐条考察, 按不构成圈的原则加入到 T
中(若有选择时, 不同的选择可能会导致最后生成树的权数不同), 直到 q (T ) = p (G ) − 1 为
止, 即 T 的边数= G 的顶点数− 1 为止.
Kruskal 避圈法的 MATLAB 程序代码如下:
n=8;A=[0 2 8 1 0 0 0 0
2 0 6 0 1 0 0 0
8 6 0 7 5 1 2 0
1 0 7 0 0 0 9 0
0 1 5 0 0 3 0 8
0 0 1 0 3 0 4 6
0 0 2 9 0 4 0 3
0 0 0 0 8 6 3 0];
k=1; %记录 A 中不同正数的个数
for(i=1:n-1)for(j=i+1:n) %此循环是查找 A 中所有不同的正数
if(A(i,j)>0)x(k)=A(i,j); %数组 x 记录 A 中不同的正数
kk=1; %临时变量
for(s=1:k-1)if(x(k)==x(s))kk=0;break;end;end %排除相同的正数
k=k+kk;end;end;end
k=k-1 %显示 A 中所有不同正数的个数
for(i=1:k-1)for(j=i+1:k) %将 x 中不同的正数从小到大排序
if(x(j)<x(i))xx=x(j);x(j)=x(i);x(i)=xx;end;end;end
T(n,n)=0; %将矩阵 T 中所有的元素赋值为 0
q=0; %记录加入到树 T 中的边数
for(s=1:k)if(q==n)break;end %获得最小生成树 T, 算法终止
for(i=1:n-1)for(j=i+1:n)if (A(i,j)==x(s))T(i,j)=x(s);T(j,i)=x(s); %加入边到树 T 中
TT=T; %临时记录 T
while(1)pd=1; %砍掉 TT 中所有的树枝
for(y=1:n)kk=0;
for(z=1:n)if(TT(y,z)>0)kk=kk+1;zz=z;end;end %寻找 TT 中的树枝
if(kk==1)TT(y,zz)=0;TT(zz,y)=0;pd=0;end;end %砍掉 TT 中的树枝
if(pd)break;end;end %已砍掉了 TT 中所有的树枝
pd=0; %判断 TT 中是否有圈
for(y=1:n-1)for(z=y+1:n)if(TT(y,z)>0)pd=1;break;end;end;end
if(pd)T(i,j)=0;T(j,i)=0; %假如 TT 中有圈
else q=q+1;end;end;end;end;end
T %显示近似最小生成树 T, 程序结束
求二部图 G 的最大匹配的算法(匈牙利算法), 其基本思想是:从 G 的任意匹配 M 开始,
对 X 中所有 M 的非饱和点, 寻找 M −增广路. 若不存在 M −增广路, 则 M 为最大匹配; 若存
在 M −增广路 P, 则将 P 中 M 与非 M 的边互换得到比 M 多一边的匹配 M
1
, 再对 M
1
重复上
述过程.
设 G = ( X, Y, E )为二部图, 其中 X = {x
1
, x
2
, … , x
n
}, Y = { y
1
, y
2
, … , y
n
}. 任取 G 的一初
始匹配 M (如任取 e∈E, 则 M = {e}是一个匹配).
① 令 S = φ , T = φ , 转向②.
② 若 M 饱和 X \ S的所有点, 则 M 是二部图 G 的最大匹配. 否则, 任取 M 的非饱和点
u∈X \ S , 令 S = S ∪{ u }, 转向③.
③ 记 N (S ) = {v | u∈S, uv∈E
}. 若 N (S ) = T, 转向②. 否则取 y∈N (S ) \ T. 若 y 是 M
的饱和点, 转向④, 否则转向⑤.
④ 设 x y∈M, 则令 S = S ∪{ x }, T = T ∪{ y }, 转向③.
⑤ u − y 路是 M−增广路, 设为 P, 并令 M = M⊕P, 转向①. 这里 M⊕P = M∪P \ M∩
P, 是对称差.
由于计算 M−增广路 P 比较麻烦, 因此将迭代步骤改为:
① 将 X 中 M 的所有非饱和点(不是 M 中某条边的端点)都给以标号 0 和标记*, 转向②.
② 若 X 中所有有标号的点都已去掉了标记*, 则 M 是 G 的最大匹配. 否则任取 X 中一
个既有标号又有标记*的点 x
i
, 去掉 x
i
的标记*, 转向③.
③ 找出在 G 中所有与 x
i
邻接的点 y
j
(即 x
i
y
j
∈E ), 若所有这样的 y
j
都已有标号, 则转向
②, 否则转向④.
④ 对与x
i
邻接且尚未给标号的y
j
都给定标号i. 若所有的y
j
都是M的饱和点, 则转向⑤,
否则逆向返回. 即由其中 M的任一个非饱和点y
j
的标号i找到x
i
, 再由x
i
的标号k 找到y
k
, … ,
最后由 y
t
的标号 s 找到标号为 0 的 x
s
时结束, 获得M −增广路 x
s
y
t
… x
i
y
j
, 记P = {x
s
y
t
, … ,
x
i
y
j
}, 重新记 M 为 M⊕P, 转向①.
⑤ 将 y
j
在 M 中与之邻接的点 x
k
(即 x
k
y
j
∈M), 给以标号 j 和标记*, 转向②.
剩余11页未读,继续阅读
资源评论
YEYEYEYE318
- 粉丝: 0
- 资源: 1
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- HandTrackingModule.py
- Python基于卷积神经网络的鸟类识别项目源代码,ipynb文件
- 批量将py编译为pyd文件.atbx
- Python项目-学生管理系统
- 图像处理基于matlab图像RGB三色合成分离【含Matlab源码第1发】
- verilog HDL硬件语法设计包括算术运算三人表决器Verilog的阻塞和非阻塞赋值源码例程quartus13.1工程合集
- 【文章话题分类论文】OpenAlex Topic Classification Whitepaper
- linux学习常用命令
- 功率拓扑快速参考指南-ti,TI官方出品
- 开源2023电赛国赛运动目标控制(E题)视觉部分
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功