35 static const unsigned char FREE = 0x00;
36 static const unsigned char SOURCE = 0x01;
37 static const unsigned char TARGET = 0x02;
48 vector<unsigned char>
_cut;
53 _sourceEdges.reserve(maxNodes);
54 _targetEdges.reserve(maxNodes);
55 _edgeWeights.reserve(2 * maxNodes);
56 _nodes.reserve(maxNodes);
65 size_t numNodes()
const {
return _nodes.size(); }
74 int nodeId = (int)_nodes.size();
75 _nodes.resize(_nodes.size() + n);
76 _sourceEdges.resize(_nodes.size(), 0.0);
77 _targetEdges.resize(_nodes.size(), 0.0);
88 DRWN_ASSERT((u >= 0) && (u < (
int)_nodes.size()));
89 if (cap < 0.0) { _flowValue += cap; _targetEdges[u] -= cap; }
90 else _sourceEdges[u] += cap;
95 DRWN_ASSERT((u >= 0) && (u < (
int)_nodes.size()));
96 if (cap < 0.0) { _flowValue += cap; _sourceEdges[u] -= cap; }
97 else _targetEdges[u] += cap;
102 inline void addEdge(
int u,
int v,
double cap_uv,
double cap_vu = 0.0) {
103 DRWN_ASSERT((u >= 0) && (u < (
int)_nodes.size()));
104 DRWN_ASSERT((v >= 0) && (v < (
int)_nodes.size()));
107 _drwnCapacitatedEdge::const_iterator it = _nodes[u].find(v);
108 if (it == _nodes[u].end()) {
109 DRWN_ASSERT(cap_uv + cap_vu >= 0.0);
111 _nodes[u].insert(make_pair(v, make_pair(_edgeWeights.size(), _edgeWeights.size() + 1)));
112 _nodes[v].insert(make_pair(u, make_pair(_edgeWeights.size() + 1, _edgeWeights.size())));
113 _edgeWeights.push_back(0.0);
114 _edgeWeights.push_back(cap_uv + cap_vu);
115 _sourceEdges[u] -= cap_uv;
116 _targetEdges[v] -= cap_uv;
117 _flowValue += cap_uv;
118 }
else if (cap_vu < 0.0) {
119 _nodes[u].insert(make_pair(v, make_pair(_edgeWeights.size(), _edgeWeights.size() + 1)));
120 _nodes[v].insert(make_pair(u, make_pair(_edgeWeights.size() + 1, _edgeWeights.size())));
121 _edgeWeights.push_back(cap_uv + cap_vu);
122 _edgeWeights.push_back(0.0);
123 _sourceEdges[v] -= cap_vu;
124 _targetEdges[u] -= cap_vu;
125 _flowValue += cap_vu;
127 _nodes[u].insert(make_pair(v, make_pair(_edgeWeights.size(), _edgeWeights.size() + 1)));
128 _nodes[v].insert(make_pair(u, make_pair(_edgeWeights.size() + 1, _edgeWeights.size())));
129 _edgeWeights.push_back(cap_uv);
130 _edgeWeights.push_back(cap_vu);
133 const double w_u = _edgeWeights[it->second.first] += cap_uv;
134 const double w_v = _edgeWeights[it->second.second] += cap_vu;
135 DRWN_ASSERT(w_u + w_v >= 0.0);
137 _edgeWeights[it->second.first] = 0.0;
138 _edgeWeights[it->second.second] += w_u;
139 _sourceEdges[u] -= w_u;
140 _targetEdges[v] -= w_u;
142 }
else if (w_v < 0.0) {
143 _edgeWeights[it->second.first] += w_v;
144 _edgeWeights[it->second.second] = 0.0;
145 _sourceEdges[v] -= w_v;
146 _targetEdges[u] -= w_v;
153 virtual double solve() = 0;
157 bool inSetS(
int u)
const {
return (_cut[u] == SOURCE); }
160 bool inSetT(
int u)
const {
return (_cut[u] == TARGET); }
164 double operator()(
int u,
int v)
const;
168 void preAugmentPaths();
183 virtual double solve();
199 static const int TERMINAL = -1;
203 vector<pair<double *, double *> > _weightptrs;
214 virtual void reset();
215 virtual void clear();
216 virtual double solve();
220 void initializeTrees();
222 pair<int, int> expandTrees();
224 void augmentBKPath(
const pair<int, int>& path, deque<int>& orphans);
226 void adoptOrphans(deque<int>& orphans);
228 bool isAncestor(
int u,
int v)
const;
void addEdge(int u, int v, double cap_uv, double cap_vu=0.0)
add edge from u to v and edge from v to u (requires cap_uv + cap_vu >= 0)
Definition: drwnMaxFlow.h:102
bool inSetT(int u) const
return true if u is in the t-set after calling solve (note that sometimes a node can be in either S o...
Definition: drwnMaxFlow.h:160
int addNodes(unsigned n=1)
add nodes to the graph (returns the id of the first node added)
Definition: drwnMaxFlow.h:73
drwnMaxFlow(unsigned maxNodes=0)
construct a maxflow/mincut problem with estimated maxNodes
Definition: drwnMaxFlow.h:52
virtual ~drwnMaxFlow()
destructor
Definition: drwnMaxFlow.h:60
Implementation of Boykov and Kolmogorov's maxflow algorithm.
Definition: drwnMaxFlow.h:197
vector< double > _targetEdges
edges entering the target
Definition: drwnMaxFlow.h:43
vector< _drwnCapacitatedEdge > _nodes
nodes and their outgoing internal edges
Definition: drwnMaxFlow.h:45
vector< double > _edgeWeights
internal edge weights
Definition: drwnMaxFlow.h:44
void addTargetEdge(int u, double cap)
add edge from nodeId to t
Definition: drwnMaxFlow.h:94
bool inSetS(int u) const
return true if u is in the s-set after calling solve. (note that sometimes a node can be in either S ...
Definition: drwnMaxFlow.h:157
void addSourceEdge(int u, double cap)
add edge from s to nodeId
Definition: drwnMaxFlow.h:87
map< int, pair< unsigned, unsigned > > _drwnCapacitatedEdge
references target node j and edge weights (i,j) and (j,i)
Definition: drwnMaxFlow.h:40
Implementation of Edmonds-Karp maxflow/min-cut algorithm.
Definition: drwnMaxFlow.h:174
vector< int > _parents
_parents flag for terminal state
Definition: drwnMaxFlow.h:202
Provides a queue datastructure on a fixed number of indexes. At most one copy of each index can appea...
Definition: drwnIndexQueue.h:38
Interface for maxflow/min-cut algorithms (for minimizing submodular quadratic pseudo-Boolean function...
Definition: drwnMaxFlow.h:32
vector< double > _sourceEdges
edges leaving the source
Definition: drwnMaxFlow.h:42
size_t numNodes() const
get number of nodes in the graph
Definition: drwnMaxFlow.h:65
double _flowValue
current flow value (includes constant)
Definition: drwnMaxFlow.h:46
vector< unsigned char > _cut
identifies which side of the cut a node falls
Definition: drwnMaxFlow.h:48
void addConstant(double c)
add constant flow to graph
Definition: drwnMaxFlow.h:82