123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889 |
- /* maxflow.cpp */
- /*
- Copyright 2001 Vladimir Kolmogorov (vnk@cs.cornell.edu), Yuri Boykov (yuri@csd.uwo.ca).
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
- #include <stdio.h>
- #include "graph.h"
- using namespace OBJREC;
- /*
- special constants for node->parent
- */
- #define TERMINAL ( (arc_forward *) 1 ) /* to terminal */
- #define ORPHAN ( (arc_forward *) 2 ) /* orphan */
- #define INFINITE_D 1000000000 /* infinite distance to the terminal */
- /***********************************************************************/
- /*
- Functions for processing active list.
- i->next points to the next node in the list
- (or to i, if i is the last node in the list).
- If i->next is NULL iff i is not in the list.
- There are two queues. Active nodes are added
- to the end of the second queue and read from
- the front of the first queue. If the first queue
- is empty, it is replaced by the second queue
- (and the second queue becomes empty).
- */
- inline void Graph::set_active(node *i)
- {
- if (!i->next)
- {
- /* it's not in the list yet */
- if (queue_last[1]) queue_last[1] -> next = i;
- else queue_first[1] = i;
- queue_last[1] = i;
- i -> next = i;
- }
- }
- /*
- Returns the next active node.
- If it is connected to the sink, it stays in the list,
- otherwise it is removed from the list
- */
- inline Graph::node * Graph::next_active()
- {
- node *i;
- while ( 1 )
- {
- if (!(i = queue_first[0]))
- {
- queue_first[0] = i = queue_first[1];
- queue_last[0] = queue_last[1];
- queue_first[1] = NULL;
- queue_last[1] = NULL;
- if (!i) return NULL;
- }
- /* remove it from the active list */
- if (i->next == i) queue_first[0] = queue_last[0] = NULL;
- else queue_first[0] = i -> next;
- i -> next = NULL;
- /* a node in the list is active iff it has a parent */
- if (i->parent) return i;
- }
- }
- /***********************************************************************/
- void Graph::maxflow_init()
- {
- node *i;
- node_block *nb;
- queue_first[0] = queue_last[0] = NULL;
- queue_first[1] = queue_last[1] = NULL;
- orphan_first = NULL;
- for (nb = node_block_first; nb; nb = nb->next)
- for (i = &nb->nodes[0]; i < nb->current; i++)
- {
- i -> next = NULL;
- i -> TS = 0;
- if (i->tr_cap > 0)
- {
- /* i is connected to the source */
- i -> is_sink = 0;
- i -> parent = TERMINAL;
- set_active(i);
- i -> TS = 0;
- i -> DIST = 1;
- }
- else if (i->tr_cap < 0)
- {
- /* i is connected to the sink */
- i -> is_sink = 1;
- i -> parent = TERMINAL;
- set_active(i);
- i -> TS = 0;
- i -> DIST = 1;
- }
- else
- {
- //seems to be buggy
- i -> parent = NULL;
- i -> is_sink = 1;
- }
- }
- TIME = 0;
- }
- /***********************************************************************/
- void Graph::augment(node *s_start, node *t_start, captype *cap_middle, captype *rev_cap_middle)
- {
- node *i;
- arc_forward *a;
- captype bottleneck;
- nodeptr *np;
- /* 1. Finding bottleneck capacity */
- /* 1a - the source tree */
- bottleneck = *cap_middle;
- for (i = s_start; ; )
- {
- a = i -> parent;
- if (a == TERMINAL) break;
- if (IS_ODD(a))
- {
- a = MAKE_EVEN(a);
- if (bottleneck > a->r_cap) bottleneck = a -> r_cap;
- i = NEIGHBOR_NODE_REV(i, a -> shift);
- }
- else
- {
- if (bottleneck > a->r_rev_cap) bottleneck = a -> r_rev_cap;
- i = NEIGHBOR_NODE(i, a -> shift);
- }
- }
- if (bottleneck > i->tr_cap) bottleneck = i -> tr_cap;
- /* 1b - the sink tree */
- for (i = t_start; ; )
- {
- a = i -> parent;
- if (a == TERMINAL) break;
- if (IS_ODD(a))
- {
- a = MAKE_EVEN(a);
- if (bottleneck > a->r_rev_cap) bottleneck = a -> r_rev_cap;
- i = NEIGHBOR_NODE_REV(i, a -> shift);
- }
- else
- {
- if (bottleneck > a->r_cap) bottleneck = a -> r_cap;
- i = NEIGHBOR_NODE(i, a -> shift);
- }
- }
- if (bottleneck > - i->tr_cap) bottleneck = - i -> tr_cap;
- /* 2. Augmenting */
- /* 2a - the source tree */
- *rev_cap_middle += bottleneck;
- *cap_middle -= bottleneck;
- for (i = s_start; ; )
- {
- a = i -> parent;
- if (a == TERMINAL) break;
- if (IS_ODD(a))
- {
- a = MAKE_EVEN(a);
- a -> r_rev_cap += bottleneck;
- a -> r_cap -= bottleneck;
- if (!a->r_cap)
- {
- /* add i to the adoption list */
- i -> parent = ORPHAN;
- np = nodeptr_block -> New();
- np -> ptr = i;
- np -> next = orphan_first;
- orphan_first = np;
- }
- i = NEIGHBOR_NODE_REV(i, a -> shift);
- }
- else
- {
- a -> r_cap += bottleneck;
- a -> r_rev_cap -= bottleneck;
- if (!a->r_rev_cap)
- {
- /* add i to the adoption list */
- i -> parent = ORPHAN;
- np = nodeptr_block -> New();
- np -> ptr = i;
- np -> next = orphan_first;
- orphan_first = np;
- }
- i = NEIGHBOR_NODE(i, a -> shift);
- }
- }
- i -> tr_cap -= bottleneck;
- if (!i->tr_cap)
- {
- /* add i to the adoption list */
- i -> parent = ORPHAN;
- np = nodeptr_block -> New();
- np -> ptr = i;
- np -> next = orphan_first;
- orphan_first = np;
- }
- /* 2b - the sink tree */
- for (i = t_start; ; )
- {
- a = i -> parent;
- if (a == TERMINAL) break;
- if (IS_ODD(a))
- {
- a = MAKE_EVEN(a);
- a -> r_cap += bottleneck;
- a -> r_rev_cap -= bottleneck;
- if (!a->r_rev_cap)
- {
- /* add i to the adoption list */
- i -> parent = ORPHAN;
- np = nodeptr_block -> New();
- np -> ptr = i;
- np -> next = orphan_first;
- orphan_first = np;
- }
- i = NEIGHBOR_NODE_REV(i, a -> shift);
- }
- else
- {
- a -> r_rev_cap += bottleneck;
- a -> r_cap -= bottleneck;
- if (!a->r_cap)
- {
- /* add i to the adoption list */
- i -> parent = ORPHAN;
- np = nodeptr_block -> New();
- np -> ptr = i;
- np -> next = orphan_first;
- orphan_first = np;
- }
- i = NEIGHBOR_NODE(i, a -> shift);
- }
- }
- i -> tr_cap += bottleneck;
- if (!i->tr_cap)
- {
- /* add i to the adoption list */
- i -> parent = ORPHAN;
- np = nodeptr_block -> New();
- np -> ptr = i;
- np -> next = orphan_first;
- orphan_first = np;
- }
- flow += bottleneck;
- }
- /***********************************************************************/
- void Graph::process_source_orphan(node *i)
- {
- node *j;
- arc_forward *a0_for, *a0_for_first, *a0_for_last;
- arc_reverse *a0_rev, *a0_rev_first, *a0_rev_last;
- arc_forward *a0_min = NULL, *a;
- nodeptr *np;
- int d, d_min = INFINITE_D;
- /* trying to find a new parent */
- a0_for_first = i -> first_out;
- if (IS_ODD(a0_for_first))
- {
- a0_for_first = (arc_forward *) (((char *)a0_for_first) + 1);
- a0_for_last = (arc_forward *) ((a0_for_first ++) -> shift);
- }
- else a0_for_last = (i + 1) -> first_out;
- a0_rev_first = i -> first_in;
- if (IS_ODD(a0_rev_first))
- {
- a0_rev_first = (arc_reverse *) (((char *)a0_rev_first) + 1);
- a0_rev_last = (arc_reverse *) ((a0_rev_first ++) -> sister);
- }
- else a0_rev_last = (i + 1) -> first_in;
- for (a0_for = a0_for_first; a0_for < a0_for_last; a0_for++)
- if (a0_for->r_rev_cap)
- {
- j = NEIGHBOR_NODE(i, a0_for -> shift);
- if ((a = j->parent) && !j->is_sink)
- {
- /* checking the origin of j */
- d = 0;
- while ( 1 )
- {
- if (j->TS == TIME)
- {
- d += j -> DIST;
- break;
- }
- a = j -> parent;
- d ++;
- if (a == TERMINAL)
- {
- j -> TS = TIME;
- j -> DIST = 1;
- break;
- }
- if (a == ORPHAN) {
- d = INFINITE_D;
- break;
- }
- if (IS_ODD(a))
- j = NEIGHBOR_NODE_REV(j, MAKE_EVEN(a) -> shift);
- else
- j = NEIGHBOR_NODE(j, a -> shift);
- }
- if (d < INFINITE_D) /* j originates from the source - done */
- {
- if (d < d_min)
- {
- a0_min = a0_for;
- d_min = d;
- }
- /* set marks along the path */
- for (j = NEIGHBOR_NODE(i, a0_for->shift); j->TS != TIME; )
- {
- j -> TS = TIME;
- j -> DIST = d --;
- a = j->parent;
- if (IS_ODD(a))
- j = NEIGHBOR_NODE_REV(j, MAKE_EVEN(a) -> shift);
- else
- j = NEIGHBOR_NODE(j, a -> shift);
- }
- }
- }
- }
- for (a0_rev = a0_rev_first; a0_rev < a0_rev_last; a0_rev++)
- {
- a0_for = a0_rev -> sister;
- if (a0_for->r_cap)
- {
- j = NEIGHBOR_NODE_REV(i, a0_for -> shift);
- if (!j->is_sink && (a = j->parent))
- {
- /* checking the origin of j */
- d = 0;
- while ( 1 )
- {
- if (j->TS == TIME)
- {
- d += j -> DIST;
- break;
- }
- a = j -> parent;
- d ++;
- if (a == TERMINAL)
- {
- j -> TS = TIME;
- j -> DIST = 1;
- break;
- }
- if (a == ORPHAN) {
- d = INFINITE_D;
- break;
- }
- if (IS_ODD(a))
- j = NEIGHBOR_NODE_REV(j, MAKE_EVEN(a) -> shift);
- else
- j = NEIGHBOR_NODE(j, a -> shift);
- }
- if (d < INFINITE_D) /* j originates from the source - done */
- {
- if (d < d_min)
- {
- a0_min = MAKE_ODD(a0_for);
- d_min = d;
- }
- /* set marks along the path */
- for (j = NEIGHBOR_NODE_REV(i, a0_for->shift); j->TS != TIME; )
- {
- j -> TS = TIME;
- j -> DIST = d --;
- a = j->parent;
- if (IS_ODD(a))
- j = NEIGHBOR_NODE_REV(j, MAKE_EVEN(a) -> shift);
- else
- j = NEIGHBOR_NODE(j, a -> shift);
- }
- }
- }
- }
- }
- if (i->parent = a0_min)
- {
- i -> TS = TIME;
- i -> DIST = d_min + 1;
- }
- else
- {
- /* no parent is found */
- i -> TS = 0;
- /* process neighbors */
- for (a0_for = a0_for_first; a0_for < a0_for_last; a0_for++)
- {
- j = NEIGHBOR_NODE(i, a0_for -> shift);
- if (!j->is_sink && (a = j->parent))
- {
- if (a0_for->r_rev_cap) set_active(j);
- if (a != TERMINAL && a != ORPHAN && IS_ODD(a) && NEIGHBOR_NODE_REV(j, MAKE_EVEN(a)->shift) == i)
- {
- /* add j to the adoption list */
- j -> parent = ORPHAN;
- np = nodeptr_block -> New();
- np -> ptr = j;
- if (orphan_last) orphan_last -> next = np;
- else orphan_first = np;
- orphan_last = np;
- np -> next = NULL;
- }
- }
- }
- for (a0_rev = a0_rev_first; a0_rev < a0_rev_last; a0_rev++)
- {
- a0_for = a0_rev -> sister;
- j = NEIGHBOR_NODE_REV(i, a0_for -> shift);
- if (!j->is_sink && (a = j->parent))
- {
- if (a0_for->r_cap) set_active(j);
- if (a != TERMINAL && a != ORPHAN && !IS_ODD(a) && NEIGHBOR_NODE(j, a->shift) == i)
- {
- /* add j to the adoption list */
- j -> parent = ORPHAN;
- np = nodeptr_block -> New();
- np -> ptr = j;
- if (orphan_last) orphan_last -> next = np;
- else orphan_first = np;
- orphan_last = np;
- np -> next = NULL;
- }
- }
- }
- }
- }
- void Graph::process_sink_orphan(node *i)
- {
- node *j;
- arc_forward *a0_for, *a0_for_first, *a0_for_last;
- arc_reverse *a0_rev, *a0_rev_first, *a0_rev_last;
- arc_forward *a0_min = NULL, *a;
- nodeptr *np;
- int d, d_min = INFINITE_D;
- /* trying to find a new parent */
- a0_for_first = i -> first_out;
- if (IS_ODD(a0_for_first))
- {
- a0_for_first = (arc_forward *) (((char *)a0_for_first) + 1);
- a0_for_last = (arc_forward *) ((a0_for_first ++) -> shift);
- }
- else a0_for_last = (i + 1) -> first_out;
- a0_rev_first = i -> first_in;
- if (IS_ODD(a0_rev_first))
- {
- a0_rev_first = (arc_reverse *) (((char *)a0_rev_first) + 1);
- a0_rev_last = (arc_reverse *) ((a0_rev_first ++) -> sister);
- }
- else a0_rev_last = (i + 1) -> first_in;
- for (a0_for = a0_for_first; a0_for < a0_for_last; a0_for++)
- if (a0_for->r_cap)
- {
- j = NEIGHBOR_NODE(i, a0_for -> shift);
- if (j->is_sink && (a = j->parent))
- {
- /* checking the origin of j */
- d = 0;
- while ( 1 )
- {
- if (j->TS == TIME)
- {
- d += j -> DIST;
- break;
- }
- a = j -> parent;
- d ++;
- if (a == TERMINAL)
- {
- j -> TS = TIME;
- j -> DIST = 1;
- break;
- }
- if (a == ORPHAN) {
- d = INFINITE_D;
- break;
- }
- if (IS_ODD(a))
- j = NEIGHBOR_NODE_REV(j, MAKE_EVEN(a) -> shift);
- else
- j = NEIGHBOR_NODE(j, a -> shift);
- }
- if (d < INFINITE_D) /* j originates from the sink - done */
- {
- if (d < d_min)
- {
- a0_min = a0_for;
- d_min = d;
- }
- /* set marks along the path */
- for (j = NEIGHBOR_NODE(i, a0_for->shift); j->TS != TIME; )
- {
- j -> TS = TIME;
- j -> DIST = d --;
- a = j->parent;
- if (IS_ODD(a))
- j = NEIGHBOR_NODE_REV(j, MAKE_EVEN(a) -> shift);
- else
- j = NEIGHBOR_NODE(j, a -> shift);
- }
- }
- }
- }
- for (a0_rev = a0_rev_first; a0_rev < a0_rev_last; a0_rev++)
- {
- a0_for = a0_rev -> sister;
- if (a0_for->r_rev_cap)
- {
- j = NEIGHBOR_NODE_REV(i, a0_for -> shift);
- if (j->is_sink && (a = j->parent))
- {
- /* checking the origin of j */
- d = 0;
- while ( 1 )
- {
- if (j->TS == TIME)
- {
- d += j -> DIST;
- break;
- }
- a = j -> parent;
- d ++;
- if (a == TERMINAL)
- {
- j -> TS = TIME;
- j -> DIST = 1;
- break;
- }
- if (a == ORPHAN) {
- d = INFINITE_D;
- break;
- }
- if (IS_ODD(a))
- j = NEIGHBOR_NODE_REV(j, MAKE_EVEN(a) -> shift);
- else
- j = NEIGHBOR_NODE(j, a -> shift);
- }
- if (d < INFINITE_D) /* j originates from the sink - done */
- {
- if (d < d_min)
- {
- a0_min = MAKE_ODD(a0_for);
- d_min = d;
- }
- /* set marks along the path */
- for (j = NEIGHBOR_NODE_REV(i, a0_for->shift); j->TS != TIME; )
- {
- j -> TS = TIME;
- j -> DIST = d --;
- a = j->parent;
- if (IS_ODD(a))
- j = NEIGHBOR_NODE_REV(j, MAKE_EVEN(a) -> shift);
- else
- j = NEIGHBOR_NODE(j, a -> shift);
- }
- }
- }
- }
- }
- if (i->parent = a0_min)
- {
- i -> TS = TIME;
- i -> DIST = d_min + 1;
- }
- else
- {
- /* no parent is found */
- i -> TS = 0;
- /* process neighbors */
- for (a0_for = a0_for_first; a0_for < a0_for_last; a0_for++)
- {
- j = NEIGHBOR_NODE(i, a0_for -> shift);
- if (j->is_sink && (a = j->parent))
- {
- if (a0_for->r_cap) set_active(j);
- if (a != TERMINAL && a != ORPHAN && IS_ODD(a) && NEIGHBOR_NODE_REV(j, MAKE_EVEN(a)->shift) == i)
- {
- /* add j to the adoption list */
- j -> parent = ORPHAN;
- np = nodeptr_block -> New();
- np -> ptr = j;
- if (orphan_last) orphan_last -> next = np;
- else orphan_first = np;
- orphan_last = np;
- np -> next = NULL;
- }
- }
- }
- for (a0_rev = a0_rev_first; a0_rev < a0_rev_last; a0_rev++)
- {
- a0_for = a0_rev -> sister;
- j = NEIGHBOR_NODE_REV(i, a0_for -> shift);
- if (j->is_sink && (a = j->parent))
- {
- if (a0_for->r_rev_cap) set_active(j);
- if (a != TERMINAL && a != ORPHAN && !IS_ODD(a) && NEIGHBOR_NODE(j, a->shift) == i)
- {
- /* add j to the adoption list */
- j -> parent = ORPHAN;
- np = nodeptr_block -> New();
- np -> ptr = j;
- if (orphan_last) orphan_last -> next = np;
- else orphan_first = np;
- orphan_last = np;
- np -> next = NULL;
- }
- }
- }
- }
- }
- /***********************************************************************/
- Graph::flowtype Graph::maxflow()
- {
- node *i, *j, *current_node = NULL, *s_start, *t_start;
- captype *cap_middle, *rev_cap_middle;
- arc_forward *a_for, *a_for_first, *a_for_last;
- arc_reverse *a_rev, *a_rev_first, *a_rev_last;
- nodeptr *np, *np_next;
- prepare_graph();
- maxflow_init();
- nodeptr_block = new DBlock<nodeptr>(NODEPTR_BLOCK_SIZE, error_function);
- while ( 1 )
- {
- if (i = current_node)
- {
- i -> next = NULL; /* remove active flag */
- if (!i->parent) i = NULL;
- }
- if (!i)
- {
- if (!(i = next_active())) break;
- }
- /* growth */
- s_start = NULL;
- a_for_first = i -> first_out;
- if (IS_ODD(a_for_first))
- {
- a_for_first = (arc_forward *) (((char *)a_for_first) + 1);
- a_for_last = (arc_forward *) ((a_for_first ++) -> shift);
- }
- else a_for_last = (i + 1) -> first_out;
- a_rev_first = i -> first_in;
- if (IS_ODD(a_rev_first))
- {
- a_rev_first = (arc_reverse *) (((char *)a_rev_first) + 1);
- a_rev_last = (arc_reverse *) ((a_rev_first ++) -> sister);
- }
- else a_rev_last = (i + 1) -> first_in;
- if (!i->is_sink)
- {
- /* grow source tree */
- for (a_for = a_for_first; a_for < a_for_last; a_for++)
- if (a_for->r_cap)
- {
- j = NEIGHBOR_NODE(i, a_for -> shift);
- if (!j->parent)
- {
- j -> is_sink = 0;
- j -> parent = MAKE_ODD(a_for);
- j -> TS = i -> TS;
- j -> DIST = i -> DIST + 1;
- set_active(j);
- }
- else if (j->is_sink)
- {
- s_start = i;
- t_start = j;
- cap_middle = & ( a_for -> r_cap );
- rev_cap_middle = & ( a_for -> r_rev_cap );
- break;
- }
- else if (j->TS <= i->TS &&
- j->DIST > i->DIST)
- {
- /* heuristic - trying to make the distance from j to the source shorter */
- j -> parent = MAKE_ODD(a_for);
- j -> TS = i -> TS;
- j -> DIST = i -> DIST + 1;
- }
- }
- if (!s_start)
- for (a_rev = a_rev_first; a_rev < a_rev_last; a_rev++)
- {
- a_for = a_rev -> sister;
- if (a_for->r_rev_cap)
- {
- j = NEIGHBOR_NODE_REV(i, a_for -> shift);
- if (!j->parent)
- {
- j -> is_sink = 0;
- j -> parent = a_for;
- j -> TS = i -> TS;
- j -> DIST = i -> DIST + 1;
- set_active(j);
- }
- else if (j->is_sink)
- {
- s_start = i;
- t_start = j;
- cap_middle = & ( a_for -> r_rev_cap );
- rev_cap_middle = & ( a_for -> r_cap );
- break;
- }
- else if (j->TS <= i->TS &&
- j->DIST > i->DIST)
- {
- /* heuristic - trying to make the distance from j to the source shorter */
- j -> parent = a_for;
- j -> TS = i -> TS;
- j -> DIST = i -> DIST + 1;
- }
- }
- }
- }
- else
- {
- /* grow sink tree */
- for (a_for = a_for_first; a_for < a_for_last; a_for++)
- if (a_for->r_rev_cap)
- {
- j = NEIGHBOR_NODE(i, a_for -> shift);
- if (!j->parent)
- {
- j -> is_sink = 1;
- j -> parent = MAKE_ODD(a_for);
- j -> TS = i -> TS;
- j -> DIST = i -> DIST + 1;
- set_active(j);
- }
- else if (!j->is_sink)
- {
- s_start = j;
- t_start = i;
- cap_middle = & ( a_for -> r_rev_cap );
- rev_cap_middle = & ( a_for -> r_cap );
- break;
- }
- else if (j->TS <= i->TS &&
- j->DIST > i->DIST)
- {
- /* heuristic - trying to make the distance from j to the sink shorter */
- j -> parent = MAKE_ODD(a_for);
- j -> TS = i -> TS;
- j -> DIST = i -> DIST + 1;
- }
- }
- for (a_rev = a_rev_first; a_rev < a_rev_last; a_rev++)
- {
- a_for = a_rev -> sister;
- if (a_for->r_cap)
- {
- j = NEIGHBOR_NODE_REV(i, a_for -> shift);
- if (!j->parent)
- {
- j -> is_sink = 1;
- j -> parent = a_for;
- j -> TS = i -> TS;
- j -> DIST = i -> DIST + 1;
- set_active(j);
- }
- else if (!j->is_sink)
- {
- s_start = j;
- t_start = i;
- cap_middle = & ( a_for -> r_cap );
- rev_cap_middle = & ( a_for -> r_rev_cap );
- break;
- }
- else if (j->TS <= i->TS &&
- j->DIST > i->DIST)
- {
- /* heuristic - trying to make the distance from j to the sink shorter */
- j -> parent = a_for;
- j -> TS = i -> TS;
- j -> DIST = i -> DIST + 1;
- }
- }
- }
- }
- TIME ++;
- if (s_start)
- {
- i -> next = i; /* set active flag */
- current_node = i;
- /* augmentation */
- augment(s_start, t_start, cap_middle, rev_cap_middle);
- /* augmentation end */
- /* adoption */
- while (np = orphan_first)
- {
- np_next = np -> next;
- np -> next = NULL;
- while (np = orphan_first)
- {
- orphan_first = np -> next;
- i = np -> ptr;
- nodeptr_block -> Delete(np);
- if (!orphan_first) orphan_last = NULL;
- if (i->is_sink) process_sink_orphan(i);
- else process_source_orphan(i);
- }
- orphan_first = np_next;
- }
- /* adoption end */
- }
- else current_node = NULL;
- }
- delete nodeptr_block;
- return flow;
- }
- /***********************************************************************/
- Graph::termtype Graph::what_segment(node_id i)
- {
- if (((node*)i)->parent && !((node*)i)->is_sink) return SOURCE;
- return SINK;
- }
|