Tri topologique de graphes - trouver et autocorriger les cycles
Bonjour,
Dans une application, j'ai une partie de la configuration qui permet de configurer une liste de composants. Un composant est décrit en résumé comme ceci :
- un identifiant obligatoire
- un identifiant faculatif de composant avant lequel ce composant doit s'exécuter
- un identifiant facultatif de composant après lequel ce composant doit s'exécuter
- accessoirement, un identifiant de composant que ce composant remplace, mais j'élimine ce cas par substitution
Pour exécuter les composants dans le bon ordre, je désire trier ma liste de composants. On peut considérer qu'il n'y a pas de problèmes du type identifiant qui ne correspond à aucun composant, de composant qui se référence lui-même, certains types de cycles faciles à détecter, etc (j'élimine ou autocorrige ces cas dans une première passe).
Au départ, j'étais parti sur des méthodes empiriques, mais vu que j'avais toujours des cas complexes à traiter, dont la résolution multipliait les passes et transformait un algorithme simple au début en usine à gaz, j'ai fini par rechercher un algorithme standard qui pouvait s'appliquer à mon problème et j'ai trouvé le tri topologique de graphe qui me semble bien adapté. Ce n'est peut-être pas le meilleur système adapté à mon problème, mais j'ai pu au moins le faire fonctionner (et comme mes graphes sont très petits, je ne me pose pas vraiment de problème de complexité et de performances). A noter, que j'ai des composants isolés, mais je les retire au départ, et les remets dans le résultat après le tri, donc aucun problème de ce côté.
Seulement, comme d'ailleurs pour les méthodes empiriques que j'avais essayées au préalable, j'ai le problème des cycles. Dans les méthodes empiriques, j'arrivais assez facilement à les autocorriger pendant le tri (en tout cas la plupart), en choisissant de privilégier le lien "avant", par rapport le lien "après", simplement en invalidant un lien, "cassant" ainsi le cycle.
Dans l'algorithme que j'ai implémenté, je peux détecter s'il existe ou pas des cycles, mais je ne trouve pas de moyen de les isoler, afin de casser l'un de leur lien. En cherchant un peu j'ai trouvé sur un forum la mention d'un algorithme à base de matrice, pas super clairement expliqué (il est surtout question de complexité d'algorithmes et de performances, et c'est probablement normal qu'ils ne s'étendent pas sur l'implémentation détaillée). Je ne sais si je m'oriente vers la bonne solution ou pas du tout. J'ai trouvé également quelque chose appelé "Feedback arc set", puis de "Minimal Spanning Forest" (ou Arbre couvrant de poids minimal, en français, si j'ai bien suivi), et d'algorithmes appelés Borůvka, Prim ou Kruskal. Le Kruskal étant le plus compréhensif pour moi, bien que tout n'y est pas explicite (en tout cas sur wikipedia), je tenterais bien celui-là : suis-je sur la bonne voie ? Ce qui me gène dans cet algorithme, c'est que, si j'ai bien compris, je vais obtenir en résultat un seul graphe non cyclique, alors que je cherche simplement à obtenir un maximum de graphes, en coupant un minimum de lien (mon but étant de ne pas perdre de composant). Mais je suppose, qu'en plusieurs passes, et par différence entre résultat et graphe de départ, je devrais obtenir la liste des noeuds vers lesquels (ou depuis lesquels) j'aurais un lien à couper.
Merci d'avance pour vos conseils et éclaircissements.