src/INTERPOLATION/MEDMEM_dTree.hxx

Go to the documentation of this file.
00001 // Copyright (C) 2005  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00002 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00003 // 
00004 // This library is free software; you can redistribute it and/or
00005 // modify it under the terms of the GNU Lesser General Public
00006 // License as published by the Free Software Foundation; either 
00007 // version 2.1 of the License.
00008 // 
00009 // This library is distributed in the hope that it will be useful 
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
00012 // Lesser General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU Lesser General Public  
00015 // License along with this library; if not, write to the Free Software 
00016 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00017 //
00018 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00019 //
00020 #ifndef MEDMEM_DTREE_HXX
00021 #define MEDMEM_DTREE_HXX
00022 
00023 #include "MEDMEM_dTreeSommet.hxx"
00024 
00025 #define DTREE_FANTOME -1
00026 #define DTREE_RACINE 0
00027 #define DTREE_TERMINAL 1
00028 #define DTREE_COURANT 2
00029 // etat_descendance
00030 #define DTREE_NON_CALCULE -1
00031 #define DTREE_AUCUNE 0
00032 #define DTREE_VALIDE 1
00033 // val min nbr noeud
00034 #define DTREE_NBR_MIN_NOEUDS 2
00035 #define DTREE_NBR_MAX_DESC 8
00036 // pour meilleu re lecture
00037 #define _TEMPLATE_ template <class NOEUD,class NUAGENOEUD,int DIMENSION,int NBR_NOEUDS_PAR_CASE> 
00038 #define _DTREE_ dTree<NOEUD,NUAGENOEUD,DIMENSION,NBR_NOEUDS_PAR_CASE>
00039 
00045 
00046 /*********************************************************/
00047 /*                                                       */
00048 /*             Calcul Statique de Puissance              */
00049 /*                                                       */
00050 /*********************************************************/
00051 
00052 // Permet de Calculer 2^n de façon statique
00053 
00054 template < int DIMENSION > struct DeuxPuissance
00055      {
00056      enum { valeur = 2 * DeuxPuissance<DIMENSION-1>::valeur } ;
00057      };
00058 
00059 template <> struct DeuxPuissance<0>
00060      {
00061      enum { valeur = 1  } ;
00062      };   
00063 
00064 /*********************************************************/
00065 /*                                                       */
00066 /*                         DTREE                         */
00067 /*                                                       */
00068 /*********************************************************/
00069 
00070 // Construit un d-Tree sur un nuage de noeud et pour un noeud donné donne lequel des noeuds du nuage est le plus proche
00071 
00072 // # Bugs connus : 
00073 //      -  Problemes avec points sur les faces des hypercubes ?
00074 //      -  Plantage sauvage si le point est plus loin de l'hypercube père que le diametre Linf de celui-ci.
00075 // # Politique de classe :
00076 //      - NOEUD : voir dans MEDMEM_WrapperNodes.hxx la classe Wrapper_Noeud<..>
00077 //      - NUAGENOEUD : typiquement, c'est vector<NOEUD> en rédefinissant NUAGENOEUD<...>::SIZE()=vector<...>::size()
00078 // Remarques :
00079 //      - NBR_NOEUDS_PAR_CASE ne doit pas être modifié sauf peut-être dans le cas où l'utilisateur veut utiliser des d-Tree parallèles 
00080 //     ou utilise des nuages de noeud trop grands
00081 
00082 template <class NOEUD,class NUAGENOEUD,int DIMENSION,int NBR_NOEUDS_PAR_CASE=DTREE_NBR_MIN_NOEUDS> class dTree
00083 {
00084 protected :
00085      // types
00086      typedef _DTREE_ * Ptr_dTree;
00087      // Static Const
00088      static const int nbr_descendants=DeuxPuissance<DIMENSION>::valeur;
00089      // champs
00090      NUAGENOEUD * nuage;
00091      Ptr_dTree descendant[nbr_descendants];
00092      // numéro des noeuds contenus
00093      vector<int> * noeud_contenu;
00094      int etat;
00095      int niveau;
00096      dTree * pere;
00097      // extrémités de l'hypercube du dTree
00098      Sommet_dTree<DIMENSION> coord_max;
00099      Sommet_dTree<DIMENSION> coord_min;
00100 public :
00101 
00102      void init();
00103      dTree();
00104      // Ce constructeur est le seul constructeur utilisateur, il construit le père puis tous les descendants
00105      dTree(NUAGENOEUD *n);
00106      // Ce Constructeur est utilisé par le précédent, pour un pere donné, avec deux extrémités données, 
00107      // il instantie un dTree sans en calculer les noeuds contenus
00108      dTree(const Sommet_dTree<DIMENSION> &A,const Sommet_dTree<DIMENSION> &B,dTree *mypere);
00109      dTree(const dTree &F);
00110      ~dTree();
00111      // Renvoie les numéros de noeuds contenus dans le dTree
00112      void Get_Noeuds_Filtre(vector<int> &tmp);
00113      // renvoie les extrémités
00114      Sommet_dTree<DIMENSION> Get_Max() const;
00115      Sommet_dTree<DIMENSION> Get_Min() const;
00116      // renvoie vrai si P est dans le dTree
00117      int is_in_dTree(NOEUD P) const;
00118      // calcule la distance topologique locale de P au dTree
00119      double calcule_distance(NOEUD P) const;
00120      dTree & operator = (const dTree & F);
00121      // retourne le sommet du dTree codé par l'entier selecteur (voir explications dans le code)
00122      Sommet_dTree<DIMENSION> donne_sommet(int selecteur) const;
00123      int a_des_fils() const;
00124      // renvoi une reference sur le dTree terminal descendant de this contenant P
00125      dTree * trouve_dTree_contenant(NOEUD P) const;
00126      // renvoie le point le plus proche de P dans this par la méthode exhaustive brutale
00127      int trouve_plus_proche_point_bourrin(NOEUD P) const;
00128      // renvoie le point le plus proche de p dans this par la méthode dtree
00129      int trouve_plus_proche_point(NOEUD P) const;
00130      // renvoie un numéro de point contenu dans this
00131      int trouve_un_point() const;
00132      // méthode récursive utilisée par trouve_plus_proche_point
00133      int tppp_rec(NOEUD P,double &delta,int &flag) const;
00134      // dit si P est d-proche de l'hypercube de this
00135      int Localise_Point(NOEUD P,double d) const;
00136      // utilisé par le constructeur pour créer tout la filiation du dTree
00137      void cree_filiation();
00138      // méthodes de mesure
00139      int Get_Nbr_Descendants_Non_Vides() const;
00140      int Get_Nbr_Descendants_Vides() const;
00141      int Get_Profondeur_Max() const;
00142 };
00143 
00144 
00150 
00151 _TEMPLATE_ void _DTREE_::init()
00152      {
00153      int i;
00154      nuage=NULL;
00155      noeud_contenu=NULL;
00156      etat=DTREE_FANTOME;
00157      for (i=0;i<nbr_descendants;i++) descendant[i]=NULL;
00158      niveau=-1;
00159      pere=NULL;
00160      }
00161 _TEMPLATE_ _DTREE_::dTree()
00162      {
00163      init();
00164      coord_max=0.0;
00165      coord_min=0.0;
00166      }
00167 _TEMPLATE_ _DTREE_::dTree(NUAGENOEUD *n)
00168      {
00169      int i,j;
00170      double tmp;
00171      
00172      if (n==NULL) 
00173           {
00174           cerr<<"DTREE : Nuage vide !"<<endl;
00175           exit(-1);
00176           }
00177      
00178      init();
00179      nuage=n;
00180      etat=DTREE_RACINE;
00181      noeud_contenu=new vector<int>(nuage->size());
00182      niveau=0;
00183      
00184      // calcule les extrémités du dTree pere
00185      for (i=0;i<DIMENSION;i++)
00186           {
00187           coord_max[i]=(*nuage)[0][i];
00188           coord_min[i]=(*nuage)[0][i];
00189           }
00190      (*noeud_contenu)[0]=0;
00191      for (i=1;i<nuage->size();i++)
00192           {
00193           (*noeud_contenu)[i]=i;
00194           for (j=0;j<DIMENSION;j++) 
00195                {
00196                if ((*nuage)[i][j]>coord_max[j]) coord_max[j]=(*nuage)[i][j];
00197                if ((*nuage)[i][j]<coord_min[j]) coord_min[j]=(*nuage)[i][j];
00198                }
00199           }
00200      for (j=0;j<DIMENSION;j++) 
00201           {
00202           tmp=(coord_max[j]-coord_min[j])*0.01;
00203           coord_max[j]+=tmp;
00204           coord_min[j]-=tmp;
00205           }
00206      
00207      // méthode récursive qui construit la filiation
00208      cree_filiation();
00209      
00210      }
00211 _TEMPLATE_ _DTREE_::dTree(const Sommet_dTree<DIMENSION> &A,const Sommet_dTree<DIMENSION> &B,dTree *mypere)
00212      {
00213      if (mypere!=NULL)
00214           {
00215           
00216           int i;
00217           
00218           init();
00219           
00220           pere=mypere;
00221           nuage=pere->nuage;
00222           niveau=pere->niveau+1;
00223           
00224           etat=DTREE_COURANT;
00225           
00226           noeud_contenu=new vector<int>;
00227           noeud_contenu->reserve((pere->noeud_contenu->size())/nbr_descendants);
00228           
00229           for (i=0;i<DIMENSION;i++)
00230                {
00231                coord_max[i]=(*nuage)[0][i];
00232                coord_min[i]=(*nuage)[0][i];
00233                }
00234           
00235           for (i=0;i<DIMENSION;i++)
00236                {
00237                if (A[i]>B[i]) 
00238                     {
00239                     coord_max[i]=A[i];
00240                     coord_min[i]=B[i];
00241                     }
00242                else
00243                     {
00244                     coord_min[i]=A[i];
00245                     coord_max[i]=B[i];
00246                     }
00247                }
00248           }
00249      else
00250           {
00251           cerr<<"DTREE : Construction de descendance sans père !"<<endl;
00252           exit(-1);
00253           }
00254      }    
00255 _TEMPLATE_ _DTREE_::dTree(const _DTREE_ &F)
00256      {
00257      // Pas Super Top Moumoute ... Recopie de pointeurs et pas de contenus, merdique
00258      int i,j;
00259      init();
00260      for (i=0;i<nbr_descendants;i++) descendant[i]=F.descendant[i];
00261      noeud_contenu=F.noeud_contenu;
00262      etat=F.etat;
00263      niveau=F.niveau;
00264      pere=F.pere;
00265      coord_max=F.coord_max;
00266      coord_min=F.coord_min;
00267      }
00268 _TEMPLATE_ _DTREE_::~dTree()
00269      {
00270      int i;
00271      nuage=NULL;
00272      pere=NULL;
00273      // cout<<*this<<endl;
00274      if (noeud_contenu) 
00275           {
00276           delete noeud_contenu;
00277           }
00278      for (i=0;i<nbr_descendants;i++) if (descendant[i]) 
00279           {
00280           delete descendant[i];
00281           }
00282      }
00283 _TEMPLATE_ void _DTREE_::Get_Noeuds_Filtre(vector<int> &tmp)
00284      {
00285      int i;
00286      switch (etat)
00287           {
00288           case DTREE_RACINE : int pourlefunlecompilolesttropcon;
00289           case DTREE_COURANT : 
00290                for (i=0;i<nbr_descendants;i++) descendant[i]->Get_Noeuds_Filtre(tmp);
00291           case DTREE_TERMINAL : 
00292                if (noeud_contenu->size()>0) 
00293                     {
00294                     for (i=0;i<NBR_NOEUDS_PAR_CASE;i++) tmp.push_back((*noeud_contenu)[i]);
00295                     }
00296           default : 
00297                cerr<<"DTREE : dTree Non Valide dans Rempli_Noeuds_Filtre"<<endl;
00298                exit(-1);
00299           }
00300      }
00301 _TEMPLATE_ Sommet_dTree<DIMENSION> _DTREE_::Get_Max() const
00302      {
00303      return coord_max;
00304      }
00305 _TEMPLATE_ Sommet_dTree<DIMENSION> _DTREE_::Get_Min() const
00306      {
00307      return coord_min;
00308      }
00309 _TEMPLATE_ int _DTREE_::is_in_dTree(NOEUD P) const
00310      {
00311      int test;
00312      for (int i=0;i<DIMENSION;i++)
00313           {
00314           test=((coord_min[i]<=P[i])&&(P[i]<=coord_max[i])); 
00315           if (!test) return 0;
00316           }
00317      return 1;
00318 
00319      }
00320 // calcule la distance Linf d'un point exterieur, si le point est interieur, le resultat sera erroné
00321 _TEMPLATE_ double _DTREE_::calcule_distance(NOEUD P) const
00322      {
00323      double min=fabs(coord_max[0]-P[0]);
00324      double tmp;
00325      int i;
00326      for (i=0;i<DIMENSION;i++)
00327           {
00328           tmp=fabs(coord_max[i]-P[i]);
00329           if (min>tmp) min=tmp;
00330           tmp=fabs(coord_min[i]-P[i]);
00331           if (min>tmp) min=tmp;
00332           }
00333      return min;    
00334      }
00335 _TEMPLATE_ _DTREE_ & _DTREE_::operator = (const _DTREE_ & F)
00336      {
00337      // Pas Super Top Moumoute ... Recopie de pointeurs et pas de contenus, merdique
00338      int i,j;
00339      init();
00340      for (i=0;i<_DTREE_::nbr_descendans;i++) descendant[i]=F.descendant[i];
00341      noeud_contenu=F.noeud_contenu;
00342      etat=F.etat;
00343      niveau=F.niveau;
00344      pere=F.pere;
00345      coord_max=F.coord_max;
00346      coord_min=F.coord_min;
00347      }
00348 // selecteur doit etre lu comme un nombre en base 2
00349 // il specifie les coordonnes de reference du sommet dont on veut les coordonnees reelles
00350 // ex : en dim 3 : coord_min=0+0*2+0*4=0
00351 //                 coord_max=1+1*2*1*4=7
00352 // donc les unites pour x, les 2aines pour y, les 4aines pour z
00353 _TEMPLATE_ Sommet_dTree<DIMENSION> _DTREE_::donne_sommet(int selecteur) const
00354      {
00355      Sommet_dTree<DIMENSION> p;
00356      int i;
00357      int residu=selecteur;
00358      int reste;
00359      for (i=0;i<DIMENSION;i++) 
00360           {
00361           reste=residu%2;
00362           if (reste==0) p[i]=coord_min[i]; else p[i]=coord_max[i];
00363           residu=(residu-reste)/2;
00364           }
00365      return p;
00366      }
00367 _TEMPLATE_ int _DTREE_::a_des_fils() const
00368      {
00369      if ((etat==DTREE_COURANT)||(etat=DTREE_RACINE)) return 1;
00370      else return 0;
00371      }
00372 _TEMPLATE_ _DTREE_ * _DTREE_::trouve_dTree_contenant(NOEUD P) const
00373      {
00374      Sommet_dTree<DIMENSION> B(coord_min,coord_max);
00375      int i;
00376      if ((etat==DTREE_RACINE)&&(!is_in_dTree(P))) return NULL; // Le noeud est extérieur a l'dTree
00377      else if (etat==DTREE_TERMINAL) return (dTree *) this;     // Le noeud est dans *this qui est terminal
00378      
00379      for (i=0;i<nbr_descendants;i++)
00380           {
00381           Sommet_dTree<DIMENSION> A=donne_sommet(i);
00382           int test,j;
00383           for (j=0;j<DIMENSION;j++)
00384                {
00385                if (A[j]<=B[j]) test=((A[j]<=P[j])&&(P[j]<=B[j])); 
00386                else test=((A[j]>=P[j])&&(P[j]>=B[j]));
00387                if (!test) break;
00388                }
00389 
00390           if (test)
00391             return descendant[i]->trouve_dTree_contenant(P); // Propagation
00392           }
00393      return NULL;
00394      }
00395 // si de le dTree n'est pas TERMINAL, scanne tous les points du nuage du pere pour trouver le point le plus proche
00396 // sinon scanne uniquement les points contenus dans le dTree
00397 _TEMPLATE_ int _DTREE_::trouve_plus_proche_point_bourrin(NOEUD P) const
00398      {
00399      int i;
00400      int num_sol=0;
00401      double min;
00402      double tmp;
00403      if (etat!=DTREE_TERMINAL)
00404           {
00405           min=DistanceL2(P,(*nuage)[0]);
00406           for (i=1;i<nuage->size();i++)
00407                {
00408                tmp=DistanceL2(P,(*nuage)[i]);
00409                if (tmp<min)
00410                     {
00411                     num_sol=i;
00412                     min=tmp;
00413                     }
00414                }
00415           return num_sol;
00416           }
00417      else
00418           {
00419           if (noeud_contenu->size()!=0)
00420                {
00421                num_sol=(*noeud_contenu)[0];
00422                min=DistanceL2(P,(*nuage)[num_sol]);
00423                for (i=1;i<noeud_contenu->size();i++)
00424                     {
00425                     tmp=DistanceL2(P,(*nuage)[(*noeud_contenu)[i]]);
00426                     if (tmp<min)
00427                          {
00428                          num_sol=(*noeud_contenu)[i];
00429                          min=tmp;
00430                          }
00431                     }
00432                return num_sol;
00433                }
00434           else return DTREE_FANTOME;
00435           }
00436      }
00437 // Fonction de pilotage de la recursion, lance les tests preliminaires et invoque la recursion
00438 _TEMPLATE_ int _DTREE_::trouve_plus_proche_point(NOEUD P) const
00439      {
00440 
00441      if (etat==DTREE_FANTOME) 
00442           {
00443           cerr<<"DTREE : TROUVE PLUS PROCHE POINT : L'octree n'est pas construit !"<<endl;
00444           exit(-1);
00445           }
00446      dTree *ref=trouve_dTree_contenant(P);   
00447      double delta;
00448 
00449      if (ref!=NULL)
00450           {
00451           // Le point est intérieur
00452 
00453           if (ref->pere!=NULL)     
00454                {
00455                delta=DistanceInf((ref->pere->coord_max),(ref->pere->coord_min));
00456                }    
00457           else 
00458                {
00459                cerr<<"DTREE : TROUVE PLUS PROCHE POINT : l'octree contenant le noeud n'a pas de pere !"<<endl;
00460                exit(-1);
00461                }
00462           }
00463      else 
00464           {
00465           // Le point est extérieur
00466 
00467           delta=DistanceL2(P,(*nuage)[0]);
00468           }
00469           
00470      int flag=0;
00471      int retour;
00472 
00473      retour=tppp_rec(P,delta,flag);
00474 
00475      return retour;
00476      }
00477 _TEMPLATE_ int _DTREE_::trouve_un_point() const
00478      {
00479      if (noeud_contenu!=NULL)
00480           {
00481           if (noeud_contenu->size()>0) return (*(noeud_contenu))[0];
00482           }
00483      else
00484           {
00485           int i;
00486           for (i=0;i<nbr_descendants;i++)
00487                {
00488                return descendant[i]->trouve_un_point();
00489                }
00490           }
00491      }
00492 // partie recursive de trouve_plus_proche_point
00493 // change le flag en 1 si un point plus proche est trouvé
00494 // adapte automatiquement la distance delta de filtrage
00495 _TEMPLATE_ int _DTREE_::tppp_rec(NOEUD P,double &delta,int &flag) const
00496      {
00497      if (Localise_Point(P,delta)==0) 
00498           {
00499      
00500      // La distance du point à l'octree est plus grande que delta
00501      
00502           return DTREE_FANTOME;
00503           }
00504      int num_Ptmp;
00505      double dtmp;
00506      if (etat==DTREE_TERMINAL)
00507           {
00508           if (noeud_contenu->size()>0)
00509                {
00510                num_Ptmp=trouve_plus_proche_point_bourrin(P);
00511                dtmp=DistanceL2((*nuage)[num_Ptmp],P);
00512                if (dtmp<=delta) 
00513                     {
00514      
00515      // Le point le plus proche minimise delta, c'est un bon candidat, on l'envoie !
00516      
00517                     delta=dtmp;
00518                     flag=1;
00519                     return num_Ptmp;
00520                     }
00521      
00522      // Le point le plus proche ne minimise pas delta
00523      
00524                // ===========> peut etre rajouter exit(-1); ??????????
00525                return DTREE_FANTOME;
00526                }
00527           else 
00528                {
00529      
00530      // L'octree qui contient P ne contient aucun point
00531      
00532                return DTREE_FANTOME;
00533                }
00534           }
00535      int i;
00536      int num_sol=DTREE_FANTOME;
00537      for (i=0;i<nbr_descendants;i++)
00538           {
00539           num_Ptmp=descendant[i]->tppp_rec(P,delta,flag);
00540           if ((num_Ptmp!=DTREE_FANTOME)&&(flag==1)) 
00541                {
00542      
00543      // On a trouvé un point qui minimise delta dans une branche
00544      
00545                num_sol=num_Ptmp;
00546                }
00547           }
00548      // A ce stade, on a trouvé un point qui minimise tous les deltas, c'est donc le point le plus proche
00549      // REMARQUE : cette affirmation est à la base de l'algorithme par dTree mais est loin d'étre évidente
00550      
00551      return num_sol;
00552      }
00553      
00554 // renvoie 1 si la distance L inf du noeud a l'octree est plus petite que d, 0 sinon
00555 _TEMPLATE_ int _DTREE_::Localise_Point(NOEUD P,double d) const
00556      {
00557      int i;
00558      for (i=0;i<DIMENSION;i++)
00559           {
00560           if (P[i]>coord_max[i]+d) return 0;
00561           if (P[i]<coord_min[i]-d) return 0;
00562           }
00563      return 1;
00564      }
00565      
00566 // Méthode de construction du dTree par propagation
00567 _TEMPLATE_ void _DTREE_::cree_filiation()
00568      {
00569      if (etat!=DTREE_RACINE) 
00570           {
00571           niveau=pere->niveau+1;
00572           }
00573      else 
00574           {
00575           niveau=0;
00576           }
00577      
00578      if (noeud_contenu->size()<=NBR_NOEUDS_PAR_CASE)
00579           {
00580           etat=DTREE_TERMINAL;
00581           }
00582      else
00583           {
00584           int i,num_loc,test;
00585           
00586           Sommet_dTree<DIMENSION> centre(coord_max,coord_min);
00587           
00588           for (i=0;i<nbr_descendants;i++)
00589                {
00590                descendant[i]=new dTree(centre,donne_sommet(i),this);
00591                }
00592           
00593           for (num_loc=0;num_loc<noeud_contenu->size();num_loc++)
00594                {
00595                int indice=(*noeud_contenu)[num_loc];
00596                NOEUD & courant=(*nuage)[indice];
00597                test=1;
00598                for (i=0;(test)&&(i<nbr_descendants);i++)
00599                     {
00600                     if (descendant[i]->is_in_dTree(courant))
00601                          {
00602                          descendant[i]->noeud_contenu->push_back(indice);
00603                          test=0;
00604                          }
00605                     }
00606                }
00607           
00608           delete noeud_contenu;
00609           noeud_contenu=NULL;
00610           
00611           for (i=0;i<nbr_descendants;i++) descendant[i]->cree_filiation();
00612           }
00613      }
00614 _TEMPLATE_ int _DTREE_::Get_Nbr_Descendants_Non_Vides() const
00615      {
00616      int i;
00617      int ndnv=0;
00618      switch (etat)
00619           {
00620           case DTREE_RACINE : int pourlefunlecompilolesttropcon;
00621           case DTREE_COURANT : 
00622                for (i=0;i<nbr_descendants;i++) ndnv+=descendant[i]->Get_Nbr_Descendants_Non_Vides();
00623                return ndnv;
00624           case DTREE_TERMINAL : 
00625                if (noeud_contenu->size()>0) return 1;
00626                else return 0;
00627           default : 
00628                cerr<<"dTree Non Valide dans Get_Nbr_Descendants_Non_Vides"<<endl;
00629                return -1;
00630           }
00631      }
00632 _TEMPLATE_ int _DTREE_::Get_Nbr_Descendants_Vides() const
00633      {
00634      int i;
00635      int ndnv=0;
00636      switch (etat)
00637           {
00638           case DTREE_RACINE : int pourlefunlecompilolesttropcon;
00639           case DTREE_COURANT : 
00640                for (i=0;i<nbr_descendants;i++) ndnv+=descendant[i]->Get_Nbr_Descendants_Vides();
00641                return ndnv;
00642           case DTREE_TERMINAL : 
00643                if (noeud_contenu->size()==0) return 1;
00644                else return 0;
00645           default : 
00646                cerr<<"dTree Non Valide dans Get_Nbr_Descendants_Non_Vides"<<endl;
00647                return -1;
00648           }
00649      }
00650 _TEMPLATE_ int _DTREE_::Get_Profondeur_Max() const
00651      {
00652      int i;
00653      int prof=0;
00654      int tmp;
00655      switch (etat)
00656           {
00657           case DTREE_RACINE : int pourlefunlecompilolesttropcon;
00658           case DTREE_COURANT : 
00659                for (i=0;i<nbr_descendants;i++) 
00660                     {
00661                     tmp=descendant[i]->Get_Profondeur_Max();
00662                     if (tmp>prof) prof=tmp;
00663                     }
00664                return prof;
00665           case DTREE_TERMINAL : return niveau;
00666           default : 
00667                cerr<<"dTree Non Valide dans Get_Nbr_Descendants_Non_Vides"<<endl;
00668                return -1;
00669           }
00670      }
00671 
00672 #undef _TEMPLATE_
00673 #undef _DTREE_
00674 
00675 
00676 #endif