Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1804 connectés 

  FORUM HardWare.fr
  Programmation
  Algo

  Méthode efficace pour détecter la circularité ?

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Méthode efficace pour détecter la circularité ?

n°719930
Requin
Posté le 09-05-2004 à 18:09:13  profilanswer
 

Exposé de la situation :
Une base de données pour représenter un arbre, 0 comme PARENT indique la racine, un autre nombre indique que l'élément possède un autre élément parent :

Code :
  1. ID | PARENT | DATA
  2. 1  |      0 | texte1
  3. 2  |      1 | texte2
  4. 3  |      2 | texte3


 
Ce qui donne l'arbre suivant :

Code :
  1. texte 1
  2. |-texte2
  3.   |-texte3


 
Le problème :
Supposons que je modifie le PARENT de 1 de la manière suivante :

Code :
  1. ID | PARENT | DATA
  2. 1  |      3 | texte1
  3. 2  |      1 | texte2
  4. 3  |      2 | texte3


 
Voila qui me fait perdre ma racine et par conséquent l'ensemble de ma structure logique en créant une boucle.
 
La question :
Quelle méthode efficace existe-il pour détecter la circularité et empêcher que celà puisse se produire lors d'un UPDATE ? Existe-il une meilleure solution de représenter un arbre ?
 
 
Note : c'est pour un code en PHP, mais en fin de compte peu importe le langage.


Message édité par Requin le 09-05-2004 à 19:21:31
mood
Publicité
Posté le 09-05-2004 à 18:09:13  profilanswer
 

n°719946
Beegee
Posté le 09-05-2004 à 19:03:05  profilanswer
 

faut faire un trigger déclenché lors des update (et des insert aussi probablement), qui contiendra le code PL/SQL permettant de lister la liste des ID fils, et si le parent est dedans, de renvoyer une erreur ...
 
pas évident à première vue :D

n°719952
black_lord
Truth speaks from peacefulness
Posté le 09-05-2004 à 19:30:21  profilanswer
 

Et plus amont ne pas laisser les utilisateurs tenter d'insérer un père dans la liste des fils (pas trop clair mais on se comprend ^^)

n°719953
Requin
Posté le 09-05-2004 à 19:30:53  profilanswer
 

J'ai eu une idée... en fait je vais probablement créer une fonction récursive en PHP.
 
La fonction parcourt l'arbre depuis le futur parent d'un élément, en remontant de parent en parent jusqu'à la racine (PARENT = 0, est la condition d'arrêt), si je retombe sur mon élément de départ c'est qu'il y a  circularité et donc erreur.
 
J'ignore si il existe une méthode plus efficace qui nécessiterait moins de traitement... toutefois vue mon application la charge induite par ce traitement me semble acceptable.

n°719965
nraynaud
lol
Posté le 09-05-2004 à 19:45:21  profilanswer
 

de manière générale, il existe 2 grandes techniques pour détecter les cycles dans un graphe.
 
1) avec un set, on parcourt le graphe et on met les noeud dans un set au fur et à mesure de l'avancement, si le noeud est déjà dans le set, il y a un cycle. (concome de la mémoire)
 
2) le lièvre et la tortue : on fait partir un lièvre qui passe les noeuds 2 par 2, et une tortue qui parcourt les noeuds 1 par 1, s'ils se retrouvent sur le même noeud, c'est que le lièvre a fait le tour et a rattrapé la tortue, s'il tappe le bout, c'est qu'il y avait un bout. évidement, cet algo nécessite plus d'un tour de cycle de parcourt, mais ne consome pas de mémoire.


---------------
trainoo.com, c'est fini
n°720069
black_lord
Truth speaks from peacefulness
Posté le 09-05-2004 à 22:48:10  profilanswer
 

nraynaud a écrit :

de manière générale, il existe 2 grandes techniques pour détecter les cycles dans un graphe.
 
1) avec un set, on parcourt le graphe et on met les noeud dans un set au fur et à mesure de l'avancement, si le noeud est déjà dans le set, il y a un cycle. (concome de la mémoire)
 
2) le lièvre et la tortue : on fait partir un lièvre qui passe les noeuds 2 par 2, et une tortue qui parcourt les noeuds 1 par 1, s'ils se retrouvent sur le même noeud, c'est que le lièvre a fait le tour et a rattrapé la tortue, s'il tappe le bout, c'est qu'il y avait un bout. évidement, cet algo nécessite plus d'un tour de cycle de parcourt, mais ne consome pas de mémoire.


 
excellent le second je connaissais pas :) complexité ?

n°720074
nraynaud
lol
Posté le 09-05-2004 à 22:55:52  profilanswer
 

black_lord a écrit :

excellent le second je connaissais pas :) complexité ?

sur un hypodrôme, la tortue se fait rattraper à la fin de son premier tour, soit 2 tours pour le lièvre.


---------------
trainoo.com, c'est fini
n°720117
Jubijub
Parce que je le VD bien
Posté le 09-05-2004 à 23:52:02  profilanswer
 

le premier je connaissais, pas le second...


---------------
Jubi Photos : Flickr - 500px
n°720119
gizmo
Posté le 09-05-2004 à 23:58:08  profilanswer
 

Question con: si c'est une DB, pourquoi ne pas mettre le parent à NULL quand c'est la racine? Ton update serait nettement simplifié...

n°720126
nraynaud
lol
Posté le 10-05-2004 à 00:11:53  profilanswer
 

Jubijub a écrit :

le premier je connaissais, pas le second...

ça a été un devoir de smalltalk quand j'étais en début de deuxième année d'IUP (implémenter les 2 algos, ce qui se fait en 5 min).
 
Depuis, je me prends régulièrement des cuites avec le prof de l'époque ...


---------------
trainoo.com, c'est fini
mood
Publicité
Posté le 10-05-2004 à 00:11:53  profilanswer
 

n°720189
Requin
Posté le 10-05-2004 à 07:50:15  profilanswer
 

gizmo -> Car je n'aime pas le néant... je préfère définir mon intervalle de travail dans les nombres entiers positifs et interdire NULL ;)
 
Sinon voici la fonction dans sa première mouture :  

Code :
  1. function cat_checkparent($id, $parent) {
  2.      
  3.       global $db;
  4.      
  5.       if ( intval($id) == intval($parent) )
  6.       {
  7.          return false;
  8.       }
  9.       elseif ( intval($parent) == 0 )
  10.       {
  11.          return true;
  12.       }
  13.       else
  14.       {
  15.          $sql = "SELECT id,parent FROM categories WHERE id=".intval($parent);
  16.          $result = $db->sql_query($sql);
  17.          $row    = $db->sql_fetchrow($result);
  18.          // recursive call
  19.          return cat_checkparent($id, $row['parent']);
  20.       }
  21.    }


Message édité par Requin le 10-05-2004 à 07:59:26
n°720256
gizmo
Posté le 10-05-2004 à 09:46:18  profilanswer
 

Ouais, enfin, de toute façon, j'atais un peu fatigué, avec 0 ca merche aussi.
 
Il suffit de faire un update table set col=value where id=blabla and col!=0. Ainsi tu évites de modifier la racine.

n°720258
Beegee
Posté le 10-05-2004 à 09:48:15  profilanswer
 

oui mais il faut pouvoir modifier la racine ... mais sans créer de cycle ;)


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  Algo

  Méthode efficace pour détecter la circularité ?

 

Sujets relatifs
Que pensez vous de cette methode ? (lister les pdf, ps d un dossier)[PHP]Détecter les modules installés
Comment detecter un depassement de capacite dans une addition[HTML/JS] Lien sur img - send via methode POST
de l'utilité d'une methode release dans un tag jsp.[JAVA] méthode toString
méthode optimisée d'écriture dans un fichier logComment détecter une valeure vide ?
Une Methode de Detection optimale et implementable sous OpenGL?comment acceder a une methode d un objet lui meme dans un ArrayList
Plus de sujets relatifs à : Méthode efficace pour détecter la circularité ?


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR