网络最大流.docx
- 文档编号:23689146
- 上传时间:2023-05-19
- 格式:DOCX
- 页数:18
- 大小:169.38KB
网络最大流.docx
《网络最大流.docx》由会员分享,可在线阅读,更多相关《网络最大流.docx(18页珍藏版)》请在冰豆网上搜索。
网络最大流
云南大学数学与统计学实验教学中心
实验报告
课程名称:
运筹学实验
学期:
2012~2013学年第二学期
成绩:
指导教师:
葛瑜
学生姓名:
卢富毓
学生学号:
20101910072
实验名称:
最大流
实验要求:
必做
实验学时:
2学时
实验编号:
07
实验日期:
2013/4/30
完成日期:
2013/5/24
学院:
数学与统计学院
专业:
信息与计算科学
年级:
2010级
一、实验目的
编制程序,在赋权图中找到从发点Vs到收点Vt的最大流,并输出最大流.
二、实验环境
VS2010(C++)
三、实验内容
P272
例14:
用标号法求图10-25所示网络的最大流,弧旁的数是
四、实验过程
A、将上面算法编写实现运行结果如下图:
用标号法寻找网络中最大流的基本思想是寻找可增广链,使网络的流量得以增加,直到最大为止(标号过程进行不下去,而收点vt尚未标号,说明不存在增广路,得到最大流)。
我采用的方法是从零流开始,再用标号法寻求最大流。
标号法主要分为两个步骤:
(1)标号过程
开始标号,初始化结点的结构体数组,然后标记vs为标号点并进行检查,此时其余都是未标号的点。
然后找到与vs有边相连的结点,标记那些点为标号而未检查的点。
取一个标号而未检查(Tag=marking)的点vi,对于一切未标号(Tag=n_mark)的点vj:
A).对于弧(vi,vj),若fij B).对于弧(vi,vj),若fji>0,则给vj标号(-vi,0),vj点成为标号而未检查的点。 然后找到下一个标号而未检查的点,重复上述步骤,一旦vt被标上号,表明得到一条从vi到vt的增广路径p,转入调整过程。 若所有标号都已检查过去,而标号过程进行不下去时,则算法结束,这时的可行流就是最大流。 (2)调整过程 从vt点开始,通过每个点的第一个标号,反向追踪(根据结点的From信息),可找出增广路P。 直到vs为止。 这时整个增广路径就找到了。 在上述找增广路径的同时计算调整值: min{min(cij-fij),min(fij)} a、初始化结果: 输入的结果为红色字体 b、初始化后的到结果: 红框中得到的图的关系与课本例题中的一样! 所以创建图形正确! c、最后得到的结果: 6x6的矩阵中,每一行中紫色表示的是有边相连的顶点。 其中的两个值,第一个代表的是容量,第二个值代表的是流量。 得到的结果与课本中例题的结果一致。 所以编写的程序正确。 五、实验总结 通过编程来实现的时候,发现手工做的话容易实现,同时在手工做的时候容易忽略一些细节性的东西。 而通过编程来实现的话需要把一些忽略的细节重视起来。 同时有了前面两个实验的铺垫,这个实验实现起来也是得心应手的。 六、源代码 源代码如下: //图的顶点结构如下: //----------------------------------- //|vex|formerNode|flowsDiff|mark| //----------------------------------- //图的边的结构如下: //---------------- //|weight|flows| //---------------- #include #include #include 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{//顶点值 public: stringvexs;//顶点名称 stringformerVex; doubleflowsDiff;//流量的差值且最小 Markmark; }; classGraphics{//创建一个图的类 private: intvexnum;//顶点数 intarcnum;//边数 Vexvexs[Max_vex];//存储定点名称 Arcllarcs[Max_vex][Max_vex];//边数 public: voidCreateGraphics(Graphics&G);//创建一个图 intLocateIndex(GraphicsG,stringv);//寻找下标 voidMark_getMaxstream(Graphics&G); boolMark_FindMaxstream(Graphics&G);//标号法寻找最大流 boolMark_Node(Graphics&G,inti);//标记的方法 intCheckMarkNode(Graphics&G,inti); }; //方法实现 //找到相应顶点的下标 intGraphics: : LocateIndex(GraphicsG,stringv){ inti=0; for(i=0;i if(G.vexs[i]pare(v)==0){ returni; } } return-1; } //创建一个有向图 voidGraphics: : CreateGraphics(Graphics&G){ inti,j,k; stringVi,Vj; doublew,f;//容量、流量 SetTextC1; cout<<"-------------------------创建有向图的存储-------------------------------"< cout<<"请输入顶点数: "; SetTextC4;//设置颜色 cin>>G.vexnum; SetTextC1;//设置颜色 cout<<"请输入图的边数: "; SetTextC4; cin>>G.arcnum; SetTextC1; cout<<"请输入顶点名: "; SetTextC4; for(i=0;i cin>>G.vexs[i].vexs; G.vexs[i].formerVex=""; G.vexs[i].mark=n_mark; } SetTextC1; for(i=0;i for(j=0;j G.arcs[i][j].weight=M; G.arcs[i][j].flows=-1; } } for(k=0;k cout<<"请输入第"< "; SetTextC4; cin>>Vi>>Vj>>w>>f; SetTextC1; i=LocateIndex(G,Vi); j=LocateIndex(G,Vj); if(i==-1||j==-1){ cout<<"输入错误! 请检查..."< return; } G.arcs[i][j].weight=w; G.arcs[i][j].flows=f; } cout< cout<<"各顶点的关系: "< SetTextC2; for(i=0;i if(i==0){ cout<<"\t\t"< }else{ cout<<"\t"< } } cout< SetTextC3; for(i=0;i SetTextC2; cout<<"\t"< SetTextC3; for(j=0;j if(G.arcs[i][j].weight==M){ SetTextC6; cout<<"\t"<<" SetTextC3; }else{ cout<<"\t<"< } } cout< } SetTextC1; cout< "< } //-------------------------标号法寻找最大流------------------------- voidGraphics: : Mark_getMaxstream(Graphics&G){ boolb=true; inti,j; G.CreateGraphics(G);//创建图的存储结构 cout<<"-------------------------标号法寻找最大流-------------------------------"< while(b){ b=Mark_FindMaxstream(G); if(! b){ break; } cout<<"调整后: "< SetTextC2; for(i=0;i if(i==0){ cout<<"\t\t"< }else{ cout<<"\t"< } } cout< SetTextC3; for(i=0;i SetTextC2; cout<<"\t"< SetTextC3; for(j=0;j if(G.arcs[i][j].weight==M){ SetTextC6; cout<<"\t"<<" SetTextC3; }else{ cout<<"\t<"< } } cout< } SetTextC1; } if(! b){ cout<<"找到了! 最后结果为: "< SetTextC2; for(i=0;i if(i==0){ cout<<"\t\t"< }else{ cout<<"\t"< } } cout< SetTextC3; for(i=0;i SetTextC2; cout<<"\t"< SetTextC5; for(j=0;j if(G.arcs[i][j].weight==M){ SetTextC6; cout<<"\t"<<" SetTextC5; }else{ cout<<"\t<"< } } cout< } SetTextC1; } } boolGraphics: : Mark_FindMaxstream(Graphics&G){ inti,j,k,x; doubledis; boolboolean=false; //step1找到vs,并对与其相连的顶点标记 i=G.LocateIndex(G,"vs");//找到顶点vs G.vexs[i].flowsDiff=M; G.vexs[i].mark=h_marked; boolean=G.Mark_Node(G,i);//标记顶点 if(! boolean){ cout<<"没有找到增广链"< returnfalse; } //step2从标记的点中找已标记未检查的点 i=0; j=0; while(G.vexs[i]pare("vt")! =0&&G.vexs[i].mark! =n_mark){//当vt找到且有标记时停止 if(G.vexs[i].mark==marking){ x=0; G.vexs[i].mark=h_marked;//代表已经检查 G.Mark_Node(G,i);//标记从当前点出发的未标记的点 k=G.CheckMarkNode(G,i);//检查: 已标记未检查的点进行h_marked标记并返回i if(k==i){ //cout<<"k==i出错"< for(j=0;j if(G.vexs[j].mark==marking){ x=x+1; break; } } if(x==1){ i=x; }else{ cout<<"k==i出错"< returnfalse; } }else{ i=k; } } if(j==G.vexnum){//找完所有点也不满足条件时停止 i=i+1; } j++; } //step3路径值调整 i=G.LocateIndex(G,"vt"); dis=G.vexs[i].flowsDiff;//得到vt的流量差 stringforvex; stringforvex1; while(G.vexs[i]pare("vs")! =0){//当顶点为vs时停止 forvex=G.vexs[i].formerVex; if(forvex.substr(0,1).compare("-")==0){ forvex1=forvex.substr(1,2); j=G.LocateIndex(G,forvex1); G.arcs[i][j].flows=G.arcs[i][j].flows-dis;//反向,流量减 }else{ j=G.LocateIndex(G,forvex);//得到前面的顶点的下标 G.arcs[j][i].flows=G.arcs[j][i].flows+dis;//正向,流量加 } i=j; } returntrue; } boolGraphics: : Mark_Node(Graphics&G,inti){ intj; doublea,b; boolb1=false,b2=false; for(j=0;j if(G.vexs[j].mark==n_mark){ if(G.arcs[i][j].weight! =M){//判断是否相连 if(G.arcs[i][j].flows! =G.arcs[i][j].weight){//正向不是饱和流,标记 G.vexs[j].mark=marking; G.vexs[j].formerVex=G.vexs[i].vexs; a=G.vexs[i].flowsDiff; b=G.arcs[i][j].weight-G.arcs[i][j].flows;
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 网络 最大