没有合适的资源?快使用搜索试试~ 我知道了~
首页Matlab版prim Kruskal算法实现文档
资源详情
资源评论
资源推荐

《计算机仿真》期末大作业
Prim 算法和 Kruskal 算法的 Matlab 实现
05605 刘禹 050697(30)
连线问题应用举例:
欲铺设连接 个城市的高速公路,若 城与 城之间的高速公路造价为 ,试
设计一个线路图,使总的造价最低。
连线问题的数学模型就是图论中在连通的赋权图上求权最小的支撑树。试用
Matlab 分别实现求最小支撑数的 Prim 算法和 Krusal 算法(避圈法)。
一.基本要求:
(1) 画出程序流程图;
(2) 对关键算法、变量和步骤进行解释说明;
(3) 用如下两图对所写算法的正确性进行验证。即输入图的信息,输出对应图
的最小支撑树及其权值。
(4)分析两种算法的实现复杂度。
二.扩展要求:
(1)提供对算法效率(复杂度)进行评估的方法,并通过举例验证,与分析得到的算
法复杂度结果相对照;
(2)从降低内存消耗、减少计算时间的角度,对算法进行优化。
三.实验步骤
I.用 Prim 算法求最小生成树
i.算法分析及需求分析,程序设计
prim 算法的基本思想是:设 G=(V,E)是一个无向连通网,令 T=(U,TE)是 G 的
最小生成树。T 的初始状态为 U={v0}(v0 )TE={},然后重复执行下述操作:在所有 u
U,
v V-U 的边中找一条代价最小的边(u,v)并入集合 TE,同时 v 并入 U,直至 U=V
1 / 14

为止。
显然,Prim 算法的基本思想是以局部最优化谋求全局的最优化,而且,还涉及到起始
结点的问题。
本程序完成的功能是:从图中的任意结点出发,都能够找出最小生成树
实现方案分析:
Prim 算法的关键是如何找到连接 U 和 V-U 的最短边来扩充生成树 T。设当前 T 中有 k
个点(即 T 的顶点集 U 中有 k 个顶点)则所有满足 u U,v V-U 的边最多有 k 条,
从如此大的边集中选取最短边是不太经济的。利用 MST 性质,可以用下述方法构造候选最
小边集:对应 V-U 中的每个顶点,保留从该顶点到 U 中的各顶点的最短边,取候选边最短
边集为 V-U 中的 n-k 个顶点所关联的 n-k 条最短边的集合。为表示候选最短边集,需设置两
个一维数组 lowcost[n]和 adjvex[n],其中 lowcost 用来保存集合 V-U 中的各顶点与集合 U 中
顶点的最短边的权值,lowcost[v]=0 表示顶点 v 已经加入最小生成树中;adjvex 用来保存依
附于该边在集合 U 中的顶点。例如下式表明顶点 和顶点 之间的权值为 w
lowcost[i]=w;
adjvex[i]=k;
程序流程图
关键代码说明:
1. 将用于验证算法正确性的两幅图用邻接矩阵的形式保存,分别保存为文件
Graph1.m,Graph2.m ( 注 : 矩 阵 的 对 角 线 元 素 设 置 为 零 。 ) 并 在 主 程 序
finallyprim 中直接进行调用。
2 / 14

2. 在输入起点时应该给程序的阅读者就该图的顶点数作出提示,不然的话使用
者很可能会输入越界下标。采取的方法如下
len=length(graph_adjacent);%求图中有多少个顶点
k=sprintf('please input the point where you want to start ,do remember it must be
between 1 and %d ',len);
start_point=input(k);%输入最小生成树产生起点
采取了 sprintf 格式化字符串的方法,就避免了编程的人每次根据输入图的顶
点
数手动对提示作修改。效果如下:
在对第一幅图进行算法验证时在 workspace 会如下输出:
please input the point where you want to start ,do remember it must be between 1
and 7
在对第二幅图进行算法验证时在 workspace 会有如下输出:
please input the point where you want to start ,do remember it must be between 1
and 8
3. 在输出结果时为了使结果在 workspace 中输出的清晰,使人一目了然,也使
用了 sprintf 格式化字符串的方法,代码如下
s=0;
for ii=1:len-1
k=sprintf(' 最 小 生 成 树 第 %d 条 边 : ( %d,%d ) , 权 值
为%d',ii,tree(ii,1),tree(ii,2),graph_adjacent(tree(ii,1),tree(ii,2)));
disp(k);
disp(' ');
s=s+graph_adjacent(tree(ii,1),tree(ii,2));
end
disp('最小生成树的总代价为:')
disp(s);
4. 下面对算法的核心部分进行说明:
在 len-1 次循环中,每次循环要完成以下三项工作
1.找到最小边,(需要求 lowcost 数组的最小非零值,因为 0 表示该边已经被
加入到了最小生成树中)
由于是求非零的最小值,就不能在直接用 min 函数了。我采取的方法是这
样的:
k=lowcost>0;%k 为一逻辑数组,它和 lowcost 同维,对于每一个位
% 置 i 如果 lowcost(i)>0 则 k(i)=1
%否则 k(i)=0;稍候将用这个数组进行辅助寻址
3 / 14
剩余13页未读,继续阅读

















安全验证
文档复制为VIP权益,开通VIP直接复制

评论6