Skip to content

Commit

Permalink
Add some comments
Browse files Browse the repository at this point in the history
  • Loading branch information
burk committed Jun 11, 2014
1 parent f96cbbe commit 21e8729
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 35 deletions.
58 changes: 34 additions & 24 deletions graph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

using namespace std;

/* Add an edge from one vertex to another. */
int FlowGraph::addEdge(int from, int to, int cap) {
G[from].push_back(Edge(from, to, cap, G[to].size()));
if (from == to) G[from].back().index++;
Expand All @@ -17,11 +18,19 @@ int FlowGraph::addEdge(int from, int to, int cap) {
return index;
}

/*
* Add an edge and at the same time an antiparallel edge
* with the same capacity.
*/
void FlowGraph::addDoubleEdge(int from, int to, int cap) {
G[from].push_back(Edge(from, to, cap, G[to].size()));
G[to].push_back(Edge(to, from, cap, G[from].size() - 1));
}

/*
* Change the capacity of an edge. Need the from-vertex and
* the index of the edge in its edge list (returned from addEdge.
*/
void FlowGraph::changeCapacity(int from, int index, int cap) {
int to = G[from][index].to;
int diff = G[from][index].flow - cap;
Expand All @@ -39,6 +48,7 @@ void FlowGraph::changeCapacity(int from, int index, int cap) {
}
}

/* Reset all flow and excess. */
void FlowGraph::resetFlow() {
for (int i = 0; i < G.size(); ++i) {
for (int j = 0; j < G[i].size(); ++j) {
Expand All @@ -48,11 +58,13 @@ void FlowGraph::resetFlow() {
fill(excess.begin(), excess.end(), 0);
}

/* Reset all distance labels. */
void FlowGraph::resetHeights() {
fill(height.begin(), height.end(), 0);
fill(count.begin(), count.end(), 0);
}

/* Push along an edge. */
void FlowGraph::push(Edge &e) {
int flow = min(e.cap - e.flow, excess[e.from]);
excess[e.from] -= flow;
Expand All @@ -63,6 +75,7 @@ void FlowGraph::push(Edge &e) {
rule.add(e.to, height[e.to], excess[e.to]);
}

/* Relabel a vertex. */
void FlowGraph::relabel(int u) {
count[height[u]]--;
height[u] = 2*N;
Expand All @@ -82,6 +95,7 @@ void FlowGraph::relabel(int u) {
}
}

/* Relabel all vertices over the gap h to label N. */
void FlowGraph::gap(int h) {
int c = 0;
for (int i = 0; i < G.size(); ++i) {
Expand All @@ -97,6 +111,7 @@ void FlowGraph::gap(int h) {
rule.gap(h);
}

/* Discharge a vertex. */
void FlowGraph::discharge(int u) {
int i;
for (i = 0; i < G[u].size() && excess[u] > 0; ++i) {
Expand All @@ -107,13 +122,15 @@ void FlowGraph::discharge(int u) {
}

if (excess[u] > 0) {
/* Check if a gap will appear. */
if (count[height[u]] == 1)
gap(height[u]);
else
relabel(u);
}
}

/* Run the push-relabel algorithm to find the min-cut. */
void FlowGraph::minCutPushRelabel(int source, int sink) {
height[source] = N;

Expand All @@ -127,17 +144,23 @@ void FlowGraph::minCutPushRelabel(int source, int sink) {
excess[source] = 0;

int c = 0;
/* Loop over active nodes using selection rule. */
while (!rule.empty()) {
c++;
int u = rule.next();
discharge(u);
}

/* Output the cut based on vertex heights. */
for (int i = 0; i < cut.size(); ++i) {
cut[i] = height[i] >= N;
}
}

/*
* Depth-first-search used to find a cut at the
* end of Diniz.
*/
void FlowGraph::DFS(int source, int sink) {
stack<int> s;
vector<bool> visited(N);
Expand All @@ -160,13 +183,18 @@ void FlowGraph::DFS(int source, int sink) {
}
}

/* Diniz min-cut algorithm. */
void FlowGraph::minCutDinic(int source, int sink) {
maxFlowDinic(source, sink);

fill(cut.begin(), cut.end(), false);
DFS(source, sink);
}

/*
* Recursive blocking flow algorithm, from the current
* vertex u, from which we can at most send limit flow.
*/
int FlowGraph::blockingFlow(vector<int> &level, int u,
int source, int sink, int limit) {
if (limit <= 0) return 0;
Expand All @@ -178,6 +206,7 @@ int FlowGraph::blockingFlow(vector<int> &level, int u,

int res = G[u][i].cap - G[u][i].flow;

/* Recurse on vertices one level closer to sink. */
if (level[G[u][i].to] == level[u] + 1 && res > 0) {
int aug = blockingFlow(
level,
Expand All @@ -200,6 +229,7 @@ int FlowGraph::blockingFlow(vector<int> &level, int u,
return throughput;
}

/* Diniz max-flow algorithm. */
int FlowGraph::maxFlowDinic(int source, int sink) {

vector<int> level(N);
Expand All @@ -209,6 +239,10 @@ int FlowGraph::maxFlowDinic(int source, int sink) {

queue<int> nq;

/*
* Fill the level vector using a basic breadth-first
* search.
*/
nq.push(source);
level[source] = 1;
while (!nq.empty()) {
Expand Down Expand Up @@ -282,14 +316,6 @@ bool FlowGraph::checkCount(void) {
return true;
}

int FlowGraph::activeNodes(void) {
int c = 0;
for (int i = 0; i < excess.size(); ++i) {
if (excess[i] > 0) c++;
}
return c;
}

int FlowGraph::outFlow(int source) {
int c = 0;
for (int i = 0; i < G[source].size(); ++i) {
Expand All @@ -306,19 +332,3 @@ int FlowGraph::inFlow(int sink) {
return c;
}

int FlowGraph::outCap(int source) {
int c = 0;
for (int i = 0; i < G[source].size(); ++i) {
c += G[source][i].cap;
}
return c;
}

int FlowGraph::inCap(int sink) {
int c = 0;
for (int i = 0; i < G[sink].size(); ++i) {
c += G[G[sink][i].to][G[sink][i].index].cap;
}
return c;
}

4 changes: 0 additions & 4 deletions graph.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,8 @@ class FlowGraph {
int source, int sink, int limit);
void DFS(int source, int sink);

int activeNodes(void);
int outFlow(int source);
int inFlow(int sink);
int outCap(int source);
int inCap(int sink);
int totalHeight(void);

bool checkExcess(void);
bool checkCapacity(void);
Expand Down
26 changes: 19 additions & 7 deletions image.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@ int f(int u, int v, int p) {
return p == 2 ? (u - v) * (u - v) : abs(u - v);
}

/* Fidelity energy term. */
int Ei(int label, int pix, int u, int p) {
return (f(label+1, pix, p) - f(label, pix, p)) * (1 - u);
}

/* Regularization energy term. */
int Eij(int up, int uq) {
return (1 - 2 * uq) * up + uq;
}
Expand All @@ -27,19 +29,19 @@ void Image::createEdges() {
int C = Eij(1, 0);
int D = Eij(1, 1);

cout << "A = " << A << endl;
cout << "B = " << B << endl;
cout << "C = " << C << endl;
cout << "D = " << D << endl;

/*
* Add sink edges first, so that the first push in discharge
* will go towards the sink.
* will go towards the sink. The capacities are set up in
* setupSourceSink.
*/
for (int i = 0; i < pixels; ++i) {
t_index[i] = network.addEdge(i, sink, 0);
}

/*
* Create internal edges, which do not depend on the current
* level.
*/
for (int j = 0; j < rows; ++j) {
for (int i = 0; i < cols; ++i) {
Neighborhood::const_iterator it;
Expand All @@ -58,11 +60,20 @@ void Image::createEdges() {
}
}

/*
* Add edges from the source. Capacities are set up in
* setupSourceSink.
*/
for (int i = 0; i < pixels; ++i) {
s_index[i] = network.addEdge(source, i, 0);
}
}

/*
* Change the capacities of the edges connecting the source
* and the sink to the rest of the network, as these edges
* are dependent on the current level.
*/
void Image::setupSourceSink(int alpha, int label, int p) {

fill(s_caps.begin(), s_caps.end(), 0);
Expand Down Expand Up @@ -96,7 +107,7 @@ void Image::restore(int alpha, int p) {
createEdges();

for (int label = 255; label >= 0; --label) {
//cout << "Label: " << label << endl;
cout << "Label: " << label << endl;

setupSourceSink(alpha, label, p);
#ifdef DINIC
Expand All @@ -106,6 +117,7 @@ void Image::restore(int alpha, int p) {
network.minCutPushRelabel(source, sink);
#endif

/* Use the cut to update the output image. */
for (int j = 0; j < rows; ++j) {
for (int i = 0; i < cols; ++i) {
if (!network.cut[j*cols + i])
Expand Down

0 comments on commit 21e8729

Please sign in to comment.