Algorithme Combinatoire

publicité
Algorithme Combinatoire Décomposition d’un graphe (partie 2) Les ponts de Königsberg, résolu par Euler Liens Wikipédia : Le problème consiste à déterminer s'il existe ou non une promenade dans les
rues de Königsberg permettant, à partir d'un point de départ au choix, de
passer une et une seule fois par chaque pont, et de revenir à son point de
départ, étant entendu qu'on ne peut traverser le Pregel qu'en passant sur les
ponts. La condition nécessaire pour satisfaire cet algorithme est d’avoir un nombre pair de degré entrant et un nombre pair de degré sortant pour chaque sommet, afin de pouvoir partir d’un sommet, passer par tous les ponts une fois exactement et revenir au sommet initial On veut passer par chaque arrête une seule fois Pour chaque sommet on regarde le degré : tps polynomial è Caractérisation des graph eulérien Schéma eulérien : aller à tous les sommets en passant une fois exactement par arête : si on a un nombre d’arête impair on doit le rendre pair Exemple d’exercice Eulérien On a un degré pair pour chaque sommet, une solution existe donc Chemin en partant de B : BACB Ici on est bloqué, on supprime donc et on le met dans la liste des isolés : B Si on continu donc : BACBDEFDAFC Comme C est donc bloqué, on l’ajoute a la liste des isolés : BC Et on continue jusqu’à être définitivement bloqué : Isolées :BCFADFEDCAB Grâce à ça, on obtient la liste désiré en inversant celle des isolées : BACDEFDAFCB On peut donc mettre un sens pour les flèches (en rouge sur le schéma) Calcul du temps : on supprime une arête a chaque sommet : A : BCDF B : AC C : ABDF D : ACFE E : DF F : ACDE La suppression de chaque arête prends un temps constant, c’est donc un algorithme super master Exo 1 : Trouver l’algorithme pour un graph Eulérien (le schéma 3) 𝑅 = [ ] → 𝑙𝑖𝑠𝑡𝑒 𝑑𝑒𝑠 𝑖𝑠𝑜𝑙é𝑠 𝑄. 𝑎𝑝𝑝𝑒𝑛𝑑(𝑢) 𝑤ℎ𝑖𝑙𝑒 𝑄 ∶ 𝑧 = 𝑄. 𝑡𝑜𝑝() 𝑖𝑓 𝑎𝑑𝑗 𝑧 == [ ] 𝑅 . 𝑖𝑛𝑠𝑒𝑟𝑡(0, 𝑧) 𝑄 . 𝑝𝑜𝑝() 𝑒𝑙𝑠𝑒 𝑥 = 𝑎𝑑𝑗 𝑧 . 𝑝𝑜𝑝() 𝑎𝑗𝑑 𝑥 . 𝑟𝑒𝑚𝑜𝑣𝑒(𝑧) 𝑄 . 𝑝𝑢𝑠ℎ 𝑥 Tri topologique Exemple : on suit un curseur informatique, chaque étudiant doit connaître java, scheme, algo, compile, python, lang, OFI, C On doit avoir des prérequis Voici le schéma : On cherche donc à obtenir : On cherche une arête qui va de gauche à droite Tri topologique : linéarisé les graphes, donc pas d’arête de droite à gauche : 𝑥! , … 𝑥! 𝑡𝑞 ∀ 𝑥! , 𝑥! ∈ 𝐸 → 𝑖 < 𝑗 Donc si le tri est cyclique, il ne peut être topologique Topologique implique acyclique On a donc que les degrés entrants è SABDCE è SBACDE Construire l’algorithme du tri topologique : On utilise un parcourt en profondeur 𝑄 = {𝑢 𝑓𝑜𝑟 𝑢 𝑖𝑛 𝑎𝑗𝑑 𝑖𝑓 𝐷 ! 𝑢 == 0} 𝐿 = [ ] 𝑎 = 1 𝑤ℎ𝑖𝑙𝑒 𝑄 ∶ 𝑧 = 𝑄. 𝑝𝑜𝑝() 𝐿 = 𝐿. 𝑎𝑝𝑝𝑒𝑛𝑑(𝑧) 𝑎 += 1 𝑓𝑜𝑟 𝑥 𝑖𝑛 𝑎𝑑𝑗 𝑧 : 𝐷 ! 𝑥 −= 1 if 𝐷 ! 𝑥 == 0 𝑄 . 𝑎𝑝𝑝𝑒𝑛𝑑(𝑥) 𝑎 = 𝐿 − 1 Avec les lignes en rouge ajouté, l’algorithme est super master : si on retrouve 𝑎 = 𝐿 − 1 sinon on a un cycle Existe-­‐t-­‐il un sommet qui n’a pas de degré entrant ? oui Si le graphe est acyclique, on supprime un sommet de degré entrant zéro, le graphe en résultant le sera-­‐t-­‐il ? oui, il prend les propriétés précédentes Supposons un graphe avec aucun sommet de degré zero, comment est-­‐il ? Il est donc cyclique Exemple :
A = BCDE B = AC C = ABDE D =AC E = AC -­‐> BACDE -­‐> on obtient une liste vide = recherche en profondeur DFS = recherche ne profondeur = depth first search 𝑢 = [0 𝑓𝑜𝑟 𝑣 𝑖𝑛 𝐺] 𝑄. 𝑝𝑢𝑠ℎ(𝑢) 𝑀 𝑢 = 1 𝑓𝑜𝑟 𝑥 𝑖𝑛 𝑎𝑑𝑗 𝑧 : 𝑖𝑓 𝑀 𝑥 == 0 𝐷𝐹𝑆! (𝐺, 𝑉) Algorithme du dernier schéma : recherche en profondeur 𝑀 𝑢 = 1 𝑄. 𝑎𝑝𝑝𝑒𝑛𝑑(𝑢) 𝑤ℎ𝑖𝑙𝑒 𝑄 ∶ 𝑧 = 𝑄. 𝑡𝑜𝑝() 𝑖𝑓 𝑎𝑑𝑗 𝑧 = [] 𝑄. 𝑝𝑜𝑝() 𝑓𝑜𝑟 𝑥 𝑖𝑛 𝑎𝑑𝑗[𝑧] 𝑎𝑑𝑗 𝑧 . 𝑟𝑒𝑚𝑜𝑣𝑒(𝑥) 𝑖𝑓 𝑀 𝑥 == 0 𝑀 𝑥 = 1 𝑄. 𝑝𝑢𝑠ℎ 𝑥 𝑏𝑟𝑒𝑎𝑘 Modifier l’algorithme pour qu’il test si le graph à un cycle ou pas 𝐿. 𝑎𝑝𝑝𝑒𝑛𝑑 (𝑢) 𝑀 𝑢 = 1 𝑓𝑜𝑟 𝑥 𝑖𝑛 𝐺[𝑧] 𝑖𝑓 𝑀 𝑥 == 0 𝐷𝐹𝑆(𝐺, 𝑉) 𝑒𝑙𝑠𝑒 𝑟𝑒𝑚𝑒𝑚𝑏𝑒𝑟(𝑥, 𝐿) 
Téléchargement