ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

手撕Ford-Fulkerson algorithm 学一半的笔记

2021-06-06 09:56:45  阅读:247  来源: 互联网

标签:parent adjMatrix algorithm int Fulkerson Ford source vector path


目录

我明白了,
余量网络 名如其名
比如你f/c=3/5
那么正边2,reverse edge3,加起来是5

在这个你建的新图上找s到t的路径
然后path的最小边权叫delta

给流图的对应path的每条边e都加流 delta,或者 反边减delta (反边的情况)
得到新的流,重复
直到余量网络没有s到t的路径
(最大流-最小割定理也行)

求最小费用流
找个最大流,
然后

建立个新图
比如这条边的性质 容量,代价= 6,3,跑着2的流
那么正向边标4,3
反向标 2,-3
新图上找 负环(负环的代价和为负)
然后min{a_1}
流加上这个
流调整了
重复
直到新图上找不到 负环(负环的代价和为负)

不断调整f得到最大流
我吐了都,要想手撕个算法首先还得理解一些定义

我找了个课件边看边学

https://www.cs.princeton.edu/~wayne/kleinberg-tardos/pdf/07NetworkFlowI.pdf

定义大概就这些

image-20200821230139062

Def. The bottleneck capacity of an augmenting path P is the minimum residual capacity of any edge in P

伪代码

image-20200821230002386

其中,AUGMENT()如下

image-20200821230032530

自己做slide里的quiz



搬运别人的代码

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=
// Copyright srcmake 2018.
// C++ Example Ford Fulkerson Algorithm

/* Ford Fulkerson Algorithm:
    // 0. Initialize an adjacency matrix to represent our graph.
    // 1. Create the residual graph. (Same as the original graph.)
    // 2. Create an default parent vector for BFS to store the augmenting path. 
    // 3. Keep calling BFS to check for an augmenting path (from the source to the sink...
        // 4. Find the max flow through the path we found.
        // 5. Update the residual capacities of the edges and reverse edges. 
        // 6. Add this path's flow to our total max flow so far.
*/

// The example graph: https://www.srcmake.com/uploads/5/3/9/0/5390645/maxflow_1_orig.jpg

#include <iostream>
#include <vector>
#include <queue>

using namespace std;

//////////////////////////////////////////////////////////////////////////////////////////////
// See the picture here: https://www.srcmake.com/uploads/5/3/9/0/5390645/adjmatrix_1_orig.jpg
vector< vector<int> > FormAdjMatrix()
    {
    // Our adjacency list.
    vector< vector<int> > adjMatrix;
    
    const int n = 6;
    
    // Initialize our matrix to all 0s.
    for(int i = 0; i < n; i++)
        {
        vector<int> row;
        adjMatrix.push_back(row);
        for(int j = 0; j < n; j++)
            {
            adjMatrix[i].push_back(0);
            }
        }
    
    // First number is the vertex, second is the edge capacity.
    adjMatrix[0][1] = 15;
    adjMatrix[0][2] = 12;
    adjMatrix[1][2] = 9;
    adjMatrix[1][3] = 11;
    adjMatrix[2][1] = 5;
    adjMatrix[2][4] = 13;
    adjMatrix[3][2] = 9;
    adjMatrix[3][5] = 25;
    adjMatrix[4][3] = 8;
    adjMatrix[4][5] = 6;
    
    // Our graph is now represented as an adjacency list. 
    return adjMatrix;
    }
//////////////////////////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////////////////////////
// A special BFS version that returns true if there's a path from source to sink.
bool BFS(vector< vector<int> > &resAdjMatrix, int &source, int &sink, vector<int> &parent)
    {
    // Create an array for all nodes we visited. Initialized to false.
    int n = resAdjMatrix.size();
    bool visited[n] = { false };
        
    // Create a queue to check each node.
    queue<int> q;
    
    // Push our source into the queue and mark it as visited. It has no parent.
    q.push(source);
    visited[source] = true;
    parent[source] = -1;
        
    // Keep visiting vertices.
    while(q.empty() == false)
        {
        int u = q.front();
        q.pop();
        
        // Check all of u's friends.
        for(int i = 0; i < n; i++)
            {
            int v = i;
            int capacity = resAdjMatrix[u][v];
            
            // We find a neighbor that hasn't been visited, and the capacity is bigger than 0.
            if(visited[v] == false && capacity > 0)
                {
                // Push the neighbor onto the queue, mark it's parent, and mark it as visited.
                q.push(v);
                parent[v] = u;
                visited[v] = true;
                }
            }
        }
        
    // If the sink got visited, then we found a path to it. 
    if(visited[sink] == true) 
        { return true; }
        
    return false;
    }
//////////////////////////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////////////////////////
// Use the Ford Fulkerson algorithm. Return the max flow.
int FordFulkerson(vector< vector<int> > &adjMatrix, int &source, int &sink)
    {
    int maxflow = 0;
    
    // 1. Create the residual graph. (Same as the original graph.)
    vector< vector<int> > resAdjMatrix;
    int n = adjMatrix.size();
    for(int i = 0; i < n; i++)
        {
        vector<int> row;
        resAdjMatrix.push_back(row);
        for(int j = 0; j < adjMatrix[i].size(); j++)
            {
            resAdjMatrix[i].push_back(adjMatrix[i][j]);
            }
        }
    
    // 2. Create an empty parent array for BFS to store the augmenting path. 
    vector<int> parent;
    for(int i = 0; i < n; i++)
        {
        parent.push_back(-1);
        }
    
    // 3. Keep calling BFS to check for an augmenting path (from the source to the sink...
    while(BFS(resAdjMatrix, source, sink, parent) == true)
        {
        // 4. Find the max flow through the path we just found.
        int pathflow = 10000007;
        
        // Go through the path we just found. Iterate through the path.
        int v = sink;
        while(v != source)
            {
            int u = parent[v]; // The parent.
            
            // Update the pathflow to this capacity if it's smaller
            int capacity = resAdjMatrix[u][v];
            pathflow = min(pathflow, capacity);
            
            // Setup for the next edge in the path.
            v = u;
            }
        
        // 5. Update the residual capacities of the edges and reverse edges. 
        v = sink;
        while(v != source)
            {
            int u = parent[v]; // The parent.
            
            // Update the capacities.
            
            resAdjMatrix[u][v] -= pathflow;
            resAdjMatrix[v][u] += pathflow;
            
            // Setup for the next edge in the path.
            v = u;
            }
        
        // 6. Add this path's flow to our total max flow so far.
        maxflow += pathflow;
        }
    
    return maxflow;
    }
//////////////////////////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////////////////////////    
int main() 
    {
    cout << "Program started.\n";
    
    // Create our adjacency list.
    vector< vector<int> > adjMatrix = FormAdjMatrix();
    
    // Call FordFulkerson to get the max flow from the source to the sink.
    int source = 0;
    int sink = 6;
    
    for(int i = 0; i < 6; i++)
        {
        for(int j = 0; j < 6; j++)
            {
            int source = i;
            int sink = j;
            
            if(i == j) { continue; }
            
            cout << "The max flow from " << source << " to " << sink << " is: ";
            cout << FordFulkerson(adjMatrix, source, sink) << endl;
            }
        cout << endl;
        }
    
    
    cout << "Program ended.\n";
    
    return 0;
    }
//////////////////////////////////////////////////////////////////////////////////////////////

标签:parent,adjMatrix,algorithm,int,Fulkerson,Ford,source,vector,path
来源: https://blog.51cto.com/u_15247503/2871583

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有