51     GCGraph( 
unsigned int vtxCount, 
unsigned int edgeCount );
    53     void create( 
unsigned int vtxCount, 
unsigned int edgeCount );
    55     void addEdges( 
int i, 
int j, TWeight w, TWeight revw );
    59     uchar 
vtxT( 
int i ) 
const;
    81     std::vector<Vtx> vtcs;
    82     std::vector<Edge> edges;
    86 template <
class TWeight>
    91 template <
class TWeight>
    94     create( vtxCount, edgeCount );
    96 template <
class TWeight>
   100 template <
class TWeight>
   103     vtcs.reserve( vtxCount );
   104     edges.reserve( edgeCount + 2 );
   108 template <
class TWeight>
   112     memset( &v, 0, 
sizeof(Vtx));
   114     return (
int)vtcs.size() - 1;
   117 template <
class TWeight>
   120     CV_Assert( i>=0 && i<(
int)vtcs.size() );
   121     CV_Assert( j>=0 && j<(
int)vtcs.size() );
   122     CV_Assert( w>=0 && revw>=0 );
   130     fromI.next = vtcs[i].first;
   132     vtcs[i].first = (int)edges.size();
   133     edges.push_back( fromI );
   136     toI.next = vtcs[j].first;
   138     vtcs[j].first = (int)edges.size();
   139     edges.push_back( toI );
   142 template <
class TWeight>
   145     CV_Assert( i>=0 && i<(
int)vtcs.size() );
   147     TWeight dw = vtcs[i].weight;
   152     flow += (sourceW < sinkW) ? sourceW : sinkW;
   153     vtcs[i].weight = sourceW - sinkW;
   156 template <
class TWeight>
   160     Vtx stub, *nilNode = &stub, *first = nilNode, *last = nilNode;
   163     Vtx *vtxPtr = &vtcs[0];
   164     Edge *edgePtr = &edges[0];
   166     std::vector<Vtx*> orphans;
   169     for( 
int i = 0; i < (int)vtcs.size(); i++ )
   175             last = last->next = v;
   178             v->t = v->weight < 0;
   184     last->next = nilNode;
   191         int e0 = -1, ei = 0, ej = 0;
   192         TWeight minWeight, weight;
   196         while( first != nilNode )
   202                 for( ei = v->first; ei != 0; ei = edgePtr[ei].next )
   204                     if( edgePtr[ei^vt].weight == 0 )
   206                     u = vtxPtr+edgePtr[ei].dst;
   212                         u->dist = v->dist + 1;
   216                             last = last->next = u;
   227                     if( u->dist > v->dist+1 && u->ts <= v->ts )
   232                         u->dist = v->dist + 1;
   247         minWeight = edgePtr[e0].weight;
   248         CV_Assert( minWeight > 0 );
   250         for( 
int k = 1; k >= 0; k-- )
   252             for( v = vtxPtr+edgePtr[e0^k].dst;; v = vtxPtr+edgePtr[ei].dst )
   254                 if( (ei = v->parent) < 0 )
   256                 weight = edgePtr[ei^k].weight;
   257                 minWeight = MIN(minWeight, weight);
   258                 CV_Assert( minWeight > 0 );
   260             weight = fabs(v->weight);
   261             minWeight = MIN(minWeight, weight);
   262             CV_Assert( minWeight > 0 );
   266         edgePtr[e0].weight -= minWeight;
   267         edgePtr[e0^1].weight += minWeight;
   271         for( 
int k = 1; k >= 0; k-- )
   273             for( v = vtxPtr+edgePtr[e0^k].dst;; v = vtxPtr+edgePtr[ei].dst )
   275                 if( (ei = v->parent) < 0 )
   277                 edgePtr[ei^(k^1)].weight += minWeight;
   278                 if( (edgePtr[ei^k].weight -= minWeight) == 0 )
   280                     orphans.push_back(v);
   285             v->weight = v->weight + minWeight*(1-k*2);
   288                orphans.push_back(v);
   295         while( !orphans.empty() )
   297             Vtx* v2 = orphans.back();
   300             int d, minDist = INT_MAX;
   304             for( ei = v2->first; ei != 0; ei = edgePtr[ei].next )
   306                 if( edgePtr[ei^(vt^1)].weight == 0 )
   308                 u = vtxPtr+edgePtr[ei].dst;
   309                 if( u->t != vt || u->parent == 0 )
   314                     if( u->ts == curr_ts )
   332                     u = vtxPtr+edgePtr[ej].dst;
   343                     for( u = vtxPtr+edgePtr[ei].dst; u->ts != curr_ts; u = vtxPtr+edgePtr[u->parent].dst )
   351             if( (v2->parent = e0) > 0 )
   360             for( ei = v2->first; ei != 0; ei = edgePtr[ei].next )
   362                 u = vtxPtr+edgePtr[ei].dst;
   364                 if( u->t != vt || !ej )
   366                 if( edgePtr[ei^(vt^1)].weight && !u->next )
   369                     last = last->next = u;
   371                 if( ej > 0 && vtxPtr+edgePtr[ej].dst == v2 )
   373                     orphans.push_back(u);
   382 template <
class TWeight>
   385     CV_Assert( i>=0 && i<(
int)vtcs.size() );
   386     return vtcs[i].t == 0;
   389 template <
class TWeight>
   392     CV_Assert( i>=0 && i<(
int)vtcs.size() );
 #define ORPHAN
Definition: maxflow.cpp:15
 
uchar vtxT(int i) const 
Definition: GCGraph.hpp:390
 
#define TERMINAL
Definition: maxflow.cpp:14
 
Definition: GCGraph.hpp:45
 
Definition: GCGraph.hpp:47
 
void create(unsigned int vtxCount, unsigned int edgeCount)
Definition: GCGraph.hpp:101
 
bool inSourceSegment(int i)
Definition: GCGraph.hpp:383
 
GCGraph()
Definition: GCGraph.hpp:87
 
void addEdges(int i, int j, TWeight w, TWeight revw)
Definition: GCGraph.hpp:118
 
~GCGraph()
Definition: GCGraph.hpp:97
 
TWeight maxFlow()
Definition: GCGraph.hpp:157
 
void addTermWeights(int i, TWeight sourceW, TWeight sinkW)
Definition: GCGraph.hpp:143
 
int addVtx()
Definition: GCGraph.hpp:109