1910072卢富毓无向图的连通度Word文件下载.docx
《1910072卢富毓无向图的连通度Word文件下载.docx》由会员分享,可在线阅读,更多相关《1910072卢富毓无向图的连通度Word文件下载.docx(20页珍藏版)》请在冰豆网上搜索。
实验日期:
2013-11-30
完成日期:
2013-11-30
学院:
数学与统计学院
专业:
信息与计算科学
年级:
2010级
一、实验目的
编程求解无向图边连通度,掌握网络流理论及其应用
二、实验环境
vs2010(C++)
三、实验内容
给定无向图G=(V,E),编程求解图G的边连通度
四、实验过程
A、预备知识
图的边连通度:
设G=(V,E)是一个图,称G的边连通度为k,如果G中不存在边数是k-1的边割集,是满足上述条件的最小正整数,记G的边连通度为k’(G)
定理3.6设G是一个图,k是正整数,称G是k-边连通的,如果k’(G)k
Menger定理:
设G=(V,E)为一个图,k是正整数,图G是k-边连通的iff对于V中任意两点u,v,在G中存在k条内部边不交的路。
应用2:
设G=(V,E)为一个无向图,s,t为G中固定顶点,k是固定正整数,如何在G中求出从s到t的k条内部边不交的无向图?
构造一个有向图D=(V,A),对G中的每一条边,在D中构造两条弧,取每条弧上的容量为1,利用最大流算法能够求得流量值为k的流f(如果最大流的流值至少为k),可以保证f为整数流。
B、标号法寻找网络最大流
用标号法寻找网络中最大流的基本思想是寻找可增广链,使网络的流量得以增加,直到最大为止(标号过程进行不下去,而收点vt尚未标号,说明不存在增广路,得到最大流)。
我采用的方法是从零流开始,再用标号法寻求最大流。
标号法主要分为两个步骤:
(1)标号过程
开始标号,初始化结点的结构体数组,然后标记vs为标号点并进行检查,此时其余都是未标号的点。
然后找到与vs有边相连的结点,标记那些点为标号而未检查的点。
取一个标号而未检查(Tag=marking)的点vi,对于一切未标号(Tag=n_mark)点vj:
A).对于弧(vi,vj),若fij<
cij,则给vj标号(vi,0),vj点成为标号而未检查的点。
B).对于弧(vi,vj),若fji>
0,则给vj标号(-vi,0),vj点成为标号而未检查的点。
然后找到下一个标号而未检查的点,重复上述步骤,一旦vt被标上号,表明得到一条从vi到vt的增广路径p,转入调整过程。
若所有标号都已检查过去,而标号过程进行不下去时,则算法结束,这时的可行流就是最大流。
(2)调整过程
从vt点开始,通过每个点的第一个标号,反向追踪(根据结点的From信息),可找出增广路P。
直到vs为止。
这时整个增广路径就找到了。
在上述找增广路径的同时计算调整值:
min{min(cij-fij),min(fij)}
C、算法运行结果如下:
五、实验总结
由于所求为边连通度,只需要根据最大流的算法加以改之就可以用来求边连通度,即将图中的容量改为1,然后求出来的每个顶点到其他任意顶点的最大流,进而所有的最大流中的最小值即为该图的边连通度。
只要掌握这个要点,那么边连通度就能轻易的求出来。
没有什么难度在里面。
六、源代码
//图的顶点结构如下:
//-----------------------------------
//|vex|formerNode|flowsDiff|mark|
//图的边的结构如下:
//----------------
//|weight|flows|
#include<
iostream>
string>
Windows.h>
usingnamespacestd;
#defineMax_vex100
#defineM1000
//SetTextC1是原来的颜色
//SetTextC2是设置的输出输入颜色
#defineSetTextC1SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE)
#defineSetTextC2SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN)
#defineSetTextC3SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN|FOREGROUND_BLUE)
#defineSetTextC4SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED)
#defineSetTextC5SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED|FOREGROUND_BLUE)
#defineSetTextC6SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE)
#defineSetTextC7SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_GREEN)
classArcll{//边上值
public:
doubleweight;
//容量
doubleflows;
//流量
};
enumMark{n_mark,marking,h_marked};
//分别代表没有标记,已经标记_未检查,已经标记_检查
classVex{//顶点值
stringvexs;
//顶点名称
stringformerVex;
doubleflowsDiff;
//流量的差值且最小
Markmark;
classGraphics{//创建一个图的类
private:
intvexnum;
//顶点数
intarcnum;
//边数
Vexvexs[Max_vex];
//存储定点名称
Arcllarcs[Max_vex][Max_vex];
voidCreateGraphics(Graphics&
G);
//创建一个图
intLocateIndex(GraphicsG,stringv);
//寻找下标
doubleMark_getMaxstream(Graphics&
G,intp,intq);
boolMark_FindMaxstream(Graphics&
//标号法寻找最大流
boolMark_Node(Graphics&
G,inti);
//标记的方法
intCheckMarkNode(Graphics&
voidConnectedDegree(Graphics&
//方法实现
//找到相应顶点的下标
intGraphics:
:
LocateIndex(GraphicsG,stringv){
inti=0;
for(i=0;
i<
G.vexnum;
i++){
if(G.vexs[i]pare(v)==0){
returni;
}
}
return-1;
}
//创建一个有向图
voidGraphics:
CreateGraphics(Graphics&
G){
inti,j,k;
stringVi,Vj;
SetTextC1;
cout<
<
"
-------------------------创建无向图的存储-------------------------------"
endl;
请输入顶点数:
;
SetTextC4;
//设置颜色
cin>
>
//设置颜色
请输入图的边数:
G.arcnum;
请输入顶点名:
i++){//初始化顶点
cin>
G.vexs[i].vexs;
i++){//初始化边
for(j=0;
j<
j++){
G.arcs[i][j].weight=M;
G.arcs[i][j].flows=-1;
for(k=0;
k<
k++){
cout<
请输入第"
k+1<
条边相连的顶点Vi,Vj:
SetTextC4;
Vi>
Vj;
SetTextC1;
i=LocateIndex(G,Vi);
j=LocateIndex(G,Vj);
if(i==-1||j==-1){
cout<
输入错误!
请检查..."
return;
G.arcs[i][j].weight=1;
//将一条边(i,j)分解成两条弧(i,j)(j,i)
G.arcs[i][j].flows=0;
G.arcs[j][i].weight=1;
G.arcs[j][i].flows=0;
各顶点的关系:
SetTextC2;
i++){
if(i==0){
\t\t"
G.vexs[i].vexs<
"
}else{
\t"
SetTextC3;
SetTextC2;
SetTextC3;
if(G.arcs[i][j].weight==M){
SetTextC6;
cout<