Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

pushrelabel_non_linear_grid_3D.h

Go to the documentation of this file.
00001 
00102 #ifndef __PUSHRELABEL_NON_LINEAR_GRID_3D__
00103 #define __PUSHRELABEL_NON_LINEAR_GRID_3D__
00104 
00105 
00106 
00107 #include <algorithm>
00108 #include <deque>
00109 #include <iterator>
00110 
00111 #ifndef WITHOUT_LIMITS
00112 #include <limits>
00113 #endif
00114 
00115 #include <list>
00116 #include <vector>
00117 
00118 #include "array.h"
00119 #include "geom.h"
00120 #include "msg_stream.h"
00121 
00122 
00123 
00124 namespace Graph_cut{
00125 
00126   
00127 
00128 /*
00129 
00130 ###################################
00131 #  PushRelabel_non_linear_grid_3D #
00132 ###################################
00133 
00134 */
00135 
00136 
00137 
00140 
00144   template<typename Real>
00145   class PushRelabel_non_linear_grid_3D{
00146 
00147   public:
00148   
00150 
00151  
00152     typedef Real                      real_type;
00153     typedef Array_3D<bool>::size_type size_type;
00155 
00157     PushRelabel_non_linear_grid_3D(
00158       const Array_3D<real_type>& cost_edge_cap,
00159       const Array_3D<bool>&      dom,
00160       const Array_2D<real_type>& x_derivative_edge_cap,
00161       const Array_2D<real_type>& y_derivative_edge_cap,
00162       const real_type            eps = 1e-3);
00163 
00165     real_type max_flow();
00166 
00168     void min_cut(Array_2D<size_type>* const cut) const;
00169 
00170 //  private:
00171 
00172     bool DBG_LOGGING;
00173   
00175 
00176   
00177     typedef Geometry::Vec3<unsigned int> position_type;
00178     typedef unsigned int                 index_type;
00179     typedef unsigned int                 label_type;
00181 
00183 
00184     typedef char direction_type;
00185   
00186     static const direction_type X_MIN_DIR       = 1;
00187     static const direction_type X_MAX_DIR       = 2;
00188 
00189     static const direction_type Y_MIN_DIR       = 3;
00190     static const direction_type Y_MAX_DIR       = 4;
00191 
00192     static const direction_type Z_MIN_x_min_DIR = 5;
00193     static const direction_type Z_MIN_x_max_DIR = 6;
00194     static const direction_type Z_MIN_y_min_DIR = 7;
00195     static const direction_type Z_MIN_y_max_DIR = 8;
00196   
00197     static const direction_type Z_MAX_x_min_DIR = 9;
00198     static const direction_type Z_MAX_x_max_DIR = 10;
00199     static const direction_type Z_MAX_y_min_DIR = 11;
00200     static const direction_type Z_MAX_y_max_DIR = 12;
00202 
00204 
00205     typedef char location_type;
00206 
00207     static const location_type CENTER_NODE      = 100;
00208     static const location_type Z_MAX_x_min_NODE = 101;
00209     static const location_type Z_MAX_x_max_NODE = 102;
00210     static const location_type Z_MAX_y_min_NODE = 103;
00211     static const location_type Z_MAX_y_max_NODE = 104;
00213 
00215     struct node_type{
00216       position_type pos;
00217       location_type loc;
00218 
00219       inline node_type(){}
00220       inline node_type(const position_type& p,const location_type l):pos(p),loc(l){}
00221       inline bool operator==(const node_type& n) const {
00222         return (pos==n.pos)&&(loc==n.loc);
00223       }
00224       inline bool operator!=(const node_type& n) const {
00225         return !((pos==n.pos)&&(loc==n.loc));
00226       }
00227     };
00228 
00230     const real_type epsilon;
00231 
00233     size_type nb_nodes;
00234 
00236     size_type nb_relabel;
00237   
00239     Array_3D<real_type> cost_edge_capacity;
00240 
00243     const Array_3D<bool>& domain;
00244 
00246 
00247   
00248     Array_2D<real_type> x_major_derivative_edge_capacity;
00249     Array_2D<real_type> x_minor_derivative_edge_capacity;
00250 
00251     Array_2D<real_type> y_major_derivative_edge_capacity;
00252     Array_2D<real_type> y_minor_derivative_edge_capacity;
00254 
00256 
00257 
00258     Array_3D<index_type> label_CENTER;
00259     Array_3D<index_type> label_Z_MAX_x_min;
00260     Array_3D<index_type> label_Z_MAX_x_max;
00261     Array_3D<index_type> label_Z_MAX_y_min;
00262     Array_3D<index_type> label_Z_MAX_y_max;
00264 
00266 
00267 
00269     Array_3D<real_type> cost_edge_Z_MAX_x_min_flow;
00270     Array_3D<real_type> cost_edge_Z_MAX_x_max_flow;
00271     Array_3D<real_type> cost_edge_Z_MAX_y_min_flow;
00272     Array_3D<real_type> cost_edge_Z_MAX_y_max_flow;
00273   
00274     Array_3D<real_type> cost_edge_Z_MAX_MAX_x_min_flow;
00275     Array_3D<real_type> cost_edge_Z_MAX_MAX_x_max_flow;
00276     Array_3D<real_type> cost_edge_Z_MAX_MAX_y_min_flow;
00277     Array_3D<real_type> cost_edge_Z_MAX_MAX_y_max_flow;
00279 
00281 
00282 
00284     Array_3D<real_type> x_major_derivative_edge_flow;
00285     Array_3D<real_type> y_major_derivative_edge_flow;
00286   
00287     Array_3D<real_type> x_minor_derivative_edge_flow;
00288     Array_3D<real_type> y_minor_derivative_edge_flow;
00290 
00292     Array_2D<size_type> min_bound;
00293 
00295     Array_2D<size_type> max_bound;
00296 
00298     std::deque<index_type> active_node_index;
00299   
00301     const node_type source;
00302 
00304     const node_type target;
00305 
00307 
00308 
00309     const size_type x_size,y_size,z_size;
00311 
00312 
00314     inline void to_index(const node_type& p,
00315                          size_type* const i) const;
00316 
00318     inline void from_index(node_type* const p,
00319                            const size_type i) const;
00320 
00322 
00323   
00324     inline const label_type& label(const node_type& node) const;
00325     inline label_type& label(const node_type& node);
00327   
00329     inline void neighbors(const node_type& node,
00330                           node_type* const result,
00331                           size_type* const n_res) const;
00332   
00334     inline void adjacent_nodes(const node_type& node,
00335                                node_type* const result,
00336                                size_type* const n_res) const;
00337 
00339     inline real_type edge_capacity(const node_type&     from,
00340                                    const direction_type dir) const;
00341 
00343     inline real_type edge_flow(const node_type&     from,
00344                                const direction_type dir) const;
00345 
00346 
00348     inline real_type edge_residual(const node_type&     from,
00349                                    const direction_type dir) const;
00350 
00352     inline real_type node_excess(const node_type& node) const;
00353   
00354 
00356     inline void add_flow(const node_type&     from,
00357                          const direction_type dir,
00358                          const real_type      flow);
00359 
00361     inline direction_type direction(const node_type& from,
00362                                     const node_type& to) const;
00363 
00365     inline label_type relabel(const node_type& node);
00366 
00368     void global_relabel();
00369 
00371     inline bool discharge(const node_type& node);
00372 
00374     inline void add_active_node(const node_type& node);
00375 
00377     inline void get_next_node(node_type* const node,
00378                               bool* const      no_more_node);
00379 
00381     inline bool is_active(const node_type& node) const;
00382 
00384     inline bool is_admissible(const node_type& from,
00385                               const node_type& to) const;
00386 
00387 
00388   };
00389 
00390 
00391 
00392 
00393   
00394 /*
00395   
00396 #############################################
00397 #############################################
00398 #############################################
00399 ######                                 ######
00400 ######   I M P L E M E N T A T I O N   ######
00401 ######                                 ######
00402 #############################################
00403 #############################################
00404 #############################################
00405   
00406 */
00407 
00408 
00409 
00410   
00411 /*
00412 
00413 ########################################
00414 # class PushRelabel_non_linear_grid_3D #
00415 ########################################
00416 
00417 */
00418 
00419 
00420 
00421 
00422 
00433   template<typename Real>
00434   PushRelabel_non_linear_grid_3D<Real>::
00435   PushRelabel_non_linear_grid_3D(
00436     const Array_3D<real_type>& cost_edge_cap,
00437     const Array_3D<bool>&      dom,
00438     const Array_2D<real_type>& x_derivative_edge_cap,
00439     const Array_2D<real_type>& y_derivative_edge_cap,
00440     const real_type            eps)
00441     :epsilon(eps),
00442      nb_nodes(2),
00443      nb_relabel(0),
00444      //cost_edge_capacity(cost_edge_cap),
00445      domain(dom),
00446      DBG_LOGGING(false),
00447    
00448      x_major_derivative_edge_capacity(x_derivative_edge_cap),
00449      x_minor_derivative_edge_capacity(x_derivative_edge_cap),
00450 
00451      y_major_derivative_edge_capacity(y_derivative_edge_cap),
00452      y_minor_derivative_edge_capacity(y_derivative_edge_cap),
00453    
00454      cost_edge_Z_MAX_x_min_flow(dom.x_size(),dom.y_size(),dom.z_size(),0),
00455      cost_edge_Z_MAX_x_max_flow(dom.x_size(),dom.y_size(),dom.z_size(),0),
00456      cost_edge_Z_MAX_y_min_flow(dom.x_size(),dom.y_size(),dom.z_size(),0),
00457      cost_edge_Z_MAX_y_max_flow(dom.x_size(),dom.y_size(),dom.z_size(),0),
00458    
00459      cost_edge_Z_MAX_MAX_x_min_flow(dom.x_size(),dom.y_size(),dom.z_size(),0),
00460      cost_edge_Z_MAX_MAX_x_max_flow(dom.x_size(),dom.y_size(),dom.z_size(),0),
00461      cost_edge_Z_MAX_MAX_y_min_flow(dom.x_size(),dom.y_size(),dom.z_size(),0),
00462      cost_edge_Z_MAX_MAX_y_max_flow(dom.x_size(),dom.y_size(),dom.z_size(),0),
00463    
00464      x_major_derivative_edge_flow(dom.x_size(),dom.y_size(),dom.z_size()+1,0),
00465      x_minor_derivative_edge_flow(dom.x_size(),dom.y_size(),dom.z_size()+1,0),
00466      y_major_derivative_edge_flow(dom.x_size(),dom.y_size(),dom.z_size()+1,0),
00467      y_minor_derivative_edge_flow(dom.x_size(),dom.y_size(),dom.z_size()+1,0),
00468 
00469      label_CENTER(dom.x_size(),dom.y_size(),dom.z_size()+1,0),
00470      label_Z_MAX_x_min(dom.x_size(),dom.y_size(),dom.z_size()+1,0),
00471      label_Z_MAX_x_max(dom.x_size(),dom.y_size(),dom.z_size()+1,0),
00472      label_Z_MAX_y_min(dom.x_size(),dom.y_size(),dom.z_size()+1,0),
00473      label_Z_MAX_y_max(dom.x_size(),dom.y_size(),dom.z_size()+1,0),
00474    
00475      min_bound(dom.x_size(),dom.y_size()),
00476      max_bound(dom.x_size(),dom.y_size()),
00477    
00478      x_size(dom.x_size()),
00479      y_size(dom.y_size()),
00480      z_size(dom.z_size()),
00481 
00482 #ifndef WITHOUT_LIMITS
00483      source(position_type(std::numeric_limits<size_type>::max(),
00484                           std::numeric_limits<size_type>::max(),
00485                           std::numeric_limits<size_type>::max()),CENTER_NODE),
00486      target(position_type(std::numeric_limits<size_type>::max()-1,
00487                           std::numeric_limits<size_type>::max()-1,
00488                           std::numeric_limits<size_type>::max()-1),CENTER_NODE)
00489 #else
00490      source(position_type(static_cast<size_type>(4294967295),
00491                           static_cast<size_type>(4294967295),
00492                           static_cast<size_type>(4294967295)),CENTER_NODE),
00493      target(position_type(static_cast<size_type>(4294967294),
00494                           static_cast<size_type>(4294967294),
00495                           static_cast<size_type>(4294967294)),CENTER_NODE)
00496 #endif
00497   {
00498 
00499     // Computes the top and bottom boundaries of the optimization domain.
00500     for(size_type x=0;x<x_size;x++){
00501       for(size_type y=0;y<y_size;y++){
00502       
00503         size_type top = 0;
00504         bool found = false;
00505     
00506         for(top=0;(top<z_size)&&(!found);top++){
00507           found = domain(x,y,top);
00508         }
00509         min_bound(x,y) = top-1; // -1 because we are one step too far.
00510       
00511         add_active_node(node_type(position_type(x,y,min_bound(x,y)),CENTER_NODE));
00512       
00513         size_type bottom = 0;
00514         found = false;
00515         for(bottom=0;(bottom<z_size)&&(!found);bottom++){
00516           found = domain(x,y,z_size-1-bottom);
00517         }
00518         max_bound(x,y) = z_size - bottom + 1;
00519       // +1 because we are one step too far
00520       //and we takethe  MAX node of the edge [MIN;MAX]
00521 
00522       }//end of for y
00523     }// end of for x
00524 
00525 //    for(size_type x=0;x<x_size;x++){
00526 //      for(size_type y=0;y<y_size;y++){
00527 //        if ((max_bound(x,y)-min_bound(x,y))<=3){
00528 //      std::cout<<x<<"\t"<<y<<"\t"
00529 //               <<VALUE_OF(min_bound(x,y))<<"\t"
00530 //               <<VALUE_OF(max_bound(x,y))<<std::endl;
00531 //        }
00532 //      }
00533 //    }
00534 
00535 //    exit(0);
00536 
00537 
00538     for(size_type x=0;x<x_size;x++){
00539       for(size_type y=0;y<y_size;y++){
00540         
00541         x_major_derivative_edge_capacity(x,y) *= 1.0;
00542         x_minor_derivative_edge_capacity(x,y) *= 1.0;
00543       
00544         y_major_derivative_edge_capacity(x,y) *= 1.0;
00545         y_minor_derivative_edge_capacity(x,y) *= 1.0;
00546         
00547         /*      
00548         x_major_derivative_edge_capacity(x,y) *= 2.0;
00549         x_minor_derivative_edge_capacity(x,y) *= .0;
00550 
00551         y_major_derivative_edge_capacity(x,y) *= 2.0;
00552         y_minor_derivative_edge_capacity(x,y) *= .0;
00553         */
00554       }
00555     }
00556 
00557     real_type max_minor = 0;
00558     for(size_type x=0;x<x_size;x++){
00559       for(size_type y=0;y<y_size;y++){
00560         if (max_minor < x_minor_derivative_edge_capacity(x,y)){
00561           max_minor = x_minor_derivative_edge_capacity(x,y);
00562         }
00563         if (max_minor < y_minor_derivative_edge_capacity(x,y)){
00564           max_minor = y_minor_derivative_edge_capacity(x,y);
00565         }
00566       }
00567     }
00568   
00569     cost_edge_capacity.resize(x_size,y_size,z_size);
00570   
00571     for(size_type x=0;x<x_size;x++){
00572       for(size_type y=0;y<y_size;y++){
00573         for(size_type z=0;z<z_size;z++){
00574           cost_edge_capacity(x,y,z) = cost_edge_cap(x,y,z)/4 + max_minor;
00575 
00576           if (domain(x,y,z)){
00577             nb_nodes += 12;
00578           }
00579         }
00580       }
00581     }
00582 
00583 //    std::cout<<VALUE_OF(max_minor)<<std::endl;
00584   }
00585 
00586 
00587   template<typename Real>
00588   void 
00589   PushRelabel_non_linear_grid_3D<Real>::
00590   to_index(const node_type& p,
00591            index_type* const i) const{
00592 
00593     if (p==source) {
00594 #ifndef WITHOUT_LIMITS
00595       *i = std::numeric_limits<index_type>::max();
00596 #else
00597       *i = static_cast<size_type>(4294967295);
00598 #endif
00599     }
00600     else if (p==target){
00601 #ifndef WITHOUT_LIMITS
00602       *i = std::numeric_limits<index_type>::max()-1;
00603 #else
00604       *i = static_cast<size_type>(4294967294);
00605 #endif
00606     }
00607     else{
00608     
00609       *i = ((p.pos.x() * y_size * z_size) + (p.pos.y() * z_size) + p.pos.z()) * 5;
00610       switch(p.loc){
00611       case CENTER_NODE:
00612         break;
00613 
00614       case Z_MAX_x_min_NODE:
00615         *i += 1;
00616         break;
00617 
00618       case Z_MAX_x_max_NODE:
00619         *i += 2;
00620         break;
00621 
00622       case Z_MAX_y_min_NODE:
00623         *i += 3;
00624         break;
00625 
00626       case Z_MAX_y_max_NODE:
00627         *i += 4;
00628         break;  
00629 
00630       default:
00631         Message::error<<"to_index: unknown value of p.loc"<<Message::done;
00632       }
00633     
00634     }
00635   }
00636 
00637 
00638   template<typename Real>
00639   void
00640   PushRelabel_non_linear_grid_3D<Real>::
00641   from_index(node_type* const p,
00642              const index_type i) const{
00643 
00644 #ifndef WITHOUT_LIMITS
00645     if (i==std::numeric_limits<index_type>::max()){
00646 #else
00647     if (i==static_cast<size_type>(4294967295)){
00648 #endif
00649       *p = source;
00650     }
00651 #ifndef WITHOUT_LIMITS
00652     else if (i==std::numeric_limits<index_type>::max()-1){
00653 #else
00654     else if (i==static_cast<size_type>(4294967294)){
00655 #endif
00656       *p = target;
00657     }
00658     else{
00659       switch(i%5){
00660       case 0:
00661         p->loc = CENTER_NODE;
00662         break;
00663       case 1:
00664         p->loc = Z_MAX_x_min_NODE;
00665         break;
00666       case 2:
00667         p->loc = Z_MAX_x_max_NODE;
00668         break;
00669       case 3:
00670         p->loc = Z_MAX_y_min_NODE;
00671         break;
00672       case 4:
00673         p->loc = Z_MAX_y_max_NODE;
00674         break;
00675       }
00676 
00677       const index_type j = i/5;
00678       p->pos.x() = j / (y_size * z_size);
00679       p->pos.y() = (j / z_size) -  (p->pos.x() * y_size);
00680       p->pos.z() = j % z_size;
00681     }
00682   }
00683 
00684 
00685   template<typename Real>
00686   const typename PushRelabel_non_linear_grid_3D<Real>::label_type&
00687   PushRelabel_non_linear_grid_3D<Real>::label(const node_type& node) const{
00688   
00689     switch(node.loc){
00690     case CENTER_NODE:      return label_CENTER[node.pos];
00691     case Z_MAX_x_min_NODE: return label_Z_MAX_x_min[node.pos];
00692     case Z_MAX_x_max_NODE: return label_Z_MAX_x_max[node.pos];
00693     case Z_MAX_y_min_NODE: return label_Z_MAX_y_min[node.pos];
00694     case Z_MAX_y_max_NODE: return label_Z_MAX_y_max[node.pos];
00695     }
00696 
00697     Message::error<<"label : non expected exit"<<Message::done;
00698     return label_CENTER[node.pos];
00699   }
00700 
00701 
00702   template<typename Real>
00703   typename PushRelabel_non_linear_grid_3D<Real>::label_type&
00704   PushRelabel_non_linear_grid_3D<Real>::label(const node_type& node){
00705   
00706     switch(node.loc){
00707     case CENTER_NODE:      return label_CENTER[node.pos];
00708     case Z_MAX_x_min_NODE: return label_Z_MAX_x_min[node.pos];
00709     case Z_MAX_x_max_NODE: return label_Z_MAX_x_max[node.pos];
00710     case Z_MAX_y_min_NODE: return label_Z_MAX_y_min[node.pos];
00711     case Z_MAX_y_max_NODE: return label_Z_MAX_y_max[node.pos];
00712     }
00713 
00714     Message::error<<"label : non expected exit"<<Message::done;
00715     return label_CENTER[node.pos];
00716   }
00717 
00718 
00719 
00723   template<typename Real>
00724   typename PushRelabel_non_linear_grid_3D<Real>::real_type
00725   PushRelabel_non_linear_grid_3D<Real>::
00726   edge_capacity(const node_type&     from,
00727                 const direction_type dir) const{
00728 
00729     switch(from.loc){
00730       // ########################### CENTER_NODE ###########################
00731     case CENTER_NODE:
00732     
00733       switch(dir){
00734       case X_MIN_DIR:
00735         return x_major_derivative_edge_capacity(from.pos.x()-1,from.pos.y());
00736 
00737       case X_MAX_DIR:
00738         return x_major_derivative_edge_capacity(from.pos.x(),from.pos.y());
00739 
00740       case Y_MIN_DIR:
00741         return y_major_derivative_edge_capacity(from.pos.x(),from.pos.y()-1);
00742 
00743       case Y_MAX_DIR:
00744         return y_major_derivative_edge_capacity(from.pos.x(),from.pos.y());  
00745 
00746       case Z_MIN_x_min_DIR: 
00747       case Z_MIN_x_max_DIR:
00748       case Z_MIN_y_min_DIR: 
00749       case Z_MIN_y_max_DIR:
00750         return cost_edge_capacity(from.pos.x(),from.pos.y(),from.pos.z()-1);
00751 
00752       case Z_MAX_x_min_DIR:
00753       case Z_MAX_x_max_DIR:
00754       case Z_MAX_y_min_DIR:
00755       case Z_MAX_y_max_DIR:
00756         return cost_edge_capacity(from.pos.x(),from.pos.y(),from.pos.z());
00757       }
00758 
00759       Message::error<<"edge_capacity : bad end 1"<<Message::done;
00760     
00761       // ########################### Z_MAX_x_min_NODE ###########################  
00762     case Z_MAX_x_min_NODE:
00763 
00764       switch(dir){
00765       case X_MIN_DIR:
00766         return x_minor_derivative_edge_capacity(from.pos.x()-1,from.pos.y());
00767 
00768       case X_MAX_DIR:
00769         Message::error<<"edge_capacity : bad end 2.1"<<Message::done;
00770 
00771       case Y_MIN_DIR:
00772         Message::error<<"edge_capacity : bad end 2.2"<<Message::done;
00773 
00774       case Y_MAX_DIR:
00775         Message::error<<"edge_capacity : bad end 2.3"<<Message::done;
00776 
00777       case Z_MIN_x_min_DIR:
00778         Message::error<<"edge_capacity : bad end 2.4"<<Message::done;
00779    
00780       case Z_MIN_x_max_DIR:
00781         return cost_edge_capacity(from.pos.x(),from.pos.y(),from.pos.z());
00782 
00783       case Z_MIN_y_min_DIR:
00784         Message::error<<"edge_capacity : bad end 2.5"<<Message::done;
00785    
00786       case Z_MIN_y_max_DIR:
00787         Message::error<<"edge_capacity : bad end 2.6"<<Message::done;
00788 
00789       case Z_MAX_x_min_DIR:
00790         Message::error<<"edge_capacity : bad end 2.7"<<Message::done;
00791 
00792       case Z_MAX_x_max_DIR:
00793         return cost_edge_capacity(from.pos.x(),from.pos.y(),from.pos.z());
00794 
00795       case Z_MAX_y_min_DIR:
00796         Message::error<<"edge_capacity : bad end 2.8"<<Message::done;
00797 
00798       case Z_MAX_y_max_DIR:
00799         Message::error<<"edge_capacity : bad end 2.9"<<Message::done;
00800       }
00801     
00802       Message::error<<"edge_capacity : bad end 2"<<Message::done;
00803     
00804       // ########################### Z_MAX_x_max_NODE ###########################
00805     case Z_MAX_x_max_NODE:
00806 
00807       switch(dir){
00808       case X_MIN_DIR:
00809         Message::error<<"edge_capacity : bad end 3.1"<<Message::done;
00810 
00811       case X_MAX_DIR:
00812         return x_minor_derivative_edge_capacity(from.pos.x(),from.pos.y());
00813 
00814       case Y_MIN_DIR:
00815         Message::error<<"edge_capacity : bad end 3.2"<<Message::done;
00816 
00817       case Y_MAX_DIR:
00818         Message::error<<"edge_capacity : bad end 3.3"<<Message::done;
00819 
00820       case Z_MIN_x_min_DIR:
00821         return cost_edge_capacity(from.pos.x(),from.pos.y(),from.pos.z());
00822 
00823       case Z_MIN_x_max_DIR: 
00824         Message::error<<"edge_capacity : bad end 3.4"<<Message::done;
00825 
00826       case Z_MIN_y_min_DIR:
00827         Message::error<<"edge_capacity : bad end 3.5"<<Message::done;
00828 
00829       case Z_MIN_y_max_DIR: 
00830         Message::error<<"edge_capacity : bad end 3.6"<<Message::done;
00831 
00832       case Z_MAX_x_min_DIR:
00833         return cost_edge_capacity(from.pos.x(),from.pos.y(),from.pos.z());
00834 
00835       case Z_MAX_x_max_DIR:
00836         Message::error<<"edge_capacity : bad end 3.7"<<Message::done;
00837 
00838       case Z_MAX_y_min_DIR:
00839         Message::error<<"edge_capacity : bad end 3.8"<<Message::done;;
00840 
00841       case Z_MAX_y_max_DIR:
00842         Message::error<<"edge_capacity : bad end 3.9"<<Message::done;  
00843       }
00844     
00845       Message::error<<"edge_capacity : bad end 3"<<Message::done;
00846       return 0;
00847 
00848       // ########################### Z_MAX_y_min_NODE ###########################  
00849     case Z_MAX_y_min_NODE:
00850 
00851       switch(dir){
00852       case X_MIN_DIR:
00853         Message::error<<"edge_capacity : bad end 4.1"<<Message::done;
00854 
00855       case X_MAX_DIR:
00856         Message::error<<"edge_capacity : bad end 4.2"<<Message::done;
00857 
00858       case Y_MIN_DIR:
00859         return y_minor_derivative_edge_capacity(from.pos.x(),from.pos.y()-1);
00860 
00861       case Y_MAX_DIR:
00862         Message::error<<"edge_capacity : bad end 4.3"<<Message::done;
00863 
00864       case Z_MIN_x_min_DIR:
00865         Message::error<<"edge_capacity : bad end 4.4"<<Message::done;
00866    
00867       case Z_MIN_x_max_DIR:
00868         Message::error<<"edge_capacity : bad end 4.5"<<Message::done;      
00869 
00870       case Z_MIN_y_min_DIR:
00871         Message::error<<"edge_capacity : bad end 4.6"<<Message::done;
00872    
00873       case Z_MIN_y_max_DIR:
00874         return cost_edge_capacity(from.pos.x(),from.pos.y(),from.pos.z());
00875 
00876       case Z_MAX_x_min_DIR:
00877         Message::error<<"edge_capacity : bad end 4.7"<<Message::done;
00878 
00879       case Z_MAX_x_max_DIR:
00880         Message::error<<"edge_capacity : bad end 4.8"<<Message::done;
00881 
00882       case Z_MAX_y_min_DIR:
00883         Message::error<<"edge_capacity : bad end 4.9"<<Message::done;
00884 
00885       case Z_MAX_y_max_DIR:
00886         return cost_edge_capacity(from.pos.x(),from.pos.y(),from.pos.z());
00887       }
00888     
00889       Message::error<<"edge_capacity : bad end 4"<<Message::done;
00890     
00891       // ########################### Z_MAX_y_max_NODE ###########################
00892     case Z_MAX_y_max_NODE:
00893 
00894       switch(dir){
00895       case X_MIN_DIR:
00896         Message::error<<"edge_capacity : bad end 5.1"<<Message::done;
00897 
00898       case X_MAX_DIR:
00899         Message::error<<"edge_capacity : bad end 5.2"<<Message::done;
00900 
00901       case Y_MIN_DIR:
00902         Message::error<<"edge_capacity : bad end 5.3"<<Message::done;
00903 
00904       case Y_MAX_DIR:
00905         return y_minor_derivative_edge_capacity(from.pos.x(),from.pos.y());
00906 
00907       case Z_MIN_x_min_DIR:
00908         Message::error<<"edge_capacity : bad end 5.4"<<Message::done;
00909 
00910       case Z_MIN_x_max_DIR: 
00911         Message::error<<"edge_capacity : bad end 5.5"<<Message::done;
00912 
00913       case Z_MIN_y_min_DIR:
00914         return cost_edge_capacity(from.pos.x(),from.pos.y(),from.pos.z());
00915 
00916       case Z_MIN_y_max_DIR: 
00917         Message::error<<"edge_capacity : bad end 5.6"<<Message::done;
00918 
00919       case Z_MAX_x_min_DIR:
00920         Message::error<<"edge_capacity : bad end 5.7"<<Message::done;;
00921 
00922       case Z_MAX_x_max_DIR:
00923         Message::error<<"edge_capacity : bad end 5.8"<<Message::done;
00924 
00925       case Z_MAX_y_min_DIR:
00926         return cost_edge_capacity(from.pos.x(),from.pos.y(),from.pos.z());
00927 
00928       case Z_MAX_y_max_DIR:
00929         Message::error<<"edge_capacity : bad end 5.9"<<Message::done;  
00930       }
00931     
00932       Message::error<<"edge_capacity : bad end 5"<<Message::done;
00933       return 0;
00934     }
00935   
00936   }
00937 
00938   template<typename Real>
00939   typename PushRelabel_non_linear_grid_3D<Real>::real_type
00940   PushRelabel_non_linear_grid_3D<Real>::
00941   edge_flow(const node_type&     from,
00942             const direction_type dir) const{
00943 
00944     switch(from.loc){
00945       // ########################### CENTER_NODE ###########################
00946     case CENTER_NODE:
00947     
00948       switch(dir){
00949       case X_MIN_DIR:
00950         return -x_major_derivative_edge_flow(from.pos.x()-1,from.pos.y(),from.pos.z());
00951       
00952       case X_MAX_DIR:
00953         return x_major_derivative_edge_flow[from.pos];
00954 
00955       case Y_MIN_DIR:
00956         return -y_major_derivative_edge_flow(from.pos.x(),from.pos.y()-1,from.pos.z());
00957       
00958       case Y_MAX_DIR:
00959         return y_major_derivative_edge_flow[from.pos];
00960 
00961       case Z_MIN_x_min_DIR:
00962         return -cost_edge_Z_MAX_MAX_x_min_flow(from.pos.x(),from.pos.y(),from.pos.z()-1);
00963       
00964       case Z_MIN_x_max_DIR:
00965         return -cost_edge_Z_MAX_MAX_x_max_flow(from.pos.x(),from.pos.y(),from.pos.z()-1);
00966 
00967       case Z_MIN_y_min_DIR:
00968         return -cost_edge_Z_MAX_MAX_y_min_flow(from.pos.x(),from.pos.y(),from.pos.z()-1);
00969       
00970       case Z_MIN_y_max_DIR:
00971         return -cost_edge_Z_MAX_MAX_y_max_flow(from.pos.x(),from.pos.y(),from.pos.z()-1);
00972 
00973       case Z_MAX_x_min_DIR:
00974         return cost_edge_Z_MAX_x_min_flow[from.pos];
00975       
00976       case Z_MAX_x_max_DIR:
00977         return cost_edge_Z_MAX_x_max_flow[from.pos];
00978 
00979       case Z_MAX_y_min_DIR:
00980         return cost_edge_Z_MAX_y_min_flow[from.pos];
00981       
00982       case Z_MAX_y_max_DIR:
00983         return cost_edge_Z_MAX_y_max_flow[from.pos];
00984       }
00985 
00986       Message::error<<"edge_flow : bad end 1"<<Message::done;
00987       return 0;
00988     
00989       // ########################### Z_MAX_x_min_NODE ###########################  
00990     case Z_MAX_x_min_NODE:
00991 
00992       switch(dir){
00993       case X_MIN_DIR:
00994         return -x_minor_derivative_edge_flow(from.pos.x()-1,from.pos.y(),from.pos.z());
00995 
00996       case X_MAX_DIR:
00997         Message::error<<"edge_flow : bad end 2.1"<<Message::done;
00998 
00999       case Y_MIN_DIR:
01000         Message::error<<"edge_flow : bad end 2.2"<<Message::done;
01001 
01002       case Y_MAX_DIR:
01003         Message::error<<"edge_flow : bad end 2.3"<<Message::done;  
01004 
01005       case Z_MIN_x_min_DIR:
01006         Message::error<<"edge_flow : bad end 2.4"<<Message::done;
01007    
01008       case Z_MIN_x_max_DIR:
01009         return -cost_edge_Z_MAX_x_min_flow[from.pos];
01010 
01011       case Z_MIN_y_min_DIR:
01012         Message::error<<"edge_flow : bad end 2.5"<<Message::done;
01013    
01014       case Z_MIN_y_max_DIR:
01015         Message::error<<"edge_flow : bad end 2.6"<<Message::done;
01016 
01017       case Z_MAX_x_min_DIR:
01018         Message::error<<"edge_flow : bad end 2.7"<<Message::done;
01019 
01020       case Z_MAX_x_max_DIR:
01021         return cost_edge_Z_MAX_MAX_x_min_flow[from.pos];
01022 
01023       case Z_MAX_y_min_DIR:
01024         Message::error<<"edge_flow : bad end 2.8"<<Message::done;
01025 
01026       case Z_MAX_y_max_DIR:
01027         Message::error<<"edge_flow : bad end 2.9"<<Message::done;
01028       }
01029     
01030       Message::error<<"edge_flow : bad end 2"<<Message::done;
01031       return 0;
01032     
01033       // ########################### Z_MAX_x_max_NODE ###########################
01034     case Z_MAX_x_max_NODE:
01035 
01036       switch(dir){
01037       case X_MIN_DIR:
01038         Message::error<<"edge_flow : bad end 3.1"<<Message::done;
01039 
01040       case X_MAX_DIR:
01041         return x_minor_derivative_edge_flow[from.pos];
01042 
01043       case Y_MIN_DIR:
01044         Message::error<<"edge_flow : bad end 3.2"<<Message::done;
01045 
01046       case Y_MAX_DIR:
01047         Message::error<<"edge_flow : bad end 3.3"<<Message::done;
01048 
01049       case Z_MIN_x_min_DIR:
01050         return -cost_edge_Z_MAX_x_max_flow[from.pos];
01051 
01052       case Z_MIN_x_max_DIR: 
01053         Message::error<<"edge_flow : bad end 3.4"<<Message::done;
01054 
01055       case Z_MIN_y_min_DIR:
01056         Message::error<<"edge_flow : bad end 3.5"<<Message::done;
01057 
01058       case Z_MIN_y_max_DIR: 
01059         Message::error<<"edge_flow : bad end 3.6"<<Message::done;  
01060 
01061       case Z_MAX_x_min_DIR:
01062         return cost_edge_Z_MAX_MAX_x_max_flow[from.pos];
01063 
01064       case Z_MAX_x_max_DIR:
01065         Message::error<<"edge_flow : bad end 3.7"<<Message::done;
01066 
01067       case Z_MAX_y_min_DIR:
01068         Message::error<<"edge_flow : bad end 3.8"<<Message::done;
01069 
01070       case Z_MAX_y_max_DIR:
01071         Message::error<<"edge_flow : bad end 3.9"<<Message::done;  
01072       }
01073     
01074       Message::error<<"edge_flow : bad end 3"<<Message::done;
01075       return 0;
01076 
01077       // ########################### Z_MAX_y_min_NODE ###########################  
01078     case Z_MAX_y_min_NODE:
01079 
01080       switch(dir){
01081       case X_MIN_DIR:
01082         Message::error<<"edge_flow : bad end 4.1"<<Message::done;
01083 
01084       case X_MAX_DIR:
01085         Message::error<<"edge_flow : bad end 4.2"<<Message::done;
01086 
01087       case Y_MIN_DIR:
01088         return -y_minor_derivative_edge_flow(from.pos.x(),from.pos.y()-1,from.pos.z());
01089 
01090 
01091       case Y_MAX_DIR:
01092         Message::error<<"edge_flow : bad end 4.3"<<Message::done;  
01093 
01094       case Z_MIN_x_min_DIR:
01095         Message::error<<"edge_flow : bad end 4.4"<<Message::done;
01096    
01097       case Z_MIN_x_max_DIR:
01098         Message::error<<"edge_flow : bad end 4.5"<<Message::done;
01099 
01100       case Z_MIN_y_min_DIR:
01101         Message::error<<"edge_flow : bad end 4.6"<<Message::done;
01102    
01103       case Z_MIN_y_max_DIR:
01104         return -cost_edge_Z_MAX_y_min_flow[from.pos];
01105 
01106       case Z_MAX_x_min_DIR:
01107         Message::error<<"edge_flow : bad end 4.7"<<Message::done;
01108 
01109       case Z_MAX_x_max_DIR:
01110         Message::error<<"edge_flow : bad end 4.8"<<Message::done;
01111 
01112       case Z_MAX_y_min_DIR:
01113         Message::error<<"edge_flow : bad end 4.9"<<Message::done;
01114 
01115       case Z_MAX_y_max_DIR:
01116         return cost_edge_Z_MAX_MAX_y_min_flow[from.pos];
01117 
01118       }
01119     
01120       Message::error<<"edge_flow : bad end 4"<<Message::done;
01121       return 0;
01122     
01123       // ########################### Z_MAX_y_max_NODE ###########################
01124     case Z_MAX_y_max_NODE:
01125 
01126       switch(dir){
01127       case X_MIN_DIR:
01128         Message::error<<"edge_flow : bad end 5.1"<<Message::done;
01129 
01130       case X_MAX_DIR:
01131         Message::error<<"edge_flow : bad end 5.2"<<Message::done;
01132 
01133       case Y_MIN_DIR:
01134         Message::error<<"edge_flow : bad end 5.3"<<Message::done;
01135 
01136       case Y_MAX_DIR:
01137         return y_minor_derivative_edge_flow[from.pos];
01138 
01139       case Z_MIN_x_min_DIR:
01140         Message::error<<"edge_flow : bad end 5.4"<<Message::done;
01141 
01142       case Z_MIN_x_max_DIR: 
01143         Message::error<<"edge_flow : bad end 5.5"<<Message::done;
01144 
01145       case Z_MIN_y_min_DIR:
01146         return -cost_edge_Z_MAX_y_max_flow[from.pos];
01147 
01148       case Z_MIN_y_max_DIR: 
01149         Message::error<<"edge_flow : bad end 5.6"<<Message::done;  
01150 
01151       case Z_MAX_x_min_DIR:
01152         Message::error<<"edge_flow : bad end 5.7"<<Message::done;
01153 
01154       case Z_MAX_x_max_DIR:
01155         Message::error<<"edge_flow : bad end 5.8"<<Message::done;
01156 
01157       case Z_MAX_y_min_DIR:
01158         return cost_edge_Z_MAX_MAX_y_max_flow[from.pos];
01159 
01160       case Z_MAX_y_max_DIR:
01161         Message::error<<"edge_flow : bad end 5.9"<<Message::done;  
01162       }
01163     
01164       Message::error<<"edge_flow : bad end 5"<<Message::done;
01165       return 0;  
01166     }
01167   
01168     Message::error<<"edge_flow : bad end 0"<<Message::done;
01169     return 0;
01170   }
01171 
01172   
01173   template<typename Real>
01174   typename PushRelabel_non_linear_grid_3D<Real>::real_type
01175   PushRelabel_non_linear_grid_3D<Real>::
01176   edge_residual(const node_type&     from,
01177                 const direction_type dir) const{
01178 
01179     switch(from.loc){
01180       // ########################### CENTER_NODE ###########################
01181     case CENTER_NODE:
01182     
01183       switch(dir){
01184       case X_MIN_DIR:
01185         return x_major_derivative_edge_capacity(from.pos.x()-1,from.pos.y())
01186           + x_major_derivative_edge_flow(from.pos.x()-1,from.pos.y(),from.pos.z());
01187       
01188       case X_MAX_DIR:
01189         return x_major_derivative_edge_capacity(from.pos.x(),from.pos.y())
01190           - x_major_derivative_edge_flow[from.pos];
01191 
01192       case Y_MIN_DIR:
01193         return y_major_derivative_edge_capacity(from.pos.x(),from.pos.y()-1)
01194           + y_major_derivative_edge_flow(from.pos.x(),from.pos.y()-1,from.pos.z());
01195       
01196       case Y_MAX_DIR:
01197         return y_major_derivative_edge_capacity(from.pos.x(),from.pos.y())
01198           - y_major_derivative_edge_flow[from.pos];
01199 
01200       case Z_MIN_x_min_DIR:
01201         return cost_edge_capacity(from.pos.x(),from.pos.y(),from.pos.z()-1)
01202           + cost_edge_Z_MAX_MAX_x_min_flow(from.pos.x(),from.pos.y(),from.pos.z()-1);
01203       
01204       case Z_MIN_x_max_DIR:
01205         return cost_edge_capacity(from.pos.x(),from.pos.y(),from.pos.z()-1)
01206           + cost_edge_Z_MAX_MAX_x_max_flow(from.pos.x(),from.pos.y(),from.pos.z()-1);
01207 
01208       case Z_MIN_y_min_DIR:
01209         return cost_edge_capacity(from.pos.x(),from.pos.y(),from.pos.z()-1)
01210           + cost_edge_Z_MAX_MAX_y_min_flow(from.pos.x(),from.pos.y(),from.pos.z()-1);
01211       
01212       case Z_MIN_y_max_DIR:
01213         return cost_edge_capacity(from.pos.x(),from.pos.y(),from.pos.z()-1)
01214           + cost_edge_Z_MAX_MAX_y_max_flow(from.pos.x(),from.pos.y(),from.pos.z()-1);
01215 
01216       case Z_MAX_x_min_DIR:
01217         return cost_edge_capacity[from.pos]
01218           - cost_edge_Z_MAX_x_min_flow[from.pos];
01219       
01220       case Z_MAX_x_max_DIR:
01221         return cost_edge_capacity[from.pos]
01222           - cost_edge_Z_MAX_x_max_flow[from.pos];
01223 
01224       case Z_MAX_y_min_DIR:
01225         return cost_edge_capacity[from.pos]
01226           - cost_edge_Z_MAX_y_min_flow[from.pos];
01227       
01228       case Z_MAX_y_max_DIR:
01229         return cost_edge_capacity[from.pos]
01230           - cost_edge_Z_MAX_y_max_flow[from.pos];
01231       }
01232 
01233       Message::error<<"edge_residual : bad end 1"<<Message::done;
01234       return 0;
01235     
01236       // ########################### Z_MAX_x_min_NODE ###########################  
01237     case Z_MAX_x_min_NODE:
01238 
01239       switch(dir){
01240       case X_MIN_DIR:
01241         return x_minor_derivative_edge_capacity(from.pos.x()-1,from.pos.y())
01242           + x_minor_derivative_edge_flow(from.pos.x()-1,from.pos.y(),from.pos.z());
01243 
01244       case X_MAX_DIR:
01245         Message::error<<"edge_residual : bad end 2.1"<<Message::done;
01246 
01247       case Y_MIN_DIR:
01248         Message::error<<"edge_residual : bad end 2.2"<<Message::done;
01249 
01250       case Y_MAX_DIR:
01251         Message::error<<"edge_residual : bad end 2.3"<<Message::done;  
01252 
01253       case Z_MIN_x_min_DIR:
01254         Message::error<<"edge_residual : bad end 2.4"<<Message::done;
01255    
01256       case Z_MIN_x_max_DIR:
01257         return cost_edge_capacity[from.pos]
01258           + cost_edge_Z_MAX_x_min_flow[from.pos];
01259 
01260       case Z_MIN_y_min_DIR:
01261         Message::error<<"edge_residual : bad end 2.5"<<Message::done;
01262    
01263       case Z_MIN_y_max_DIR:
01264         Message::error<<"edge_residual : bad end 2.6"<<Message::done;
01265 
01266       case Z_MAX_x_min_DIR:
01267         Message::error<<"edge_residual : bad end 2.7"<<Message::done;
01268 
01269       case Z_MAX_x_max_DIR:
01270         return cost_edge_capacity[from.pos]
01271           - cost_edge_Z_MAX_MAX_x_min_flow[from.pos];
01272 
01273       case Z_MAX_y_min_DIR:
01274         Message::error<<"edge_residual : bad end 2.8"<<Message::done;
01275 
01276       case Z_MAX_y_max_DIR:
01277         Message::error<<"edge_residual : bad end 2.9"<<Message::done;
01278       }
01279     
01280       Message::error<<"edge_residual : bad end 2"<<Message::done;
01281       return 0;
01282     
01283       // ########################### Z_MAX_x_max_NODE ###########################
01284     case Z_MAX_x_max_NODE:
01285 
01286       switch(dir){
01287       case X_MIN_DIR:
01288         Message::error<<"edge_residual : bad end 3.1"<<Message::done;
01289 
01290       case X_MAX_DIR:
01291         return x_minor_derivative_edge_capacity(from.pos.x(),from.pos.y())
01292           - x_minor_derivative_edge_flow[from.pos];
01293 
01294       case Y_MIN_DIR:
01295         Message::error<<"edge_residual : bad end 3.2"<<Message::done;
01296 
01297       case Y_MAX_DIR:
01298         Message::error<<"edge_residual : bad end 3.3"<<Message::done;
01299 
01300       case Z_MIN_x_min_DIR:
01301         return cost_edge_capacity[from.pos]
01302           + cost_edge_Z_MAX_x_max_flow[from.pos];
01303 
01304       case Z_MIN_x_max_DIR: 
01305         Message::error<<"edge_residual : bad end 3.4"<<Message::done;
01306 
01307       case Z_MIN_y_min_DIR:
01308         Message::error<<"edge_residual : bad end 3.5"<<Message::done;
01309 
01310       case Z_MIN_y_max_DIR: 
01311         Message::error<<"edge_residual : bad end 3.6"<<Message::done;  
01312 
01313       case Z_MAX_x_min_DIR:
01314         return cost_edge_capacity[from.pos]
01315           - cost_edge_Z_MAX_MAX_x_max_flow[from.pos];
01316 
01317       case Z_MAX_x_max_DIR:
01318         Message::error<<"edge_residual : bad end 3.7"<<Message::done;
01319 
01320       case Z_MAX_y_min_DIR:
01321         Message::error<<"edge_residual : bad end 3.8"<<Message::done;
01322 
01323       case Z_MAX_y_max_DIR:
01324         Message::error<<"edge_residual : bad end 3.9"<<Message::done;  
01325       }
01326     
01327       Message::error<<"edge_residual : bad end 3"<<Message::done;
01328       return 0;
01329 
01330       // ########################### Z_MAX_y_min_NODE ###########################  
01331     case Z_MAX_y_min_NODE:
01332 
01333       switch(dir){
01334       case X_MIN_DIR:
01335         Message::error<<"edge_residual : bad end 4.1"<<Message::done;
01336 
01337       case X_MAX_DIR:
01338         Message::error<<"edge_residual : bad end 4.2"<<Message::done;
01339 
01340       case Y_MIN_DIR:
01341         return y_minor_derivative_edge_capacity(from.pos.x(),from.pos.y()-1)
01342           + y_minor_derivative_edge_flow(from.pos.x(),from.pos.y()-1,from.pos.z());
01343 
01344 
01345       case Y_MAX_DIR:
01346         Message::error<<"edge_residual : bad end 4.3"<<Message::done;  
01347 
01348       case Z_MIN_x_min_DIR:
01349         Message::error<<"edge_residual : bad end 4.4"<<Message::done;
01350    
01351       case Z_MIN_x_max_DIR:
01352         Message::error<<"edge_residual : bad end 4.5"<<Message::done;
01353 
01354       case Z_MIN_y_min_DIR:
01355         Message::error<<"edge_residual : bad end 4.6"<<Message::done;
01356    
01357       case Z_MIN_y_max_DIR:
01358         return cost_edge_capacity[from.pos]
01359           + cost_edge_Z_MAX_y_min_flow[from.pos];
01360 
01361       case Z_MAX_x_min_DIR:
01362         Message::error<<"edge_residual : bad end 4.7"<<Message::done;
01363 
01364       case Z_MAX_x_max_DIR:
01365         Message::error<<"edge_residual : bad end 4.8"<<Message::done;
01366 
01367       case Z_MAX_y_min_DIR:
01368         Message::error<<"edge_residual : bad end 4.9"<<Message::done;
01369 
01370       case Z_MAX_y_max_DIR:
01371         return cost_edge_capacity[from.pos]
01372           - cost_edge_Z_MAX_MAX_y_min_flow[from.pos];
01373 
01374       }
01375     
01376       Message::error<<"edge_residual : bad end 4"<<Message::done;
01377       return 0;
01378     
01379       // ########################### Z_MAX_y_max_NODE ###########################
01380     case Z_MAX_y_max_NODE:
01381 
01382       switch(dir){
01383       case X_MIN_DIR:
01384         Message::error<<"edge_residual : bad end 5.1"<<Message::done;
01385 
01386       case X_MAX_DIR:
01387         Message::error<<"edge_residual : bad end 5.2"<<Message::done;
01388 
01389       case Y_MIN_DIR:
01390         Message::error<<"edge_residual : bad end 5.3"<<Message::done;
01391 
01392       case Y_MAX_DIR:
01393         return y_minor_derivative_edge_capacity(from.pos.x(),from.pos.y())
01394           - y_minor_derivative_edge_flow[from.pos];
01395 
01396       case Z_MIN_x_min_DIR:
01397         Message::error<<"edge_residual : bad end 5.4"<<Message::done;
01398 
01399       case Z_MIN_x_max_DIR: 
01400         Message::error<<"edge_residual : bad end 5.5"<<Message::done;
01401 
01402       case Z_MIN_y_min_DIR:
01403         return cost_edge_capacity[from.pos]
01404           + cost_edge_Z_MAX_y_max_flow[from.pos];
01405 
01406       case Z_MIN_y_max_DIR: 
01407         Message::error<<"edge_residual : bad end 5.6"<<Message::done;  
01408 
01409       case Z_MAX_x_min_DIR:
01410         Message::error<<"edge_residual : bad end 5.7"<<Message::done;
01411 
01412       case Z_MAX_x_max_DIR:
01413         Message::error<<"edge_residual : bad end 5.8"<<Message::done;
01414 
01415       case Z_MAX_y_min_DIR:
01416         return cost_edge_capacity[from.pos]
01417           - cost_edge_Z_MAX_MAX_y_max_flow[from.pos];
01418 
01419       case Z_MAX_y_max_DIR:
01420         Message::error<<"edge_residual : bad end 5.9"<<Message::done;  
01421       }
01422     
01423       Message::error<<"edge_residual : bad end 5"<<Message::done;
01424       return 0;  
01425     }
01426   
01427     Message::error<<"edge_residual : bad end 0"<<Message::done;
01428     return 0;
01429   }
01430 
01431 
01432 
01436   template<typename Real>
01437   void
01438   PushRelabel_non_linear_grid_3D<Real>::
01439   neighbors(const node_type& node,
01440             node_type* const result,
01441             size_type* const n_res) const{
01442   
01443     *n_res = 0;
01444 
01445     // ################ toward X_MIN ################ 
01446   
01447     switch(node.loc){
01448       
01449     case CENTER_NODE:
01450       if ((node.pos.x()>0)
01451           &&(domain(node.pos.x()-1,node.pos.y(),node.pos.z())||
01452              ((node.pos.z()>0)&&
01453               domain(node.pos.x()-1,node.pos.y(),node.pos.z()-1)))){
01454         result[*n_res].pos.x() = node.pos.x()-1;
01455         result[*n_res].pos.y() = node.pos.y();
01456         result[*n_res].pos.z() = node.pos.z();
01457         result[*n_res].loc     = CENTER_NODE;
01458         (*n_res)++;
01459       }
01460       break;
01461       
01462     case Z_MAX_x_min_NODE:
01463       if ((node.pos.x()>0)
01464           &&(domain(node.pos.x()-1,node.pos.y(),node.pos.z()))){
01465         result[*n_res].pos.x() = node.pos.x()-1;
01466         result[*n_res].pos.y() = node.pos.y();
01467         result[*n_res].pos.z() = node.pos.z();
01468         result[*n_res].loc     = Z_MAX_x_max_NODE;
01469         (*n_res)++;
01470       }
01471       break;
01472       
01473     case Z_MAX_x_max_NODE:
01474     case Z_MAX_y_min_NODE:
01475     case Z_MAX_y_max_NODE:
01476       break;
01477     }
01478 
01479     // ################ toward Y_MIN ################ 
01480   
01481     switch(node.loc){
01482       
01483     case CENTER_NODE:
01484       if ((node.pos.y()>0)
01485           &&(domain(node.pos.x(),node.pos.y()-1,node.pos.z())||
01486              ((node.pos.z()>0)&&
01487               domain(node.pos.x(),node.pos.y()-1,node.pos.z()-1)))){
01488         result[*n_res].pos.x() = node.pos.x();
01489         result[*n_res].pos.y() = node.pos.y()-1;
01490         result[*n_res].pos.z() = node.pos.z();
01491         result[*n_res].loc     = CENTER_NODE;
01492         (*n_res)++;
01493       }
01494       break;
01495       
01496     case Z_MAX_y_min_NODE:
01497       if ((node.pos.y()>0)
01498           &&(domain(node.pos.x(),node.pos.y()-1,node.pos.z()))){
01499         result[*n_res].pos.x() = node.pos.x();
01500         result[*n_res].pos.y() = node.pos.y()-1;
01501         result[*n_res].pos.z() = node.pos.z();
01502         result[*n_res].loc     = Z_MAX_y_max_NODE;
01503         (*n_res)++;
01504       }
01505       break;
01506       
01507     case Z_MAX_x_max_NODE:
01508     case Z_MAX_x_min_NODE:
01509     case Z_MAX_y_max_NODE:
01510       break;
01511     }
01512   
01513     // ################ toward Z_MIN ################
01514   
01515     switch(node.loc){
01516       
01517     case CENTER_NODE:
01518 
01519       if ((node.pos.z()>0)
01520           &&(domain(node.pos.x(),node.pos.y(),node.pos.z()-1))){
01521 
01522         result[*n_res].pos.x() = node.pos.x();
01523         result[*n_res].pos.y() = node.pos.y();
01524         result[*n_res].pos.z() = node.pos.z()-1;
01525         result[*n_res].loc     = Z_MAX_x_min_NODE;
01526         (*n_res)++;
01527 
01528         result[*n_res].pos.x() = node.pos.x();
01529         result[*n_res].pos.y() = node.pos.y();
01530         result[*n_res].pos.z() = node.pos.z()-1;
01531         result[*n_res].loc     = Z_MAX_x_max_NODE;
01532         (*n_res)++;
01533 
01534         result[*n_res].pos.x() = node.pos.x();
01535         result[*n_res].pos.y() = node.pos.y();
01536         result[*n_res].pos.z() = node.pos.z()-1;
01537         result[*n_res].loc     = Z_MAX_y_min_NODE;
01538         (*n_res)++;
01539 
01540         result[*n_res].pos.x() = node.pos.x();
01541         result[*n_res].pos.y() = node.pos.y();
01542         result[*n_res].pos.z() = node.pos.z()-1;
01543         result[*n_res].loc     = Z_MAX_y_max_NODE;
01544         (*n_res)++;
01545       }
01546       break;
01547 
01548     case Z_MAX_x_min_NODE:
01549       result[*n_res].pos.x() = node.pos.x();
01550       result[*n_res].pos.y() = node.pos.y();
01551       result[*n_res].pos.z() = node.pos.z();
01552       result[*n_res].loc     = CENTER_NODE;
01553       (*n_res)++;
01554       break;
01555 
01556     case Z_MAX_x_max_NODE:
01557       result[*n_res].pos.x() = node.pos.x();
01558       result[*n_res].pos.y() = node.pos.y();
01559       result[*n_res].pos.z() = node.pos.z();
01560       result[*n_res].loc     = CENTER_NODE;
01561       (*n_res)++;
01562       break;
01563 
01564     case Z_MAX_y_min_NODE:
01565       result[*n_res].pos.x() = node.pos.x();
01566       result[*n_res].pos.y() = node.pos.y();
01567       result[*n_res].pos.z() = node.pos.z();
01568       result[*n_res].loc     = CENTER_NODE;
01569       (*n_res)++;
01570       break;
01571 
01572     case Z_MAX_y_max_NODE:
01573       result[*n_res].pos.x() = node.pos.x();
01574       result[*n_res].pos.y() = node.pos.y();
01575       result[*n_res].pos.z() = node.pos.z();
01576       result[*n_res].loc     = CENTER_NODE;
01577       (*n_res)++;
01578       break;  
01579     }
01580 
01581     // ################ toward X_MAX ################ 
01582 
01583     switch(node.loc){
01584 
01585     case CENTER_NODE:
01586 
01587       if ((node.pos.x()<x_size-1)
01588           &&(domain(node.pos.x()+1,node.pos.y(),node.pos.z())||
01589              ((node.pos.z()>0)&&
01590               domain(node.pos.x()+1,node.pos.y(),node.pos.z()-1)))){
01591 
01592         result[*n_res].pos.x() = node.pos.x()+1;
01593         result[*n_res].pos.y() = node.pos.y();
01594         result[*n_res].pos.z() = node.pos.z();
01595         result[*n_res].loc     = CENTER_NODE;
01596         (*n_res)++;
01597       }
01598       break;
01599 
01600     case Z_MAX_x_max_NODE:
01601 
01602       if ((node.pos.x()<x_size-1)
01603           &&(domain(node.pos.x()+1,node.pos.y(),node.pos.z()))){
01604         result[*n_res].pos.x() = node.pos.x()+1;
01605         result[*n_res].pos.y() = node.pos.y();
01606         result[*n_res].pos.z() = node.pos.z();
01607         result[*n_res].loc     = Z_MAX_x_min_NODE;
01608         (*n_res)++;
01609       }
01610       break;
01611 
01612     case Z_MAX_x_min_NODE:
01613     case Z_MAX_y_min_NODE:
01614     case Z_MAX_y_max_NODE:
01615       break;  
01616     }
01617 
01618     // ################ toward Y_MAX ################ 
01619 
01620     switch(node.loc){
01621 
01622     case CENTER_NODE:
01623 
01624       if ((node.pos.y()<y_size-1)
01625           &&(domain(node.pos.x(),node.pos.y()+1,node.pos.z())||
01626              ((node.pos.z()>0)&&
01627               domain(node.pos.x(),node.pos.y()+1,node.pos.z()-1)))){
01628     
01629         result[*n_res].pos.x() = node.pos.x();
01630         result[*n_res].pos.y() = node.pos.y()+1;
01631         result[*n_res].pos.z() = node.pos.z();
01632         result[*n_res].loc     = CENTER_NODE;
01633         (*n_res)++;
01634       }
01635       break;
01636 
01637     case Z_MAX_y_max_NODE:
01638       if ((node.pos.y()<y_size-1)
01639           &&(domain(node.pos.x(),node.pos.y()+1,node.pos.z()))){
01640 
01641         result[*n_res].pos.x() = node.pos.x();
01642         result[*n_res].pos.y() = node.pos.y()+1;
01643         result[*n_res].pos.z() = node.pos.z();
01644         result[*n_res].loc     = Z_MAX_y_min_NODE;
01645         (*n_res)++;
01646       }
01647       break;
01648 
01649     case Z_MAX_x_min_NODE:
01650     case Z_MAX_x_max_NODE:
01651     case Z_MAX_y_min_NODE:
01652       break;  
01653     }
01654     
01655 
01656     // ################ toward Z_MAX ################ 
01657 
01658     switch(node.loc){
01659     case CENTER_NODE:
01660       if ((node.pos.z()<z_size)
01661           &&(domain[node.pos])){
01662 
01663         result[*n_res].pos.x() = node.pos.x();
01664         result[*n_res].pos.y() = node.pos.y();
01665         result[*n_res].pos.z() = node.pos.z();
01666         result[*n_res].loc     = Z_MAX_x_min_NODE;
01667         (*n_res)++;
01668       
01669         result[*n_res].pos.x() = node.pos.x();
01670         result[*n_res].pos.y() = node.pos.y();
01671         result[*n_res].pos.z() = node.pos.z();
01672         result[*n_res].loc     = Z_MAX_x_max_NODE;
01673         (*n_res)++;
01674       
01675         result[*n_res].pos.x() = node.pos.x();
01676         result[*n_res].pos.y() = node.pos.y();
01677         result[*n_res].pos.z() = node.pos.z();
01678         result[*n_res].loc     = Z_MAX_y_min_NODE;
01679         (*n_res)++;
01680       
01681         result[*n_res].pos.x() = node.pos.x();
01682         result[*n_res].pos.y() = node.pos.y();
01683         result[*n_res].pos.z() = node.pos.z();
01684         result[*n_res].loc     = Z_MAX_y_max_NODE;
01685         (*n_res)++;
01686       }
01687       break;
01688 
01689     case Z_MAX_x_min_NODE:
01690       if ((node.pos.z()<z_size)
01691           &&(domain[node.pos])){//no +1 because node ok if ZMIN ok.
01692       
01693         result[*n_res].pos.x() = node.pos.x();
01694         result[*n_res].pos.y() = node.pos.y();
01695         result[*n_res].pos.z() = node.pos.z()+1;
01696         result[*n_res].loc     = CENTER_NODE;
01697         (*n_res)++;
01698       }
01699       break;
01700 
01701     case Z_MAX_x_max_NODE:
01702       if ((node.pos.z()<z_size)
01703           &&(domain[node.pos])){//no +1 because node ok if ZMIN ok.
01704 
01705         result[*n_res].pos.x() = node.pos.x();
01706         result[*n_res].pos.y() = node.pos.y();
01707         result[*n_res].pos.z() = node.pos.z()+1;
01708         result[*n_res].loc     = CENTER_NODE;
01709         (*n_res)++;
01710       }
01711       break;
01712 
01713     case Z_MAX_y_min_NODE:
01714       if ((node.pos.z()<z_size)
01715           &&(domain[node.pos])){//no +1 because node ok if ZMIN ok.
01716          
01717         result[*n_res].pos.x() = node.pos.x();
01718         result[*n_res].pos.y() = node.pos.y();
01719         result[*n_res].pos.z() = node.pos.z()+1;
01720         result[*n_res].loc     = CENTER_NODE;
01721         (*n_res)++;
01722       }
01723       break;
01724 
01725     case Z_MAX_y_max_NODE:
01726       if ((node.pos.z()<z_size)
01727           &&(domain[node.pos])){//no +1 because node ok if ZMIN ok.
01728         
01729         result[*n_res].pos.x() = node.pos.x();
01730         result[*n_res].pos.y() = node.pos.y();
01731         result[*n_res].pos.z() = node.pos.z()+1;
01732         result[*n_res].loc     = CENTER_NODE;
01733         (*n_res)++;
01734       }
01735       break;
01736     }
01737   }
01738 
01739 
01740 
01741 
01742 
01746   template<typename Real>
01747   void
01748   PushRelabel_non_linear_grid_3D<Real>::
01749   adjacent_nodes(const node_type& node,
01750                  node_type* const result,
01751                  size_type* const n_res) const{
01752 
01753     *n_res = 0;
01754 
01755     // ################ toward X_MIN ################ 
01756       
01757     switch(node.loc){
01758       
01759     case CENTER_NODE:
01760       if ((node.pos.x()>0)
01761           &&(domain(node.pos.x()-1,node.pos.y(),node.pos.z())||
01762              ((node.pos.z()>0)&&
01763               domain(node.pos.x()-1,node.pos.y(),node.pos.z()-1)))){
01764 
01765         if(edge_residual(node,X_MIN_DIR)>epsilon){
01766           result[*n_res].pos.x() = node.pos.x()-1;
01767           result[*n_res].pos.y() = node.pos.y();
01768           result[*n_res].pos.z() = node.pos.z();
01769           result[*n_res].loc     = CENTER_NODE;
01770           (*n_res)++;
01771         }
01772       }
01773       break;
01774       
01775     case Z_MAX_x_min_NODE:
01776       if ((node.pos.x()>0)
01777           &&(domain(node.pos.x()-1,node.pos.y(),node.pos.z()))){
01778         if(edge_residual(node,X_MIN_DIR)>epsilon){
01779           result[*n_res].pos.x() = node.pos.x()-1;
01780           result[*n_res].pos.y() = node.pos.y();
01781           result[*n_res].pos.z() = node.pos.z();
01782           result[*n_res].loc     = Z_MAX_x_max_NODE;
01783           (*n_res)++;
01784         }
01785       }
01786       break;
01787       
01788     case Z_MAX_x_max_NODE:
01789     case Z_MAX_y_min_NODE:
01790     case Z_MAX_y_max_NODE:
01791       break;
01792     }
01793 
01794     // ################ toward Y_MIN ################ 
01795   
01796     switch(node.loc){
01797       
01798     case CENTER_NODE:
01799       if ((node.pos.y()>0)
01800           &&(domain(node.pos.x(),node.pos.y()-1,node.pos.z())||
01801              ((node.pos.z()>0)&&
01802               domain(node.pos.x(),node.pos.y()-1,node.pos.z()-1)))){
01803         if(edge_residual(node,Y_MIN_DIR)>epsilon){
01804           result[*n_res].pos.x() = node.pos.x();
01805           result[*n_res].pos.y() = node.pos.y()-1;
01806           result[*n_res].pos.z() = node.pos.z();
01807           result[*n_res].loc     = CENTER_NODE;
01808           (*n_res)++;
01809         }
01810       }
01811       break;
01812       
01813     case Z_MAX_y_min_NODE:
01814       if ((node.pos.y()>0)
01815           &&(domain(node.pos.x(),node.pos.y()-1,node.pos.z()))){
01816         if(edge_residual(node,Y_MIN_DIR)>epsilon){
01817           result[*n_res].pos.x() = node.pos.x();
01818           result[*n_res].pos.y() = node.pos.y()-1;
01819           result[*n_res].pos.z() = node.pos.z();
01820           result[*n_res].loc     = Z_MAX_y_max_NODE;
01821           (*n_res)++;
01822         }
01823       }
01824       break;
01825       
01826     case Z_MAX_x_max_NODE:
01827     case Z_MAX_x_min_NODE:
01828     case Z_MAX_y_max_NODE:
01829       break;
01830     }
01831 
01832   
01833     // ################ toward Z_MIN ################
01834   
01835     switch(node.loc){
01836       
01837     case CENTER_NODE:
01838 
01839       if ((node.pos.z()>0)
01840           &&(domain(node.pos.x(),node.pos.y(),node.pos.z()-1))){
01841 
01842         if (edge_residual(node,Z_MIN_x_min_DIR)>epsilon){
01843           result[*n_res].pos.x() = node.pos.x();
01844           result[*n_res].pos.y() = node.pos.y();
01845           result[*n_res].pos.z() = node.pos.z()-1;
01846           result[*n_res].loc     = Z_MAX_x_min_NODE;
01847           (*n_res)++;
01848         }
01849 
01850         if (edge_residual(node,Z_MIN_x_max_DIR)>epsilon){
01851           result[*n_res].pos.x() = node.pos.x();
01852           result[*n_res].pos.y() = node.pos.y();
01853           result[*n_res].pos.z() = node.pos.z()-1;
01854           result[*n_res].loc     = Z_MAX_x_max_NODE;
01855           (*n_res)++;
01856         }
01857 
01858         if (edge_residual(node,Z_MIN_y_min_DIR)>epsilon){
01859           result[*n_res].pos.x() = node.pos.x();
01860           result[*n_res].pos.y() = node.pos.y();
01861           result[*n_res].pos.z() = node.pos.z()-1;
01862           result[*n_res].loc     = Z_MAX_y_min_NODE;
01863           (*n_res)++;
01864         }
01865 
01866         if (edge_residual(node,Z_MIN_y_max_DIR)>epsilon){
01867           result[*n_res].pos.x() = node.pos.x();
01868           result[*n_res].pos.y() = node.pos.y();
01869           result[*n_res].pos.z() = node.pos.z()-1;
01870           result[*n_res].loc     = Z_MAX_y_max_NODE;
01871           (*n_res)++;
01872         }
01873       }
01874       break;
01875 
01876     case Z_MAX_x_min_NODE:
01877       if (edge_residual(node,Z_MIN_x_max_DIR)>epsilon){
01878         result[*n_res].pos.x() = node.pos.x();
01879         result[*n_res].pos.y() = node.pos.y();
01880         result[*n_res].pos.z() = node.pos.z();
01881         result[*n_res].loc     = CENTER_NODE;
01882         (*n_res)++;
01883       }
01884       break;
01885 
01886     case Z_MAX_x_max_NODE:
01887       if (edge_residual(node,Z_MIN_x_min_DIR)>epsilon){
01888         result[*n_res].pos.x() = node.pos.x();
01889         result[*n_res].pos.y() = node.pos.y();
01890         result[*n_res].pos.z() = node.pos.z();
01891         result[*n_res].loc     = CENTER_NODE;
01892         (*n_res)++;
01893       }
01894       break;
01895 
01896     case Z_MAX_y_min_NODE:
01897       if (edge_residual(node,Z_MIN_y_max_DIR)>epsilon){
01898         result[*n_res].pos.x() = node.pos.x();
01899         result[*n_res].pos.y() = node.pos.y();
01900         result[*n_res].pos.z() = node.pos.z();
01901         result[*n_res].loc     = CENTER_NODE;
01902         (*n_res)++;
01903       }
01904       break;
01905 
01906     case Z_MAX_y_max_NODE:
01907       if (edge_residual(node,Z_MIN_y_min_DIR)>epsilon){
01908         result[*n_res].pos.x() = node.pos.x();
01909         result[*n_res].pos.y() = node.pos.y();
01910         result[*n_res].pos.z() = node.pos.z();
01911         result[*n_res].loc     = CENTER_NODE;
01912         (*n_res)++;
01913       }
01914       break;  
01915     }
01916 
01917     // ################ toward X_MAX ################ 
01918 
01919     switch(node.loc){
01920 
01921     case CENTER_NODE:
01922       if ((node.pos.x()<x_size-1)
01923           &&(domain(node.pos.x()+1,node.pos.y(),node.pos.z())||
01924              ((node.pos.z()>0)&&
01925               domain(node.pos.x()+1,node.pos.y(),node.pos.z()-1)))){
01926         if (edge_residual(node,X_MAX_DIR)>epsilon){
01927     
01928           result[*n_res].pos.x() = node.pos.x()+1;
01929           result[*n_res].pos.y() = node.pos.y();
01930           result[*n_res].pos.z() = node.pos.z();
01931           result[*n_res].loc     = CENTER_NODE;
01932           (*n_res)++;
01933         }
01934       }
01935       break;
01936 
01937     case Z_MAX_x_max_NODE:
01938       if ((node.pos.x()<x_size-1)
01939           &&(domain(node.pos.x()+1,node.pos.y(),node.pos.z()))){
01940         if (edge_residual(node,X_MAX_DIR)>epsilon){
01941     
01942           result[*n_res].pos.x() = node.pos.x()+1;
01943           result[*n_res].pos.y() = node.pos.y();
01944           result[*n_res].pos.z() = node.pos.z();
01945           result[*n_res].loc     = Z_MAX_x_min_NODE;
01946           (*n_res)++;
01947         }
01948       }
01949       break;
01950 
01951     case Z_MAX_x_min_NODE:
01952     case Z_MAX_y_min_NODE:
01953     case Z_MAX_y_max_NODE:
01954       break;  
01955     }
01956 
01957     // ################ toward Y_MAX ################ 
01958 
01959     switch(node.loc){
01960 
01961     case CENTER_NODE:
01962       if ((node.pos.y()<y_size-1)
01963           &&(domain(node.pos.x(),node.pos.y()+1,node.pos.z())||
01964              ((node.pos.z()>0)&&
01965               domain(node.pos.x(),node.pos.y()+1,node.pos.z()-1)))){
01966 
01967         if (edge_residual(node,Y_MAX_DIR)>epsilon){
01968     
01969           result[*n_res].pos.x() = node.pos.x();
01970           result[*n_res].pos.y() = node.pos.y()+1;
01971           result[*n_res].pos.z() = node.pos.z();
01972           result[*n_res].loc     = CENTER_NODE;
01973           (*n_res)++;
01974         }
01975       }
01976       break;
01977 
01978     case Z_MAX_y_max_NODE:
01979       if ((node.pos.y()<y_size-1)
01980           &&(domain(node.pos.x(),node.pos.y()+1,node.pos.z()))){
01981         if (edge_residual(node,Y_MAX_DIR)>epsilon){
01982     
01983           result[*n_res].pos.x() = node.pos.x();
01984           result[*n_res].pos.y() = node.pos.y()+1;
01985           result[*n_res].pos.z() = node.pos.z();
01986           result[*n_res].loc     = Z_MAX_y_min_NODE;
01987           (*n_res)++;
01988         }
01989       }
01990       break;
01991 
01992     case Z_MAX_x_min_NODE:
01993     case Z_MAX_x_max_NODE:
01994     case Z_MAX_y_min_NODE:
01995       break;  
01996     }
01997   
01998 
01999     // ################ toward Z_MAX ################ 
02000 
02001     switch(node.loc){
02002     case CENTER_NODE:
02003       if ((node.pos.z()<z_size)
02004           &&(domain[node.pos])){
02005 
02006         if (edge_residual(node,Z_MAX_x_min_DIR)>epsilon){
02007       
02008           result[*n_res].pos.x() = node.pos.x();
02009           result[*n_res].pos.y() = node.pos.y();
02010           result[*n_res].pos.z() = node.pos.z();
02011           result[*n_res].loc     = Z_MAX_x_min_NODE;
02012           (*n_res)++;
02013         }
02014 
02015         if (edge_residual(node,Z_MAX_x_max_DIR)>epsilon){
02016       
02017           result[*n_res].pos.x() = node.pos.x();
02018           result[*n_res].pos.y() = node.pos.y();
02019           result[*n_res].pos.z() = node.pos.z();
02020           result[*n_res].loc     = Z_MAX_x_max_NODE;
02021           (*n_res)++;
02022         }
02023 
02024         if (edge_residual(node,Z_MAX_y_min_DIR)>epsilon){
02025       
02026           result[*n_res].pos.x() = node.pos.x();
02027           result[*n_res].pos.y() = node.pos.y();
02028           result[*n_res].pos.z() = node.pos.z();
02029           result[*n_res].loc     = Z_MAX_y_min_NODE;
02030           (*n_res)++;
02031         }
02032 
02033         if (edge_residual(node,Z_MAX_y_max_DIR)>epsilon){
02034       
02035           result[*n_res].pos.x() = node.pos.x();
02036           result[*n_res].pos.y() = node.pos.y();
02037           result[*n_res].pos.z() = node.pos.z();
02038           result[*n_res].loc     = Z_MAX_y_max_NODE;
02039           (*n_res)++;
02040         }
02041       }
02042       break;
02043 
02044     case Z_MAX_x_min_NODE:
02045       if ((node.pos.z()<z_size)
02046           &&(domain[node.pos])//no +1 because node ok if ZMIN ok.
02047           &&(edge_residual(node,Z_MAX_x_max_DIR)>epsilon)){
02048       
02049         result[*n_res].pos.x() = node.pos.x();
02050         result[*n_res].pos.y() = node.pos.y();
02051         result[*n_res].pos.z() = node.pos.z()+1;
02052         result[*n_res].loc     = CENTER_NODE;
02053         (*n_res)++;
02054       }
02055       break;
02056 
02057     case Z_MAX_x_max_NODE:
02058       if ((node.pos.z()<z_size)
02059           &&(domain[node.pos])//no +1 because node ok if ZMIN ok.
02060           &&(edge_residual(node,Z_MAX_x_min_DIR)>epsilon)){
02061 
02062         result[*n_res].pos.x() = node.pos.x();
02063         result[*n_res].pos.y() = node.pos.y();
02064         result[*n_res].pos.z() = node.pos.z()+1;
02065         result[*n_res].loc     = CENTER_NODE;
02066         (*n_res)++;
02067       }
02068       break;
02069 
02070     case Z_MAX_y_min_NODE:
02071       if ((node.pos.z()<z_size)
02072           &&(domain[node.pos])//no +1 because node ok if ZMIN ok.
02073           &&(edge_residual(node,Z_MAX_y_max_DIR)>epsilon)){
02074       
02075         result[*n_res].pos.x() = node.pos.x();
02076         result[*n_res].pos.y() = node.pos.y();
02077         result[*n_res].pos.z() = node.pos.z()+1;
02078         result[*n_res].loc     = CENTER_NODE;
02079         (*n_res)++;
02080       }
02081       break;
02082 
02083     case Z_MAX_y_max_NODE:
02084       if ((node.pos.z()<z_size)
02085           &&(domain[node.pos])//no +1 because node ok if ZMIN ok.
02086           &&(edge_residual(node,Z_MAX_y_min_DIR)>epsilon)){
02087 
02088         result[*n_res].pos.x() = node.pos.x();
02089         result[*n_res].pos.y() = node.pos.y();
02090         result[*n_res].pos.z() = node.pos.z()+1;
02091         result[*n_res].loc     = CENTER_NODE;
02092         (*n_res)++;
02093       }
02094       break;
02095     }
02096   }
02097 
02098 
02099   template<typename Real>
02100   typename PushRelabel_non_linear_grid_3D<Real>::real_type
02101   PushRelabel_non_linear_grid_3D<Real>::
02102   node_excess(const node_type& node) const{
02103   
02104     // neigbors of the source have an infinite excess.
02105     if ((node.loc == CENTER_NODE) && (node.pos.z() == min_bound(node.pos.x(),
02106                                                                 node.pos.y()))){
02107 #ifndef WITHOUT_LIMITS
02108       return (std::numeric_limits<real_type>::max());
02109 #else
02110       return 1e20;
02111 #endif
02112     }
02113   
02114     // neighbors of the think have no excess.
02115     if ((node.loc == CENTER_NODE) && (node.pos.z() == max_bound(node.pos.x(),
02116                                                                 node.pos.y()))){
02117       return 0;
02118     } 
02119   
02120     node_type neighbor[12];
02121     size_type n_neighbor;
02122 
02123     neighbors(node,neighbor,&n_neighbor);
02124 
02125     real_type res = 0;
02126     for(size_type n=0;n<n_neighbor;n++){
02127       res -= edge_flow(node,direction(node,neighbor[n]));
02128     }
02129     return res;
02130   }
02131 
02132 
02136   template<typename Real>
02137   void
02138   PushRelabel_non_linear_grid_3D<Real>::
02139   add_flow(const node_type&     from,
02140            const direction_type dir,
02141            const real_type      flow){
02142 
02143 //     if (edge_residual(from,dir)<=flow){
02144     if (edge_residual(from,dir)+epsilon<flow){
02145       Message::error<<"not enough capacity ("<<edge_residual(from,dir)
02146                     <<") for flow ("<<flow<<") ["
02147                     <<(flow-edge_residual(from,dir))<<"]"
02148                     <<Message::done;
02149     }
02150 
02151     switch(from.loc){
02152       // ########################### CENTER_NODE ###########################
02153     case CENTER_NODE:
02154     
02155       switch(dir){
02156       case X_MIN_DIR:
02157         x_major_derivative_edge_flow(from.pos.x()-1,from.pos.y(),from.pos.z())
02158           -= flow;
02159         return;
02160       
02161       case X_MAX_DIR:
02162         x_major_derivative_edge_flow[from.pos]
02163           += flow;
02164         return;
02165 
02166       case Y_MIN_DIR:
02167         y_major_derivative_edge_flow(from.pos.x(),from.pos.y()-1,from.pos.z())
02168           -= flow;
02169         return;
02170       
02171       case Y_MAX_DIR:
02172         y_major_derivative_edge_flow[from.pos]
02173           += flow;
02174         return;  
02175 
02176       case Z_MIN_x_min_DIR:
02177         cost_edge_Z_MAX_MAX_x_min_flow(from.pos.x(),from.pos.y(),from.pos.z()-1)
02178           -= flow;
02179         return;
02180       
02181       case Z_MIN_x_max_DIR:
02182         cost_edge_Z_MAX_MAX_x_max_flow(from.pos.x(),from.pos.y(),from.pos.z()-1)
02183           -= flow;
02184         return;
02185 
02186       case Z_MIN_y_min_DIR:
02187         cost_edge_Z_MAX_MAX_y_min_flow(from.pos.x(),from.pos.y(),from.pos.z()-1)
02188           -= flow;
02189         return;
02190       
02191       case Z_MIN_y_max_DIR:
02192         cost_edge_Z_MAX_MAX_y_max_flow(from.pos.x(),from.pos.y(),from.pos.z()-1)
02193           -= flow;
02194         return;  
02195 
02196       case Z_MAX_x_min_DIR:
02197         cost_edge_Z_MAX_x_min_flow[from.pos]
02198           += flow;
02199         return;
02200      
02201       case Z_MAX_x_max_DIR:
02202         cost_edge_Z_MAX_x_max_flow[from.pos]
02203           += flow;
02204         return;
02205 
02206       case Z_MAX_y_min_DIR:
02207         cost_edge_Z_MAX_y_min_flow[from.pos]
02208           += flow;
02209         return;
02210      
02211       case Z_MAX_y_max_DIR:
02212         cost_edge_Z_MAX_y_max_flow[from.pos]
02213           += flow;
02214         return;  
02215       }
02216 
02217       Message::error<<"add_flow: bad end 1"<<Message::done;
02218     
02219       // ########################### Z_MAX_x_min_NODE ###########################  
02220     case Z_MAX_x_min_NODE:
02221 
02222       switch(dir){
02223       case X_MIN_DIR:
02224         x_minor_derivative_edge_flow(from.pos.x()-1,from.pos.y(),from.pos.z())
02225           -= flow;
02226         return;
02227 
02228       case X_MAX_DIR:
02229         Message::error<<"add_flow : bad end 2.1"<<Message::done;
02230 
02231       case Y_MIN_DIR:
02232         Message::error<<"add_flow : bad end 2.2"<<Message::done;
02233       
02234       case Y_MAX_DIR:
02235         Message::error<<"add_flow : bad end 2.3"<<Message::done;
02236 
02237       case Z_MIN_x_min_DIR:
02238         Message::error<<"add_flow : bad end 2.4"<<Message::done;
02239    
02240       case Z_MIN_x_max_DIR:
02241         cost_edge_Z_MAX_x_min_flow[from.pos]
02242           -= flow;
02243         return;
02244 
02245       case Z_MIN_y_min_DIR:
02246         Message::error<<"add_flow : bad end 2.5"<<Message::done;
02247    
02248       case Z_MIN_y_max_DIR:
02249         Message::error<<"add_flow : bad end 2.6"<<Message::done;
02250 
02251       case Z_MAX_x_min_DIR:
02252         Message::error<<"add_flow : bad end 2.7"<<Message::done;
02253 
02254       case Z_MAX_x_max_DIR:
02255         cost_edge_Z_MAX_MAX_x_min_flow[from.pos]
02256           += flow;
02257         return;
02258 
02259       case Z_MAX_y_min_DIR:
02260         Message::error<<"add_flow : bad end 2.8"<<Message::done;
02261 
02262       case Z_MAX_y_max_DIR:
02263         Message::error<<"add_flow : bad end 2.9"<<Message::done;
02264       }
02265     
02266       Message::error<<"add_flow : bad end 2"<<Message::done;
02267     
02268       // ########################### Z_MAX_x_max_NODE ###########################
02269     case Z_MAX_x_max_NODE:
02270 
02271       switch(dir){
02272       case X_MIN_DIR:
02273         Message::error<<"add_flow : bad end 3.1"<<Message::done;
02274 
02275       case X_MAX_DIR:
02276         x_minor_derivative_edge_flow[from.pos]
02277           += flow;
02278         return;
02279 
02280       case Y_MIN_DIR:
02281         Message::error<<"add_flow : bad end 3.2"<<Message::done;
02282 
02283       case Y_MAX_DIR:
02284         Message::error<<"add_flow : bad end 3.3"<<Message::done;
02285 
02286       case Z_MIN_x_min_DIR:
02287         cost_edge_Z_MAX_x_max_flow[from.pos]
02288           -= flow;
02289         return;
02290 
02291       case Z_MIN_x_max_DIR: 
02292         Message::error<<"add_flow : bad end 3.4"<<Message::done;
02293 
02294       case Z_MIN_y_min_DIR:
02295         Message::error<<"add_flow : bad end 3.5"<<Message::done;
02296 
02297       case Z_MIN_y_max_DIR: 
02298         Message::error<<"add_flow : bad end 3.6"<<Message::done;  
02299 
02300       case Z_MAX_x_min_DIR:
02301         cost_edge_Z_MAX_MAX_x_max_flow[from.pos]
02302           += flow;
02303         return;
02304 
02305       case Z_MAX_x_max_DIR:
02306         Message::error<<"add_flow : bad end 3.7"<<Message::done;
02307 
02308       case Z_MAX_y_min_DIR:
02309         Message::error<<"add_flow : bad end 3.8"<<Message::done;
02310 
02311       case Z_MAX_y_max_DIR:
02312         Message::error<<"add_flow : bad end 3.9"<<Message::done;  
02313       }
02314     
02315       Message::error<<"add_flow : bad end 3"<<Message::done;
02316 
02317       // ########################### Z_MAX_y_min_NODE ###########################  
02318     case Z_MAX_y_min_NODE:
02319 
02320       switch(dir){
02321       case X_MIN_DIR:
02322         Message::error<<"add_flow : bad end 4.1"<<Message::done;
02323 
02324       case X_MAX_DIR:
02325         Message::error<<"add_flow : bad end 4.2"<<Message::done;
02326 
02327       case Y_MIN_DIR:
02328         y_minor_derivative_edge_flow(from.pos.x(),from.pos.y()-1,from.pos.z())
02329           -= flow;
02330         return; 
02331       
02332       case Y_MAX_DIR:
02333         Message::error<<"add_flow : bad end 4.3"<<Message::done;
02334 
02335       case Z_MIN_x_min_DIR:
02336         Message::error<<"add_flow : bad end 4.4"<<Message::done;
02337    
02338       case Z_MIN_x_max_DIR:
02339         Message::error<<"add_flow : bad end 4.5"<<Message::done;
02340 
02341       case Z_MIN_y_min_DIR:
02342         Message::error<<"add_flow : bad end 4.6"<<Message::done;
02343    
02344       case Z_MIN_y_max_DIR:
02345         cost_edge_Z_MAX_y_min_flow[from.pos]
02346           -= flow;
02347         return;
02348 
02349       case Z_MAX_x_min_DIR:
02350         Message::error<<"add_flow : bad end 4.7"<<Message::done;
02351 
02352       case Z_MAX_x_max_DIR:
02353         Message::error<<"add_flow : bad end 4.8"<<Message::done;
02354 
02355       case Z_MAX_y_min_DIR:
02356         Message::error<<"add_flow : bad end 4.9"<<Message::done;
02357 
02358       case Z_MAX_y_max_DIR:
02359         cost_edge_Z_MAX_MAX_y_min_flow[from.pos]
02360           += flow;
02361         return;
02362       }
02363     
02364       Message::error<<"add_flow : bad end 4"<<Message::done;
02365     
02366       // ########################### Z_MAX_y_max_NODE ###########################
02367     case Z_MAX_y_max_NODE:
02368 
02369       switch(dir){
02370       case X_MIN_DIR:
02371         Message::error<<"add_flow : bad end 5.1"<<Message::done;
02372 
02373       case X_MAX_DIR:
02374         Message::error<<"add_flow : bad end 5.2"<<Message::done;
02375 
02376       case Y_MIN_DIR:
02377         Message::error<<"add_flow : bad end 5.3"<<Message::done;
02378 
02379       case Y_MAX_DIR:
02380         y_minor_derivative_edge_flow[from.pos]
02381           += flow;
02382         return;
02383 
02384       case Z_MIN_x_min_DIR:
02385         Message::error<<"add_flow : bad end 5.4"<<Message::done;
02386 
02387       case Z_MIN_x_max_DIR: 
02388         Message::error<<"add_flow : bad end 5.5"<<Message::done;
02389 
02390       case Z_MIN_y_min_DIR:
02391         cost_edge_Z_MAX_y_max_flow[from.pos]
02392           -= flow;
02393         return;
02394 
02395       case Z_MIN_y_max_DIR: 
02396         Message::error<<"add_flow : bad end 5.6"<<Message::done;  
02397 
02398       case Z_MAX_x_min_DIR:
02399         Message::error<<"add_flow : bad end 5.7"<<Message::done;
02400 
02401       case Z_MAX_x_max_DIR:
02402         Message::error<<"add_flow : bad end 5.8"<<Message::done;
02403 
02404       case Z_MAX_y_min_DIR:
02405         cost_edge_Z_MAX_MAX_y_max_flow[from.pos]
02406           += flow;
02407         return;
02408 
02409       case Z_MAX_y_max_DIR:
02410         Message::error<<"add_flow : bad end 5.9"<<Message::done;  
02411       }
02412     
02413       Message::error<<"add_flow : bad end 5"<<Message::done;
02414     }
02415   
02416     Message::error<<"add_flow : bad end 0"<<Message::done;
02417   }
02418 
02419 
02420   template<typename Real>
02421   typename PushRelabel_non_linear_grid_3D<Real>::direction_type
02422   PushRelabel_non_linear_grid_3D<Real>::
02423   direction(const node_type& from,
02424             const node_type& to) const{
02425 
02426     switch(from.loc){
02427 
02428       // ########################### CENTER_NODE ###########################
02429     case CENTER_NODE:
02430       switch(to.loc){
02431       
02432       case CENTER_NODE:
02433         if (from.pos.z() == to.pos.z()){
02434       
02435           if ((from.pos.x()+1 == to.pos.x()) && (from.pos.y() == to.pos.y())){
02436             return X_MAX_DIR;
02437           }
02438           else if ((from.pos.x() == to.pos.x()+1) && (from.pos.y() == to.pos.y())){
02439             return X_MIN_DIR;
02440           }
02441           else if ((from.pos.x() == to.pos.x()) && (from.pos.y()+1 == to.pos.y())){
02442             return Y_MAX_DIR;
02443           }
02444           else if ((from.pos.x() == to.pos.x()) && (from.pos.y() == to.pos.y()+1)){
02445             return Y_MIN_DIR;
02446           }
02447           else{
02448             Message::error<<"direction : bad end 1.1"<<Message::done;
02449             return 0;
02450           }
02451         }
02452         else{
02453           Message::error<<"direction : bad end 1.2"<<Message::done;
02454           return 0;
02455         }
02456           
02457       case Z_MAX_x_min_NODE:
02458         if ((from.pos.x() == to.pos.x()) && (from.pos.y() == to.pos.y())){
02459           if (to.pos.z()+1 == from.pos.z()){
02460             return Z_MIN_x_min_DIR;
02461           }
02462           else if (from.pos.z() == to.pos.z()){
02463             return Z_MAX_x_min_DIR;
02464           }
02465           else{
02466             Message::error<<"direction : bad end 1.3"<<Message::done;
02467             return 0;
02468           }
02469         }
02470         else{
02471           Message::error<<"direction : bad end 1.4"<<Message::done;
02472           return 0;
02473         }
02474     
02475       case Z_MAX_x_max_NODE:
02476         if ((from.pos.x() == to.pos.x()) && (from.pos.y() == to.pos.y())){
02477           if (to.pos.z()+1 == from.pos.z()){
02478             return Z_MIN_x_max_DIR;
02479           }
02480           else if (from.pos.z() == to.pos.z()){
02481             return Z_MAX_x_max_DIR;
02482           }
02483           else{
02484             Message::error<<"direction : bad end 1.5"<<Message::done;
02485             return 0;
02486           }
02487         }
02488         else{
02489           Message::error<<"direction : bad end 1.6"<<Message::done;
02490           return 0;
02491         }
02492 
02493       case Z_MAX_y_min_NODE:
02494         if ((from.pos.x() == to.pos.x()) && (from.pos.y() == to.pos.y())){
02495           if (to.pos.z()+1 == from.pos.z()){
02496             return Z_MIN_y_min_DIR;
02497           }
02498           else if (from.pos.z() == to.pos.z()){
02499             return Z_MAX_y_min_DIR;
02500           }
02501           else{
02502             Message::error<<"direction : bad end 1.7"<<Message::done;
02503             return 0;
02504           }
02505         }
02506         else{
02507           Message::error<<"direction : bad end 1.8\n"
02508                         <<VALUE_OF(from.pos)<<"\t"<<VALUE_OF(int(from.loc))<<"\n"
02509                         <<VALUE_OF(to.pos)<<"\t"<<VALUE_OF(int(to.loc))
02510                         <<Message::done;
02511           return 0;
02512         }
02513     
02514       case Z_MAX_y_max_NODE:
02515         if ((from.pos.x() == to.pos.x()) && (from.pos.y() == to.pos.y())){
02516           if (to.pos.z()+1 == from.pos.z()){
02517             return Z_MIN_y_max_DIR;
02518           }
02519           else if (from.pos.z() == to.pos.z()){
02520             return Z_MAX_y_max_DIR;
02521           }
02522           else{
02523             Message::error<<"direction : bad end 1.9"<<Message::done;
02524             return 0;
02525           }
02526         }
02527         else{
02528           Message::error<<"direction : bad end 1.10"<<Message::done;
02529           return 0;
02530         }  
02531       }
02532 
02533       // ########################### Z_MAX_x_min_NODE ###########################  
02534     case Z_MAX_x_min_NODE:
02535       switch(to.loc){
02536       
02537       case CENTER_NODE:
02538         if ((from.pos.x() == to.pos.x()) && (from.pos.y() == to.pos.y())){
02539           if (from.pos.z() == to.pos.z()){
02540             return Z_MIN_x_max_DIR;
02541           }
02542           else if (from.pos.z()+1 == to.pos.z()){
02543             return Z_MAX_x_max_DIR;
02544           }
02545           else{
02546             Message::error<<"direction : bad end 2.1"<<Message::done;
02547             return 0;
02548           }
02549         }
02550       
02551       case Z_MAX_x_min_NODE:
02552         Message::error<<"direction : bad end 2.2"<<Message::done;
02553         return 0;
02554       
02555     
02556       case Z_MAX_x_max_NODE:
02557         if ((from.pos.y() == to.pos.y())&&
02558             (from.pos.z() == to.pos.z())&&
02559             (from.pos.x() == to.pos.x()+1)){
02560           return X_MIN_DIR;
02561         }
02562         else{
02563           Message::error<<"direction : bad end 2.3 "<<Message::done;
02564           return 0;
02565         }
02566 
02567       case Z_MAX_y_min_NODE:
02568         Message::error<<"direction : bad end 2.4"<<Message::done;
02569         return 0;
02570       
02571     
02572       case Z_MAX_y_max_NODE:
02573         Message::error<<"direction : bad end 2.5 "<<Message::done;
02574         return 0;
02575       }
02576     
02577       // ########################### Z_MAX_x_max_NODE ########################### 
02578     case Z_MAX_x_max_NODE:
02579       switch(to.loc){
02580       
02581       case CENTER_NODE:
02582         if ((from.pos.x() == to.pos.x())&&(from.pos.y() == to.pos.y())){
02583           if (from.pos.z() == to.pos.z()){
02584             return Z_MIN_x_min_DIR;
02585           }
02586           else if (from.pos.z()+1 == to.pos.z()){
02587             return Z_MAX_x_min_DIR;
02588           }
02589           else{
02590             Message::error<<"direction : bad end 3.1"<<Message::done;
02591             return 0;
02592           }
02593         }
02594 
02595       case Z_MAX_x_min_NODE:
02596         if ((from.pos.y() == to.pos.y())&&
02597             (from.pos.z() == to.pos.z())&&
02598             (from.pos.x()+1 == to.pos.x())){
02599           return X_MAX_DIR;
02600         }      
02601     
02602       case Z_MAX_x_max_NODE:
02603         Message::error<<"direction : bad end 3.2"<<Message::done;
02604         return 0;
02605 
02606       case Z_MAX_y_min_NODE:
02607         Message::error<<"direction : bad end 3.3"<<Message::done;
02608         return 0;
02609       
02610       case Z_MAX_y_max_NODE:
02611         Message::error<<"direction : bad end 3.4"<<Message::done;
02612         return 0;
02613       }
02614 
02615       // ########################### Z_MAX_y_min_NODE ###########################  
02616     case Z_MAX_y_min_NODE:
02617       switch(to.loc){
02618       
02619       case CENTER_NODE:
02620         if ((from.pos.x() == to.pos.x()) && (from.pos.y() == to.pos.y())){
02621           if (from.pos.z() == to.pos.z()){
02622             return Z_MIN_y_max_DIR;
02623           }
02624           else if (from.pos.z()+1 == to.pos.z()){
02625             return Z_MAX_y_max_DIR;
02626           }
02627           else{
02628             Message::error<<"direction : bad end 4.1"<<Message::done;
02629             return 0;
02630           }
02631         }
02632       
02633       case Z_MAX_x_min_NODE:
02634         Message::error<<"direction : bad end 4.2"<<Message::done;
02635         return 0;
02636       
02637     
02638       case Z_MAX_x_max_NODE:
02639         Message::error<<"direction : bad end 4.3 "<<Message::done;
02640         return 0;      
02641 
02642       case Z_MAX_y_min_NODE:
02643         Message::error<<"direction : bad end 4.4"<<Message::done;
02644         return 0;
02645       
02646     
02647       case Z_MAX_y_max_NODE:
02648         if ((from.pos.x() == to.pos.x())&&
02649             (from.pos.z() == to.pos.z())&&
02650             (from.pos.y() == to.pos.y()+1)){
02651           return Y_MIN_DIR;
02652         }
02653         else{
02654           Message::error<<"direction : bad end 4.5 "<<Message::done;
02655           return 0;
02656         }
02657       }
02658     
02659       // ########################### Z_MAX_y_max_NODE ########################### 
02660     case Z_MAX_y_max_NODE:
02661       switch(to.loc){
02662       
02663       case CENTER_NODE:
02664         if ((from.pos.x() == to.pos.x())&&(from.pos.y() == to.pos.y())){
02665           if (from.pos.z() == to.pos.z()){
02666             return Z_MIN_y_min_DIR;
02667           }
02668           else if (from.pos.z()+1 == to.pos.z()){
02669             return Z_MAX_y_min_DIR;
02670           }
02671           else{
02672             Message::error<<"direction : bad end 5.1"<<Message::done;
02673             return 0;
02674           }
02675         }
02676 
02677       case Z_MAX_x_min_NODE:    
02678         Message::error<<"direction : bad end 5.2"<<Message::done;
02679         return 0;
02680       
02681       case Z_MAX_x_max_NODE:
02682         Message::error<<"direction : bad end 5.3"<<Message::done;
02683         return 0;
02684 
02685       case Z_MAX_y_min_NODE:
02686         if ((from.pos.x() == to.pos.x())&&
02687             (from.pos.z() == to.pos.z())&&
02688             (from.pos.y()+1 == to.pos.y())){
02689           return Y_MAX_DIR;
02690         }      
02691       
02692       case Z_MAX_y_max_NODE:
02693         Message::error<<"direction : bad end 5.4"<<Message::done;
02694         return 0;
02695       }
02696   
02697     }
02698 
02699     Message::error<<"direction : bad end 0"<<Message::done;
02700     return 0;
02701   }
02702 
02703 
02704   template<typename Real>
02705   typename PushRelabel_non_linear_grid_3D<Real>::label_type
02706   PushRelabel_non_linear_grid_3D<Real>::
02707   relabel(const node_type& node){
02708   
02709     node_type neighbor[12];
02710     size_type n_neighbor;
02711 #ifndef WITHOUT_LIMITS
02712     label_type min = std::numeric_limits<label_type>::max();
02713 #else
02714     label_type min = static_cast<size_type>(4294967295);
02715 #endif
02716 
02717     static unsigned int NB_RELABEL = 0;
02718     static unsigned int NB_GLOBAL = 0;
02719   
02720     if (NB_RELABEL >= nb_nodes/2 /*10*/){
02721       global_relabel();
02722       NB_GLOBAL++;
02723       NB_RELABEL = 0;
02724       return 0;
02725     }
02726 
02727 
02728     NB_RELABEL++;
02729 
02730     // neighbors of the source have the source label.
02731     if ((node.pos.z() == min_bound(node.pos.x(),node.pos.y())) &&
02732         (node.loc == CENTER_NODE)){
02733     
02734       label_CENTER[node.pos] = nb_nodes;
02735 
02736       return nb_nodes;
02737     }
02738   
02739     adjacent_nodes(node,neighbor,&n_neighbor);
02740 
02741     for(size_type n=0;n<n_neighbor;n++){
02742       const label_type l = label(neighbor[n]);
02743 
02744       if (l<min){
02745         min = l;
02746       }
02747     }// end of for i
02748 
02749 #ifndef WITHOUT_LIMITS
02750     if (min == std::numeric_limits<label_type>::max()){
02751 #else
02752     if (min == static_cast<size_type>(4294967295)){
02753 #endif
02754       Message::error<<"#neighbor = "<<n_neighbor<<std::endl;
02755       Message::error<<"labels :"<<std::endl;
02756       for(size_type n=0;n<n_neighbor;n++){
02757         const label_type l = label(neighbor[n]);
02758 
02759         Message::error<<l<<std::endl;
02760       }// end of for i
02761 
02762       Message::error<<"relabel : no neighbor reachable !"<<Message::done;
02763     }
02764   
02765     min++;
02766 
02767     label(node) = min;
02768   
02769     return min;
02770   }
02771 
02772 
02773   namespace{
02774     template<typename Real>
02775     struct Index_cmp{
02776       typedef typename PushRelabel_non_linear_grid_3D<Real>::index_type
02777       index_type;
02778 
02779       typedef typename PushRelabel_non_linear_grid_3D<Real>::node_type
02780       node_type;
02781     
02782       const PushRelabel_non_linear_grid_3D<Real>& graph;
02783      
02784       Index_cmp(const PushRelabel_non_linear_grid_3D<Real>& g):graph(g){}
02785 
02786       inline bool operator()(const index_type i1,
02787                              const index_type i2){
02788         node_type n1,n2;
02789 
02790         graph.from_index(&n1,i1);
02791         graph.from_index(&n2,i2);
02792 
02793         return (graph.label(n1)>graph.label(n2));
02794       }
02795     };
02796   }
02797 
02798 
02799   template<typename Real>
02800   void
02801   PushRelabel_non_linear_grid_3D<Real>::
02802   global_relabel(){
02803 
02804     using namespace std;
02805 
02806     cout<<"GLOBAL RELABEL ";
02807 
02808     deque<node_type>* to_explore = new deque<node_type>;
02809     deque<node_type>* exploring  = new deque<node_type>;
02810     typedef typename deque<node_type>::iterator iterator;
02811 
02812     for(size_type x=0;x<x_size;x++){
02813       for(size_type y=0;y<y_size;y++){
02814         for(size_type z=0;z<z_size+1;z++){
02815       
02816           label_CENTER(x,y,z) = 0;
02817           label_Z_MAX_x_min(x,y,z) = 0;
02818           label_Z_MAX_x_max(x,y,z) = 0;
02819           label_Z_MAX_y_min(x,y,z) = 0;
02820           label_Z_MAX_y_max(x,y,z) = 0;
02821         }
02822       }
02823     }
02824 
02825     for(size_type x=0;x<x_size;x++){
02826       for(size_type y=0;y<y_size;y++){
02827         const size_type z = max_bound(x,y);
02828         node_type node(position_type(x,y,z),CENTER_NODE);
02829       
02830         if ((domain(x,y,z-1)) && (label_CENTER(x,y,z) < nb_nodes)){
02831         
02832           exploring->push_back(node);
02833           label_CENTER(x,y,z) = 1;
02834         }
02835       }
02836     }
02837 
02838     while(!exploring->empty()){
02839       for(iterator node=exploring->begin();node!=exploring->end();node++){
02840       
02841         node_type neighbor[12];
02842         size_type n_neighbor;
02843 
02844         neighbors(*node,neighbor,&n_neighbor);
02845 
02846         const label_type l = label(*node);
02847       
02848         for(size_type n=0;n<n_neighbor;n++){
02849           const node_type n_node   = neighbor[n];
02850           const direction_type dir = direction(n_node,*node);
02851 
02852           if (edge_residual(n_node,dir)>epsilon){
02853         
02854             const label_type ln = label(n_node);
02855           
02856             if (((ln > l+1)||(ln == 0))&&(ln < nb_nodes)){
02857 
02858               label(n_node) = l+1;
02859             
02860               to_explore->push_back(n_node);
02861 
02862             }
02863           }
02864         
02865         }// end of for n
02866       }// end of for node
02867 
02868       delete exploring;
02869       exploring = to_explore;
02870       to_explore = new deque<node_type>;
02871     }// end of while
02872   
02873     delete exploring;
02874     delete to_explore;
02875 
02876     label_type max_l = 0;
02877     label_type max_L = 0;
02878     active_node_index.clear();
02879 
02880     for(size_type x=0;x<x_size;x++){
02881       for(size_type y=0;y<y_size;y++){
02882         for(size_type z=0;z<z_size+1;z++){
02883       
02884           if (label_CENTER(x,y,z) == 0) {
02885             label_CENTER(x,y,z) = nb_nodes;
02886           }
02887 
02888           if (label_Z_MAX_x_min(x,y,z) == 0) {
02889             label_Z_MAX_x_min(x,y,z) = nb_nodes;
02890           }
02891 
02892           if (label_Z_MAX_x_max(x,y,z) == 0) {
02893             label_Z_MAX_x_max(x,y,z) = nb_nodes;
02894           }
02895 
02896           if (label_Z_MAX_y_min(x,y,z) == 0) {
02897             label_Z_MAX_y_min(x,y,z) = nb_nodes;
02898           }
02899 
02900           if (label_Z_MAX_y_max(x,y,z) == 0) {
02901             label_Z_MAX_y_max(x,y,z) = nb_nodes;
02902           }
02903 
02905           label_type l = label_CENTER(x,y,z);
02906           node_type n = node_type(position_type(x,y,z),CENTER_NODE);
02907           if ((l>max_L)&&(l<nb_nodes)){
02908             max_L = l;
02909           }
02910           if ((l<nb_nodes)&&(node_excess(n)>epsilon)){
02911             if (l>max_l){
02912               max_l = l;
02913             }
02914           
02915             index_type i;
02916             to_index(n,&i);
02917             active_node_index.push_back(i);
02918           }
02919 
02920           l = label_Z_MAX_x_min(x,y,z);
02921           n = node_type(position_type(x,y,z),Z_MAX_x_min_NODE);
02922           if ((l>max_L)&&(l<nb_nodes)){
02923             max_L = l;
02924           }
02925           if ((l<nb_nodes)&&(node_excess(n)>epsilon)){
02926             if (l>max_l){
02927               max_l = l;
02928             }
02929 
02930             index_type i;
02931             to_index(n,&i);
02932             active_node_index.push_back(i);
02933           }
02934 
02935           l = label_Z_MAX_x_max(x,y,z);
02936           n = node_type(position_type(x,y,z),Z_MAX_x_max_NODE);
02937           if ((l>max_L)&&(l<nb_nodes)){
02938             max_L = l;
02939           }
02940           if ((l<nb_nodes)&&(node_excess(n)>epsilon)){
02941             if (l>max_l){
02942               max_l = l;
02943             }
02944 
02945             index_type i;
02946             to_index(n,&i);
02947             active_node_index.push_back(i);
02948           }
02949 
02950           l = label_Z_MAX_y_min(x,y,z);
02951           n = node_type(position_type(x,y,z),Z_MAX_y_min_NODE);
02952           if ((l>max_L)&&(l<nb_nodes)){
02953             max_L = l;
02954           }
02955           if ((l<nb_nodes)&&(node_excess(n)>epsilon)){
02956             if (l>max_l){
02957               max_l = l;
02958             }
02959 
02960             index_type i;
02961             to_index(n,&i);
02962             active_node_index.push_back(i);
02963           }
02964 
02965           l = label_Z_MAX_y_max(x,y,z);
02966           n = node_type(position_type(x,y,z),Z_MAX_y_max_NODE);
02967           if ((l>max_L)&&(l<nb_nodes)){
02968             max_L = l;
02969           }
02970           if ((l<nb_nodes)&&(node_excess(n)>epsilon)){
02971             if (l>max_l){
02972               max_l = l;
02973             }
02974 
02975             index_type i;
02976             to_index(n,&i);
02977             active_node_index.push_back(i);
02978           }
02980         }
02981       }
02982     }
02983 
02984     Index_cmp<real_type> cmp(*this);
02985   
02986     std::sort(active_node_index.begin(),active_node_index.end(),cmp);
02987 //    active_node_index.sort(cmp);
02988 
02989     cout<<"label max : "<<max_l<<" "<<max_L<<endl;
02990   
02991   }
02992 
02993 
02997   template<typename Real>
02998   bool
02999   PushRelabel_non_linear_grid_3D<Real>::
03000   discharge(const node_type& node){
03001 
03002     using namespace std;
03003     
03004     node_type neighbor[12];
03005     size_type n_neighbor;
03006     
03007     adjacent_nodes(node,neighbor,&n_neighbor);
03008 
03009     real_type excess = node_excess(node);
03010     size_type n = 0;
03011 
03012     if (excess <= epsilon) {
03013       return false;
03014     }
03015 
03016   
03017     while ((n<n_neighbor)&&(excess>epsilon)){
03018 
03019       const node_type n_node = neighbor[n];
03020 
03021       if (is_admissible(node,n_node)){
03022       
03023         const direction_type d = direction(node,n_node);
03024         const real_type to_push = std::min(excess,edge_residual(node,d));
03025         
03026         add_flow(node,d,to_push);
03027 
03028         excess -= to_push;
03029       
03030         add_active_node(n_node);
03031       }
03032       n++;    
03033     }
03034 
03035     if ((n==n_neighbor)&&(excess>epsilon)){
03036       relabel(node);
03037       add_active_node(node);
03038     }
03039 
03040     return true;
03041   }
03042 
03043 
03044 
03045   template<typename Real>
03046   void
03047   PushRelabel_non_linear_grid_3D<Real>::
03048   add_active_node(const node_type& node){
03049 
03050     index_type i;
03051 
03052     to_index(node,&i);
03053 
03054     active_node_index.push_back(i);
03055   }
03056 
03057 
03058 
03059   template<typename Real>
03060   void
03061   PushRelabel_non_linear_grid_3D<Real>::
03062   get_next_node(node_type* const node,
03063                 bool* const      no_more_node){
03064 
03065     label_type l;
03066   
03067     do{
03068       *no_more_node = active_node_index.empty();
03069 
03070       if(!(*no_more_node)){
03071     
03072         const index_type i = active_node_index.front();
03073         active_node_index.pop_front();
03074       
03075         from_index(node,i);
03076         
03077         l = label(*node);
03078       }
03079     
03080     } while(((l >= nb_nodes)||
03081              (node->pos.z() == max_bound(node->pos.x(),node->pos.y()))) &&
03082             (!(*no_more_node)));
03083   }
03084 
03085 
03086 
03087   template<typename Real>
03088   bool
03089   PushRelabel_non_linear_grid_3D<Real>::
03090   is_active(const node_type& node) const{
03091 
03092     return (node_excess(node) > epsilon);
03093   }
03094 
03095 
03096 
03097   template<typename Real>
03098   bool
03099   PushRelabel_non_linear_grid_3D<Real>::
03100   is_admissible(const node_type& from,
03101                 const node_type& to) const{
03102 
03103     return (label(from) == (label(to)+1));
03104   }
03105 
03106 
03107   template<typename Real>
03108   typename PushRelabel_non_linear_grid_3D<Real>::real_type
03109   PushRelabel_non_linear_grid_3D<Real>::
03110   max_flow(){
03111 
03112     using namespace std;
03113 
03114     global_relabel();
03115 
03116     node_type to_discharge;
03117     bool no_more_to_discharge;
03118 
03119     get_next_node(&to_discharge,&no_more_to_discharge);
03120 
03121     while(!no_more_to_discharge){
03122       discharge(to_discharge);
03123       get_next_node(&to_discharge,&no_more_to_discharge);
03124     }
03125   
03126     // Computes the flow.
03127     real_type flow = 0;
03128     for(size_type x=0;x<x_size;x++){
03129       for(size_type y=0;y<y_size;y++){
03130     
03131         const size_type z = max_bound(x,y) - 1;
03132       
03133         if (domain(x,y,z)){
03134           flow += cost_edge_Z_MAX_x_min_flow(x,y,z)
03135             + cost_edge_Z_MAX_x_max_flow(x,y,z)
03136             + cost_edge_Z_MAX_y_min_flow(x,y,z)
03137             + cost_edge_Z_MAX_y_max_flow(x,y,z);
03138         }
03139       }
03140     }
03141   
03142     return flow;
03143   }
03144 
03145 
03146 
03147   template<typename Real>
03148   void
03149   PushRelabel_non_linear_grid_3D<Real>::
03150   min_cut(Array_2D<size_type>* const cut) const{
03151   
03152     using namespace std;
03153   
03154     Array_3D<bool> visited_CENTER(x_size,y_size,z_size+1,false);
03155     Array_3D<bool> visited_Z_MAX_x_min(x_size,y_size,z_size+1,false);
03156     Array_3D<bool> visited_Z_MAX_x_max(x_size,y_size,z_size+1,false);
03157     Array_3D<bool> visited_Z_MAX_y_min(x_size,y_size,z_size+1,false);
03158     Array_3D<bool> visited_Z_MAX_y_max(x_size,y_size,z_size+1,false);
03159   
03160     list<node_type> to_visit;
03161 
03162     // Initialization.
03163     for(size_type x=0;x<x_size;x++){
03164       for(size_type y=0;y<y_size;y++){
03165         node_type p(position_type(x,y,max_bound(x,y)),CENTER_NODE);    
03166         if (domain(p.pos.x(),p.pos.y(),p.pos.z()-1)&&
03167             (label_CENTER[p.pos] < nb_nodes)){
03168           to_visit.push_back(p);
03169           visited_CENTER[p.pos] = true;
03170         }
03171       }
03172     }
03173   
03174     // Visits the graph to mark the nodes which are on the source side.
03175     node_type neighbor[12];
03176     size_type n_neighbor;
03177   
03178     while(!to_visit.empty()){
03179       node_type node = to_visit.front();
03180       to_visit.pop_front();
03181 
03182       neighbors(node,neighbor,&n_neighbor);
03183     
03184       for(size_type n=0;n<n_neighbor;n++){
03185 
03186         const node_type n_node   = neighbor[n];
03187         const direction_type dir = direction(n_node,node);
03188       
03189         if ((edge_residual(n_node,dir)>epsilon)/*&&(label(n_node)<nb_nodes)*/){
03190         
03191           switch(n_node.loc){
03192           case CENTER_NODE:
03193           
03194             if(!visited_CENTER[neighbor[n].pos]){
03195               visited_CENTER[neighbor[n].pos] = true;
03196               to_visit.push_back(neighbor[n]);
03197             }
03198             break;
03199           
03200           case Z_MAX_x_min_NODE:
03201           
03202             if(!visited_Z_MAX_x_min[neighbor[n].pos]){
03203               visited_Z_MAX_x_min[neighbor[n].pos] = true;
03204               to_visit.push_back(neighbor[n]);
03205             }
03206             break;
03207           
03208           case Z_MAX_x_max_NODE:
03209           
03210             if(!visited_Z_MAX_x_max[neighbor[n].pos]){
03211               visited_Z_MAX_x_max[neighbor[n].pos] = true;
03212               to_visit.push_back(neighbor[n]);
03213             }
03214             break;
03215           
03216           case Z_MAX_y_min_NODE:
03217           
03218             if(!visited_Z_MAX_y_min[neighbor[n].pos]){
03219               visited_Z_MAX_y_min[neighbor[n].pos] = true;
03220               to_visit.push_back(neighbor[n]);
03221             }
03222             break;
03223           
03224           case Z_MAX_y_max_NODE:
03225           
03226             if(!visited_Z_MAX_y_max[neighbor[n].pos]){
03227               visited_Z_MAX_y_max[neighbor[n].pos] = true;
03228               to_visit.push_back(neighbor[n]);
03229             }
03230             break;
03231           }
03232         }
03233       }
03234     }
03235 
03236     // Looks for the cut
03237     cut->assign(x_size,y_size,0);
03238   
03239     for(size_type x=0;x<x_size;x++){
03240       for(size_type y=0;y<y_size;y++){
03241 
03242         bool found = false;
03243         
03244         for(size_type z=min_bound(x,y)+1;(z<z_size);z++){
03245           if ((visited_CENTER(x,y,z))&&(!found)){
03246             found = true;
03247             (*cut)(x,y) = z-1;
03248           }
03249         }
03250       }
03251     }
03252   
03253   }
03254 
03255 
03256 } // end of namepsace
03257 
03258 #endif
03259 
03260 

Generated on Tue Mar 2 18:12:45 2004 for Graph-cut code by doxygen1.2.18