Skip to content
Snippets Groups Projects
Commit fdabd4cc authored by Lukas Garbas's avatar Lukas Garbas
Browse files

Edmonds-Karp add source and sink methods

parent 0ab573dd
Branches
No related merge requests found
......@@ -8,8 +8,10 @@
edmonds_karp::edmonds_karp(const graph &g, std::vector<node_id> sources, std::vector<node_id> sinks)
: g_(g), sources_(sources), sinks_(sinks) {
index_edges();
int num_edges = indexed_edges_.size() / 2;
// Initial flow value
flow_value_ = 0;
int num_edges = g_.num_edges();
// Initialize vectors
flow_.assign(num_edges, 0);
......@@ -23,32 +25,6 @@ edmonds_karp::edmonds_karp(const graph &g, std::vector<node_id> sources, std::ve
sources_and_sinks_[t] = -1;
};
/* Indexes edges of the graph
Every edge in the graph is mapped to its unique id
indexed_edges std::map consists of key: pair<node_id, node_id> value: edge_id */
void edmonds_karp::index_edges() {
unsigned int num_nodes = g_.num_nodes();
unsigned int eid = 0;
for (node_id u = 1; u <= num_nodes; u++) {
std::vector<node_id> neighbors = g_.get_adjacency(u);
for (node_id v : neighbors) {
auto node_pair = std::make_pair(u, v);
// edge was already listed
if (indexed_edges_.count(std::make_pair(v, u)) == 1) {
indexed_edges_[node_pair] = indexed_edges_.at(std::make_pair(v, u));
} else {
indexed_edges_[node_pair] = eid;
eid++;
}
}
}
}
/* Breadth-first search in the graph from source nodes to sink nodes */
std::pair<int, node_id> edmonds_karp::bfs(std::vector<unsigned int> &pred) const {
......@@ -73,11 +49,17 @@ std::pair<int, node_id> edmonds_karp::bfs(std::vector<unsigned int> &pred) const
node_id u = q.front();
q.pop();
std::vector<node_id> neighbors = g_.get_adjacency(u);
const std::vector<node_id> & neighbors = g_.get_adjacency(u);
// iterate through neighbors of u
for (node_id v : neighbors) {
unsigned int edge_id = indexed_edges_.at(std::make_pair(u, v));
unsigned int edge_id;
if ( u < v )
edge_id = g_.get_edge_id(u, v);
else
edge_id = g_.get_edge_id(v, u);
int edge_weight = 1; // unweighted graph
if (((u >= v && flow_[edge_id] < edge_weight)
......@@ -105,6 +87,20 @@ std::pair<int, node_id> edmonds_karp::bfs(std::vector<unsigned int> &pred) const
};
void edmonds_karp::add_source(node_id s) {
sources_.push_back(s);
sources_and_sinks_[s] = 1;
run();
}
void edmonds_karp::add_sink(node_id t) {
sinks_.push_back(t);
sources_and_sinks_[t] = -1;
run();
}
/* Edmonds-Karp Algorithm for unweighted, undirected graphs
Step 0: Index graph edges
Step 1: Initialize flow and residual flow vectors with length |E|
......@@ -114,8 +110,6 @@ Step 3: Add gain that was calculated during BFS to the flow value. Break from th
Step 4: Update flow and residual flow values for each node */
void edmonds_karp::run() {
flow_value_ = 0;
while (true) {
std::vector<node_id> pred;
......@@ -134,12 +128,13 @@ void edmonds_karp::run() {
bool source_reached = false;
while (!source_reached) {
node_id u = pred[v];
int edge_id = indexed_edges_[std::make_pair(u, v)];
if (u >= v) {
unsigned int edge_id = g_.get_edge_id(v, u);
flow_[edge_id] += gain;
resid_flow_[edge_id] -= gain;
} else {
unsigned int edge_id = g_.get_edge_id(u, v);
flow_[edge_id] -= gain;
resid_flow_[edge_id] += gain;
}
......@@ -153,6 +148,7 @@ void edmonds_karp::run() {
};
int edmonds_karp::get_max_flow() const {
return flow_value_;
};
......@@ -48,6 +48,13 @@ public:
*/
void run();
/**
* Dynamically add a source or a sink node and
* recalculate maximum flow value
*/
void add_source(node_id s);
void add_sink(node_id t);
/**
* Returns the value of the maximum flow from source to sink.
*
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment