算法分析报告与复杂性理论 实验报告材料 最大流问题.docx
- 文档编号:7134014
- 上传时间:2023-01-21
- 格式:DOCX
- 页数:12
- 大小:781.35KB
算法分析报告与复杂性理论 实验报告材料 最大流问题.docx
《算法分析报告与复杂性理论 实验报告材料 最大流问题.docx》由会员分享,可在线阅读,更多相关《算法分析报告与复杂性理论 实验报告材料 最大流问题.docx(12页珍藏版)》请在冰豆网上搜索。
算法分析报告与复杂性理论实验报告材料最大流问题
深圳大学实验报告
课程名称:
算法分析与复杂性理论
实验名称:
实验五最短增益路径法求最大流问题
学院:
计算机与软件学院专业:
软件工程
报告人:
文成学号:
2150230509班级:
学术型
同组人:
无
指导教师:
杨烜
实验时间:
2015/11/23——2015/11/30
实验报告提交时间:
2015/11/28
教务处制
一.实验目的与实验内容
实验目的:
(1) 掌握最短增益路径法思想。
(2) 学会最大流问题求解方法。
实验内容:
1.给定下面的通信网络,该网络中各节点之间的路径流量给定,使用最短增益路径法求解该网络的最大流量,并进行流量分配。
2. 要求用加权矩阵输入该网络,输出每次迭代过程中的最大流量及各路径分配的流量。
3. 如果能利用图形界面输出动态求解过程(在网络结构的图形显示中,标注每一次求得的增益路径,并显示当前流量分配),可获加分。
算法思想提示:
1. 利用二维数组C[i,j]和F[i,j]分别存放容量和流量。
2. 构建队列类Queue,该类具有取队首元素,加入队尾元素等方法。
3. 具体算法过程参见教材pp.271-272
二.实验步骤
最大流问题的问题描述:
如上图。
s是源点,t为汇点,每条边上数字的含义是边能够允许流过的最大流量。
可以将边看成管道,3代表该管道每秒最多能通过3个单位的流量。
最大流问题即是说,从s点到t点,最大允许流量是多少?
最大流问题的算法思想:
最短增益路径法(先标记先扫描算法):
用两个记号来标记一个新的顶点
第一个标记指出从源点到被标记顶点还能增加多少流量
第二个标记指出另一个顶点的名字,可加上+或-来表示顶点时通过前向边还是后向边访问到的
算法及其伪代码:
Maxflow(G)
//最短增量路径算法的实现
//输入:
网络G,具有一个源点1和一个汇点n,每条边(i,j)的容量都是正整数Uij
//输出:
最大流量x
//对网络中的每条边(i,j),设xij=0
//把源点标记为∞,-,再把源点加入到空队列Q中
WhilenotEmpty(Q)do
i←Front(Q);Dequeue(Q)
for从i到j的每条边do//前向边
ifj没有被标记
rij←uij-xij
ifrij>0
Ljmin{Li,xji};用L,i-来标记j
Enqueue(Q,j)
If汇点被标记了
//沿着找到的增益路径进行增量
j←n//从汇点开始,用第二个标记反向移动
whilej!
=i//没有到达源点
if顶点j的第二个标记是i+
xij←xij+Ln
else//顶点j的第二个标记是i-
xji←xji-Ln
j←i;i←i的第二个标记指出的顶点
除了源点,擦去所有顶点的标记
用源点对Q重新初始化
returnx//当前流量是最大的
思路以及代码解释:
(全部源代码见附件)
先创建一个解决问题的类,命名为G。
计算最大流作为这个类中的一个方法来实现。
利用二维数组Map[i,j]和Flow[i,j]分别存放容量和流量。
添加头文件#include
classG
{
public:
G();
G(intn,intstart,intend);
voidEdge(inta,intb,intflow);//顶点a和顶点b之间的流量
voidMaxflow();//计算最大流
private:
intN;//顶点个数
intStart;//源点
intEnd,//汇点
**Map,//网络容量
**Flow,//通过流量
**Rest,//剩余流量
*Pre,//标记流向,正为前向,负为后向
*Sign,//顶点是否标记,0为未标记,1为已标记
*P;//过程变量,记录流量
boolSignN();//标记顶点
intMin(inta,intb);//计算最小值
voidUpdate();//更新网络
};
构造函数就先定义两个
G:
:
G(){Pre=NULL;}//不带参数的构造函数
G:
:
G(intn,intstart,intend)//带三个参数的构造函数,顶点个数,源点和汇点
{初始化}
在类G中,实现了voidMaxflow();方法,用来计算最大流,
其中标记顶点的函数定义为boolSignN();
boolG:
:
SignN()//标记顶点
{
Update();//更新
queue
que.push(Start);//把源点放进队列里面
Sign[Start]=1;//将源点标记
P[Start]=1000;
Pre[Start]=-1;//标记流向为后向
while(!
que.empty())//WhilenotEmpty(Q)do
{
inthead=que.front();//不断地取队首为head
que.pop();
for(inti=1;i<=N;i++)
{
//如果为标记顶点j是由j到i的有向边和遍历队列中的前面顶点i相连接的,而且j具有大于0的未使用容量rij=uij-xij,其中uij为边的总容量,xij为当前正容量,那么顶点j就标记为lj,i+,其中lj=min{li,rij}
if(Rest[head][i]>0&&Sign[i]==0)//如果从head出发到其它顶点,有剩余流量大于0,并且没有被标记
{
P[i]=Min(P[head],Rest[head][i]);
Pre[i]=head;
Sign[i]=1;
if(i==End)returntrue;//当扫描到汇点后返回
que.push(i);
}
}
for(i=1;i<=N;i++)
{
//如果为标记顶点j是由j到i的有向边和遍历队列中的前面顶点i相连接的,而且j具有大于0的未使用容量xji,那么顶点j就标记为lj,i-,其中lj=min{li,xji}
if(Flow[i][head]>0&&Sign[i]==0)//如果有顶点到head的流量大于0.并且没有被标记
{
P[i]=Min(P[head],Flow[i][head]);
Pre[i]=-head;
Sign[i]=1;
if(i==End)returntrue;//当扫描到汇点后返回
que.push(i);
}
}
}
returnfalse;
}
voidG:
:
Maxflow()//计算最大流
{
intmaxflow=0;
while(SignN())//迭代地去标记顶点
{
maxflow=maxflow+P[End];
for(inti=End;i>1;i=abs(Pre[i]))
{
if(Pre[i]>0)//流向为前向
{
Flow[Pre[i]][i]=Flow[Pre[i]][i]+P[End];
}
if(Pre[i]<0)//流向为后向
{
Flow[i][abs(Pre[i])]=Flow[i][abs(Pre[i])]-P[End];
}
}
}
cout<<"最大流:
"< } 三.实验结果与分析 编写主函数,对于下图的程序运行结果 以上就是每次迭代的过程,下面详细解释一下这些过程。 1—>2—>3—>6,一条4的通路。 此时流量为4 此时流量为6。 此时流量为8。 此时流量为10 下一次迭代之后,流量没有增长,那么结束。 最后的结果应该是这样的。 最大流量为10 由最大流最小割定理可以验证。 该图的最小割为(2,5)(3,6)(4,5),最小割流量为2+4+4=10。 因为网络中的最大流量值等于它最小割的容量,可以验证上图的正确性。 后面,我也实现了用加权矩阵输入该网络,输出每次迭代过程中的最大流量及各路径分配的流量。 四.实验心得 在现实生活中,在实际的网络中,网络的结点和边都是有容量限制的.很多情况下我们需要知道在一个有容量限制的网络中两个指定结点(分别称为源点和汇点)之间最多能传输多少流量,并确定达到这个最大流量的传输策略.网络最大流问题(简称最大流问题)就是描述这个问题的数学模型. 求解最大流的算法有不少,在此次实验中,我学习到了最短增益路径法,也明白了,最大流量值和最小割容量是相等的。 本次实验挺有难度的,让我明白了最大流问题的算法,对迭代改进算法的认识也更加深刻了。 这次实验结束后让我感觉到好的算法是多么的重要,当然合理利用算法也是不可忽视的。 这次实验虽然花了很大精力,却收获累累。 指导教师批阅意见: 成绩评定: 指导教师签字: 年月日 备注: 注: 1、报告内的项目或内容设置,可根据实际情况加以调整和补充。 2、教师批改学生实验报告时间应在学生提交实验报告时间后10日内。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 算法分析报告与复杂性理论 实验报告材料 最大流问题 算法 分析 报告 复杂性 理论 实验 材料 最大 问题