- 在线时间
- 2759 小时
- 最后登录
- 2017-9-15
- 注册时间
- 2011-4-3
- 听众数
- 538
- 收听数
- 4
- 能力
- 80 分
- 体力
- 1764 点
- 威望
- 27 点
- 阅读权限
- 150
- 积分
- 5990
- 相册
- 0
- 日志
- 0
- 记录
- 5
- 帖子
- 6675
- 主题
- 3503
- 精华
- 8
- 分享
- 6
- 好友
- 1721
TA的每日心情 | 开心 2017-2-7 15:12 |
---|
签到天数: 691 天 [LV.9]以坛为家II
群组: 2013年国赛赛前培训 群组: 2014年地区赛数学建模 群组: 数学中国第二期SAS培训 群组: 物联网工程师考试 群组: 2013年美赛优秀论文解 |
贪婪算法是应用最广泛,最广泛的算法,没有之一,所以永远不朽,人人都有贪婪之心,所以这个算法一定程度上说相对较好理解同样也非常重要,下面继续拓展一些,站在数据结构上面继续做些介绍。
程序13-6 Kruskal算法所需要的数据类型
template <class T>
class EdgeNode {
p u b l i c :
operator T() const {return weight;}
p r i v a t e :
T weight;//边的高度
int u, v;//边的端点
} ;
为了更简单地使用查找和合并策略,定义了U n i o n F i n d类,它的构造函数是程序8 - 1 6的初始化函数,U n i o n是程序8 - 1 6的加权合并函数,F i n d是程序8 - 1 7的路径压缩搜索函数。
为了编写与网络描述无关的代码,还定义了一个新的类U N e t Wo r k,它包含了应用于无向网络的所有函数。这个类与U n d i r e c t e d类的差别在于U n d i r e c t e d类中的函数不要求加权边,而U N e t Wo r k要求边必须带有权值。U N e t Wo r k中的成员需要利用N e t w o r k类中定义的诸如B e g i n和N e x t Ve r t e x的遍历函数。不过,新的遍历函数不仅需要返回下一个邻接的顶点,而且要返回到达这个顶点的边的权值。这些遍历函数以及有向和无向加权网络的其他函数一起构成了W 、
N e t w o r k类(见程序1 3 - 7)。
程序13-7 WNetwork类
template<class T>
class WNetwork : virtual public Network
{
public :
virtual void First(int i, int& j, T& c)=0;
virtual void Next(int i, int& j, T& c)=0;
} ;
象B e g i n和N e x t Ve r t e x一样,可在A d j a c e n c y W D i g r a p
h及L i n k e d W D i g r a p h类中加入函数F i r s t与N e x t。现在A d j a c e
n c y W D i g r a p h及L i n k e d W D i g r a p h类都需要从W N e t Wo r
k中派生而来。由于A d j a c e n c y W G r a p h类和L i n k e d W G r a p
h类需要访问U N e t w o r k的成员,所以这两个类还必须从U N e t Wo r k中派生而来。U N e t Wo
r k : : K r u s k a l的代码见程序1 3 - 8,它要求将Edges() 定义为N e t Work
类的虚成员,并且把U N e t Wo r k定义为E d g e N o d e的友元)。如果没有生成树,函数返回f a l s
e,否则返回t r u e。注意当返回true 时,在数组t 中返回最小耗费生成树。
程序13-8 Kr u s k a l算法的C + +代码
template<class T>
bool UNetwork<T>::Kruskal(EdgeNode<T> t[])
{// 使用K r u s k a l算法寻找最小耗费生成树
// 如果不连通则返回false
// 如果连通,则在t [ 0 : n - 2 ]中返回最小生成树
int n = Ve r t i c e s ( ) ;
int e = Edges();
/ /设置网络边的数组
InitializePos(); // 图遍历器
EdgeNode<T> *E = new EdgeNode<T> [e+1];
int k = 0; // E的游标
for (int i = 1; i <= n; i++) { // 使所有边附属于i
int j;
T c;
First(i, j, c);
while (j) { // j 邻接自i
if (i < j) {// 添加到达E的边
E[++k].weight = c;
E[k].u = i;
E[k].v = j;}
Next(i, j, c);
}
}
// 把边放入最小堆
MinHeap<EdgeNode<T> > H(1);
H.Initialize(E, e, e);
UnionFind U(n); // 合并/搜索结构
// 根据耗费的次序来抽取边
k = 0; // 此时作为t的游标
while (e && k < n - 1) {
// 生成树未完成,尚有剩余边
EdgeNode<T> x;
H.DeleteMin(x); // 最小耗费边
e - - ;
int a = U.Find(x.u);
int b = U.Find(x.v);
if (a != b) {// 选择边
t[k++] = x;
U . U n i o n ( a , b ) ; }
}
D e a c t i v a t e P o s ( ) ;
H . D e a c t i v a t e ( ) ;
return (k == n - 1);
}
2. Prim算法
与Kr u s k a l算法类似,P r i m算法通过每次选择多条边来创建最小生成树。选择下一条边的贪婪准则是:从剩余的边中,选择一条耗费最小的边,并且它的加入应使所有入选的边仍是一棵树。最终,在所有步骤中选择的边形成一棵树。相反,在Kruskal 算法中所有入选的边集合最终形成一个森林。
P r i m算法从具有一个单一顶点的树T开始,这个顶点可以是原图中任意一个顶点。然后往T中加入一条代价最小的边( u , v)使TÈ{ (u , v) }仍是一棵树,这种加边的步骤反复循环直到T中包含n- 1条边。注意对于边( u , v),u、v 中正好有一个顶点位于T中。P r i m算法的伪代码如图1 -14所示。在伪代码中也包含了所输入的图不是连通图的可能,在这种情况下没有生成树。图1 - 1 5显示了对图1-12a 使用P r i m算法的过程。把图1 - 1 4的伪代码细化为C + +程序及其正确性的证明留作练习(练习3 1)。
/ /假设网络中至少具有一个顶点
设T为所选择的边的集合,初始化T=
设T V为已在树中的顶点的集合,置T V= { 1 }
令E为网络中边的集合 w h i l e(E< > ) & & (| T | < > n-1) {
令(u , v)为最小代价边,其中u T V, v T V
i f(没有这种边) b re a k
E=E- { (u,v) } / /从E中删除此边
在T中加入边( u , v)
}
if (| T | = =n- 1 ) T是一棵最小生成树
else 网络是不连通的,没有最小生成树
图13-14 Prim最小生成树算法
如果根据每个不在T V中的顶点v 选择一个顶点n e ar (v),使得n e ar (v) Î TV 且c o st (v, n
e ar (v) )的值是所有这样的n e ar (v) 节点中最小的,则实现P r i m算法的时间复杂性为O (n2 )。下一条添加到T中的边是这样的边:其cost (v, near (v)) 最小,且v T V。
3. Sollin算法
S o l l i n算法每步选择若干条边。在每步开始时,所选择的边及图中的n个顶点形成一个生成树的森林。在每一步中为森林中的每棵树选择一条边,这条边刚好有一个顶点在树中且边的代价最小。将所选择的边加入要创建的生成树中。注意一个森林中的两棵树可选择同一条边,因此必须多次复制同一条边。当有多条边具有相同的耗费时,两棵树可选择与它们相连的不同的边,在这种情况下,必须丢弃其中的一条边。开始时,所选择的边的集合为空。若某一步结束时仅剩下一棵树或没有剩余的边可供选择时算法终止。
图1 - 6给出了初始状态为图1-12a 时,使用S o l l i n算法的步骤。初始入选边数为0时的情形如图13-12a 时,森林中的每棵树均是单个顶点。顶点1,2,.,7所选择的边分别是(1.6), (2,7),(3,4), (4,3), (5,4),
(6,1), (7,2),其中不同的边是( 1 , 6 ),( 2 , 7 ),(3,4) 和( 5 , 4 ),将这些边加入入选边的集合后所得到的结果如图1 3 - 1 6 a所示。下一步具有顶点集{ 1 , 6 }的树选择边( 6 , 5 ),剩下的两棵树选择边( 2 , 3 ),加入这两条边后已形成一棵生成树,构建好的生成树见图1 3 - 6 b。S o l l i n算法的C + +程序实现及其正确性证明留作练习(练习3 2 )。
|
|