如何找到一个图增广路径
How to find a graph augmenting path
我正在尝试实现Ford-Fulkerson算法来计算流网络中的最大流量。
算法的一个步骤是找到一条从开始节点到结束节点(也称为sink)的路径,所有边都有可用容量。
你能建议一个简单易懂的方法来找到扩展路径吗?
UPDATE # 1:
My BFS function:
template <class T>
vector<Vertex<T> *> Graph<T>::bfs(T source) const {
vector<Vertex<T> *> path;
queue<Vertex<T> *> q;
Vertex<T> * v = getVertex(source);
q.push(v);
v->visited = true;
while (!q.empty()) {
Vertex<T> *v1 = q.front();
q.pop();
path.push_back(v1);
typename vector<Edge<T> >::iterator it = v1->adj.begin();
typename vector<Edge<T> >::iterator ite = v1->adj.end();
for (; it!=ite; it++) {
Vertex<T> *d = it->dest;
if (d->visited == false) {
d->visited = true;
q.push(d);
}
}
}
return path;
}
返回的结果是错误的/不完整的。我想我忘了什么。
点击此处阅读。基本使用width -firstrongearch。
编辑:path.push_back(v1);
在错误的地方。你将把图的所有顶点都添加到路径上。正确的方法是为每个节点存储前身节点。这样就可以恢复找到的路径。当你到达水槽时,你也可以打破while
条款。
if (d->visited == false) {
d->visited = true;
q.push(d);
predecessor[d] = v1;
}
在不了解底层数据结构的情况下,很难给出明确的建议。通常当你处理流的时候,你有一个有向图。我假设这是我的答案。现在我看到了几个主要问题和一个小问题:
template <class T>
vector<Vertex<T> *> Graph<T>::bfs(T source) const {
vector<Vertex<T> *> path;
在这种情况下,列表可能是一个更好的选择,因为向量只是平摊常数的插入和删除时间,而列表确实是常数。(假设您指的是STL-Containers) -这是次要的注释;)
queue<Vertex<T> *> q;
对于BFS,你有两种选择:要么保存所有路径,要么保存每个顶点的前导路径。你只需要保存你要访问的顶点。这样一来,我不知道你如何能够重建一个完整的路径,一旦你到达接收器。
Vertex<T> * v = getVertex(source);
q.push(v);
v->visited = true;
初始化对我来说似乎很好。
while (!q.empty()) {
Vertex<T> *v1 = q.front();
q.pop();
path.push_back(v1);
typename vector<Edge<T> >::iterator it = v1->adj.begin();
typename vector<Edge<T> >::iterator ite = v1->adj.end();
这里取当前所在顶点的邻接表。记住,扩增路径之所以被称为扩增,是因为你可以向前(如果还有剩余容量,那么通过这条边的电流小于这条边的容量)或向后(如果这条边的电流大于0)遍历一条边。你只是取图中所有向前的边并访问它们。这是"正常的"BFS,而不是适应最大流量问题中使用的不同图结构的BFS。
(为了完整:你可以把你的网络和当前的流放在一起,并从这个(我知道这个是辅助网络)创建一个新的图,它正好代表这个结构。在这种情况下,你的BFS会工作得很好。如果你现在正在做这个,我想看看计算辅助网络的例程。
for (; it!=ite; it++) {
Vertex<T> *d = it->dest;
if (d->visited == false) {
d->visited = true;
q.push(d);
}
}
}
那部分看起来不错,除了我已经提到的几点。因此,保存前人,检查路径是否对最大流量有帮助(剩余容量),并检查向后的弧线。
return path;
再看一下您在path变量中收集的内容。实际上你把BFS访问过的所有顶点按照访问的顺序保存在那里。但是,您需要这些顶点的子集给出正确的路径。
最后一句话:对于Ford-Fulkerson来说,在执行BFS时直接计算当前路径上可以增加的流的值可能是一个聪明的主意。这样你就不需要再次访问边缘了。当然,您可以在使用尚未保存的前辈收集路径时执行此操作。
我不会给你一个完整的工作代码示例,因为我认为这是家庭作业,你应该学习一些东西,而不是完成代码。
查看源代码:http://aduni.org/courses/algorithms/courseware/handouts/Reciation_09.html
- 检查路径是否包含C++中的另一个路径
- 如何使用条件计算 3D 网格中从一个点到另一个点的所有路径
- 在由邻接列表表示的树中查找节点到另一个给定节点之间的路径
- 从另一个应用启动我的应用时出现相对路径更改问题
- 如何在另一个系统上启用文件路径
- 添加一个节点,并在通用树中的两个给定节点之间找到路径成本,其中c 中的儿童列表
- 如果路径的每个元素不存在,请为其创建一个目录
- “并非所有控制路径都返回一个值./&quot“控制可能达到非空隙功能的末端”.验证时循环时
- 我正在尝试在Eclipse中构建一个C 项目,但是即使在使用MINGW路径设置路径变量之后,也会获得构建错误
- 最短路径问题与一个变化
- 在树中查找一个路径/子路径,使权重之和小于给定的整数
- 使用 ros launch 创建一个目录,然后将其路径传递给不同的节点
- 如何确保迷宫总是有一个有效的路径C++
- 有没有一个带有距离标记的最短路径算法的开源实现
- 在MacOS上编译一个动态库,库搜索路径指向同一目录(CMake)
- 在一个有权无向图中寻找某一长度的所有路径
- 类型名称路径由一个静态变量隐藏
- Qt:如何创建一个文件(其路径需要目录)
- 给定一个二叉搜索树和一个数字,找到一个路径,其节点的数据被添加为给定的数字。
- 将filesystem::path元素附加到另一个路径的最佳方法是什么?