Tri topologique

On considère dans cet exercice des graphes orientés acycliques, soit des graphes orientés sans circuit, représentés par listes de successeurs à l'aide de dictionnaires. Par exemple ;

Dictionnaire représentant un graphe
g = {
    'A': ['B'],
    'B': ['C'],
    'C': [],
    'D': ['B', 'C'],
    'E': ['A', 'B']
    }

graphe

Un ordre topologique sur un graphe est un ordre sur les sommets du graphe tel que, pour tout couple de sommets \(u\), \(v\) distincts, s'il existe un arc \(u \rightarrow v\), alors \(u\) précède \(v\) dans l'ordre. Dans ce cas, on note \(u \prec v\).

L'objectif de cet exercice est d'obtenir une liste des sommets ordonnés suivant un ordre topologique. Cette liste n'est pas nécessairement unique. Par exemple, pour le graphe g, les deux listes ['D', 'E', 'A', 'B', 'C'] et ['E', 'A', 'D', 'B', 'C'] conviennent.

La figure ci-dessous reprend le graphe proposé plus haut et illustre deux ordres topologiques.

graphe

L'ordre topologique peut être utilisé afin de trier des tâches dépendants les unes des autres. Par exemple, lorsqu'une personne s'habille, il lui est possible de mettre un pantalon avant des chaussettes ou le contraire. Par contre elle ne peut pas mettre sa chemise avant son pull. On modélise cette situation par un graphe dans lequel chaque sommet est une tâche et les arêtes illustrent les relations de dépendance.


On appelle degré entrant d'un sommet \(v\) le nombre d'arcs \(u \rightarrow v\), soit le nombre de prédécesseurs de \(v\).

On peut montrer que ;

  • tout graphe orienté acyclique possède au moins un sommet de degré entrant égal à \(0\), autrement dit il existe au moins un sommet sans prédécesseur ;

  • si un graphe orienté acyclique possède \(n\) sommets \(u_0, u_1, ..., u_{n-1}\), si le degré entrant de \(u_0\) est 0 et si \([u_1, ..., u_{n-1}]\) est triée, alors \([u_0, u_1, ..., u_{n-1}]\) est triée.

Cette dernière propriété est à la base de l'algorithme de Kahn dont le principe est le suivant ;

  • une liste vide est créée pour contenir les sommets triés ;

  • le degré entrant de chaque sommet est calculé et stocké à l'aide d'un dictionnaire ;

  • les sommets dont le degré entrant est égal à \(0\) sont placés dans une pile (ou une file, voir plus bas);

  • tant que la pile (file) n'est pas vide, un élément en est retiré, il est ajouté à la liste des sommets triés. Le degré entrant de tous ses successeurs est ensuite diminué d'une unité et les successeurs dont le nouveau degré entrant vaut \(0\) sont placés dans la pile (file);

  • la liste des sommets triés est renvoyée.

Afin de simplifier la mise en œuvre, on propose de stocker les sommets en attente de traitement dans une pile.

Compléter la fonction tri_topo qui prend en paramètre un dictionnaire graphe représentant un graphe orienté acyclique et renvoie une liste de sommets ordonnés selon un ordre topologique.

Exemple
>>> g = {'A': ['B'], 'B': [], 'C': ['B']}
>>> resultat = tri_topo(g)
>>> resultat
['A', 'C', 'B']

###(Dés-)Active le code après la ligne # Tests (insensible à la casse)
(Ctrl+I)
Entrer ou sortir du mode "deux colonnes"
(Alt+: ; Ctrl pour inverser les colonnes)
Entrer ou sortir du mode "plein écran"
(Esc)
Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)
Si activé, le texte copié dans le terminal est joint sur une seule ligne avant d'être copié dans le presse-papier
Évaluations restantes : 10/10

.1280135[4})2R,Ba!- ièà8m16ClK7.e:9A;S/dktf{+Irj3sogu0x]PpnEh=céyvD(wq_b050H0A0J0k0o0w0R0n0(0w0k0R0R0%010J0o0Z010406050R0U0s0s0k0O0*040F0S0w0U150S0!0n020k0s0Z0E0n0h0A1f0O0/0U0A0R050G1c1e1g1i1a0Z041G1N051Q0G1Q1S1N1a0H0o0+0}0 11130$0o0T0$0w1*0$0J18050^0;0w0A1#1012011)1+1-1+0J1?1^1;0J0;0S0H1i1=0O1O0J0$0}1l0R0Z0k0!130g011`1%010K0`0A0!1t0A1;2i2k2p1|2s1^2v0s2x040a0n0Y0O0S0Z0S0R0o1o1q0?2g0O0O0A0(2S1G2z0!1O0G2e2(0J2c2b2d0H2B131-0!2u2P1;1Y1!0~1{2=0o2@0!281Z1;0Z2X1O2$2(391b2j1q2}2q320O1f0w180n0t2#3d193c2A3f1|3h3j3l0g3o2k3q2$2;013v0k3k040n0Q3z2%1a3C3t133F3H0n0d3L3B3d3D3R3l0b3V3N3X3P3E0S3i3G3l0u3$3r3e1$3u3+3w3I0y3:3O3?3Q3^3-3I0r3|3(3~3*3,3S0C443s463Z040t0V4b3=2~473_0t3n1H3p3%4c4k4e0t3y4p3A4r4j3g403H0t3K4x3M3;3Y4C180t3U4G3W4s4B484L3#4O4z4J4S4f3/4V4I3)4u3{4#3}4t4K4f434*454,4Y0t4a4:4Q3@4Y0g4h4_4A4{3_0g4o394W4%4-0g4w554$4d584F3b1T371G2{2+0H2/3D0(282H0=1Z1O360A383p3V055p0?5x4`130I180?0K5z4+2q0.3l5K4;3g0K182,0o5P5E0117040-5W503Q180T0O0k0Z0$0A5$3D5Z0f0B3$0n5_0n5c4t183+0H2X3V5{5L1|0S180%625|2q5Z0c0X62635Q1|0(0t18030n1-0R0J1_2O0U0O0n6p0S0(0I0A6u1^0n2X1c0w0^0J3$065`6g5X6j6l0n0?5*0)0n2u2,2k0J6Q1_0(0$0k1C1_0R0S1e0@5^5`6a3u5H0A5*1E6964136604684O6M5%5Y180L5:4%180U75465Z5@6 6:130s0o184~39703D5G040K3+6_6h5(04787d6`010S5N04307r5X0!5)5+5-5/4O7e72040e6.5_7L7n7p0O7D717F7u7V3D7z187C7w7s3E7G5,5.794k7b7P6L7l3)7S7q7(7E180+7Z3)7#7B0!7~4d7+7I7.6b180c876;7Y7K7x5Z0X7c557=8k7?84046R6E8b136c8r7*047}8e7)8g834k6|6~7k7L7X8p6^8y5X8t8K7W7|8u8A7`716|0M8B2q7g4L6J6L7L6O046m1^0|6*6,0J0|2U8p6T6V5+0!6Y0V6v1p6Y0Z0 0(0)8/2k0|0U2@0n0Z2t7;8G18981^8W65679f8s898u7X7v8F7x7^7U8S3Y779i7y7A7%9o7)7X5*7,7J9z5X7n0o5J9s768o6?8q8N5;9k9P9L9n5y8f186e9K468D8E3p8m4k8Y047j9V8z9X8!6/7x8%6m5p0!6p0O0U2Z0o1p6Z6n0k6n0o6p1_5 1p0!0)9E4q8#9p180.1)9e9Z5}049dab3A9(2q6|0l9$ao7L6c8h7;ad9A9uajaq9haC8cam8u6|0z9l9c2N8Q180-0f6f8$6k8(6D0@0o2X6u958{8-a00 97994V8lap8c5 619S9!18aKa=ak5,0Z2u0HaO5!aL8d3b9W04aR6 a.139?0n0k0P0S1n6A0}6)6+2G6Y0qa1a3a50na:an3M6K8l7R187T9v7X8x9F8T9x82aF7t9C86a_88048abK8c9U3Aav9X8i9%b801ba6s6u6#6%1D0n0+0Sa430b(a0bQ3Ma-az7{9M6@1FbO9jbMb1bB9-8L9/bG7yaEbC9tb@9Ob39.b|b`8vb~bRb49Yc57 180m9v9*54bVaT6P1Y7g0!1D6B1_8;6U8^8@6Y2Uceb:b;7Qae7B9Jci8n8Ib_c9c0cbcP8O8wa ch9%7L9#cm7h9+a bUaobWbabcbe6q6u1!bma)am6v0o8{2T9N8=cA6Xb(0k1n0n9,4ycG8k9bala+cS7!a@b1a{a}a 5#ccbAa b655bucH7)7n2X0J6tbFcLakbr3:0G5B5w1P5i0G5k1G0J5mdG2-2)27292+0k1@dBdE5t1M5D712X0s0:0K0k6z0:0$0Q181y1A6(0|c(2%1P3q1N0N0w6v6A0_8}1m0|0w0S0T0o6(6Q001n0`a4bg951_2D0A0i0n0-5p6,97bea!1q2j0O5p6t0|2ua10O0T0A6t0feebZbb0Z8~e2cv6U0W0k2Z1z6Vbn362N0O0o0)0J6Tc;a20;10cx1_0w003G0T3+2R0$2Ga00x0k0$0!a^1W1R04d@6U6p0n30eS6E0Rc~2Uehenbg1c6u2Ua|158.eG1z8~1Eeee!brbq0;6qcud_d 1q1C009 e66o1_eaa*6Cbe0nfvec0z0n060#em1g150(0U1-bg0k0+2Yfz1qbI5.0n323ea80A0Wedc@bq1qfse8fQ6r2tf$fi15eL8*a$bk0|2X5*be0Z91971g2g1u2P6X1E2g0!2@fZ0|0Z0Ua4f}6ufh8:c{cz6W8^ee3G3+0|e32Qf-f(0Rfu96ec069 0Sfj0of:g38,f?gcbq0O60eY6Z6SghcB97gag8f~f2g18^g39^g61EfC0Yf~fYfc6CfNfP6CfS1_5A5q040T0n0%0n0L000D000B0n0c000j000Xeeg g{g}h20n000vh5g~0,h1h3hdg|6d7Odzg/ffa27p0!9}9 g.5C5U0:0J2N0S1GdA19grc~fvc?eN0Hga6YfggH2X5{hAg~hahf00h3g`h3h09YhA1wgp9 dX8~eIeZa2hFf~fA2teegxgzf:fqhLg-hOg_hSh8hQh8h0hRhXhlhNg/h`hzg/6U6Yhs5wh900i65C0neRc~f;0?0U0Wf=0@8/eYgL8?c~0)0T3G0nbm7L1ge)1f6q0W18090-0V09dl3pe;d=04d+1ge3g|esc,1nhD1q6qe`ia3D1~1,1.1:dV7m7$cKcX7x0!0;182Edgb1dxcc5=9varat2%bWi:i=2ui@di857-i`18iKbRhkifbm0(6r2M9C6,h/emewcCeR6Actf4c^a#g,gGgA8^6T2O110p2Ua#0(0*0~0AfC0,93bh0}10ee0`fU00fYa46qf}8/h?gI0nhw2Od e16(iM1adE0@0_0{04.

###(Dés-)Active le code après la ligne # Tests (insensible à la casse)
(Ctrl+I)
Entrer ou sortir du mode "deux colonnes"
(Alt+: ; Ctrl pour inverser les colonnes)
Entrer ou sortir du mode "plein écran"
(Esc)
Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)
Si activé, le texte copié dans le terminal est joint sur une seule ligne avant d'être copié dans le presse-papier
Évaluations restantes : 10/10

.1280135[4})2R,Ba!- ièà8m16ClK7.e:9A;S/dktf{+Irj3sogu0x]PpnEh=céyvD(wq_b050H0A0J0k0o0w0R0n0(0w0k0R0R0%010J0o0Z010406050R0U0s0s0k0O0*040F0S0w0U150S0!0n020k0s0Z0E0n0h0A1f0O0/0U0A0R050G1c1e1g1i1a0Z041G1N051Q0G1Q1S1N1a0H0o0+0}0 11130$0o0T0$0w1*0$0J18050^0;0w0A1#1012011)1+1-1+0J1?1^1;0J0;0S0H1i1=0O1O0J0$0}1l0R0Z0k0!130g011`1%010K0`0A0!1t0A1;2i2k2p1|2s1^2v0s2x040a0n0Y0O0S0Z0S0R0o1o1q0?2g0O0O0A0(2S1G2z0!1O0G2e2(0J2c2b2d0H2B131-0!2u2P1;1Y1!0~1{2=0o2@0!281Z1;0Z2X1O2$2(391b2j1q2}2q320O1f0w180n0t2#3d193c2A3f1|3h3j3l0g3o2k3q2$2;013v0k3k040n0Q3z2%1a3C3t133F3H0n0d3L3B3d3D3R3l0b3V3N3X3P3E0S3i3G3l0u3$3r3e1$3u3+3w3I0y3:3O3?3Q3^3-3I0r3|3(3~3*3,3S0C443s463Z040t0V4b3=2~473_0t3n1H3p3%4c4k4e0t3y4p3A4r4j3g403H0t3K4x3M3;3Y4C180t3U4G3W4s4B484L3#4O4z4J4S4f3/4V4I3)4u3{4#3}4t4K4f434*454,4Y0t4a4:4Q3@4Y0g4h4_4A4{3_0g4o394W4%4-0g4w554$4d584F3b1T371G2{2+0H2/3D0(282H0=1Z1O360A383p3V055p0?5x4`130I180?0K5z4+2q0.3l5K4;3g0K182,0o5P5E0117040-5W503Q180T0O0k0Z0$0A5$3D5Z0f0B3$0n5_0n5c4t183+0H2X3V5{5L1|0S180%625|2q5Z0c0X62635Q1|0(0t18030n1-0R0J1_2O0U0O0n6p0S0(0I0A6u1^0n2X1c0w0^0J3$065`6g5X6j6l0n0?5*0)0n2u2,2k0J6Q1_0(0$0k1C1_0R0S1e0@5^5`6a3u5H0A5*1E6964136604684O6M5%5Y180L5:4%180U75465Z5@6 6:130s0o184~39703D5G040K3+6_6h5(04787d6`010S5N04307r5X0!5)5+5-5/4O7e72040e6.5_7L7n7p0O7D717F7u7V3D7z187C7w7s3E7G5,5.794k7b7P6L7l3)7S7q7(7E180+7Z3)7#7B0!7~4d7+7I7.6b180c876;7Y7K7x5Z0X7c557=8k7?84046R6E8b136c8r7*047}8e7)8g834k6|6~7k7L7X8p6^8y5X8t8K7W7|8u8A7`716|0M8B2q7g4L6J6L7L6O046m1^0|6*6,0J0|2U8p6T6V5+0!6Y0V6v1p6Y0Z0 0(0)8/2k0|0U2@0n0Z2t7;8G18981^8W65679f8s898u7X7v8F7x7^7U8S3Y779i7y7A7%9o7)7X5*7,7J9z5X7n0o5J9s768o6?8q8N5;9k9P9L9n5y8f186e9K468D8E3p8m4k8Y047j9V8z9X8!6/7x8%6m5p0!6p0O0U2Z0o1p6Z6n0k6n0o6p1_5 1p0!0)9E4q8#9p180.1)9e9Z5}049dab3A9(2q6|0l9$ao7L6c8h7;ad9A9uajaq9haC8cam8u6|0z9l9c2N8Q180-0f6f8$6k8(6D0@0o2X6u958{8-a00 97994V8lap8c5 619S9!18aKa=ak5,0Z2u0HaO5!aL8d3b9W04aR6 a.139?0n0k0P0S1n6A0}6)6+2G6Y0qa1a3a50na:an3M6K8l7R187T9v7X8x9F8T9x82aF7t9C86a_88048abK8c9U3Aav9X8i9%b801ba6s6u6#6%1D0n0+0Sa430b(a0bQ3Ma-az7{9M6@1FbO9jbMb1bB9-8L9/bG7yaEbC9tb@9Ob39.b|b`8vb~bRb49Yc57 180m9v9*54bVaT6P1Y7g0!1D6B1_8;6U8^8@6Y2Uceb:b;7Qae7B9Jci8n8Ib_c9c0cbcP8O8wa ch9%7L9#cm7h9+a bUaobWbabcbe6q6u1!bma)am6v0o8{2T9N8=cA6Xb(0k1n0n9,4ycG8k9bala+cS7!a@b1a{a}a 5#ccbAa b655bucH7)7n2X0J6tbFcLakbr3:0G5B5w1P5i0G5k1G0J5mdG2-2)27292+0k1@dBdE5t1M5D712X0s0:0K0k6z0:0$0Q181y1A6(0|c(2%1P3q1N0N0w6v6A0_8}1m0|0w0S0T0o6(6Q001n0`a4bg951_2D0A0i0n0-5p6,97bea!1q2j0O5p6t0|2ua10O0T0A6t0feebZbb0Z8~e2cv6U0W0k2Z1z6Vbn362N0O0o0)0J6Tc;a20;10cx1_0w003G0T3+2R0$2Ga00x0k0$0!a^1W1R04d@6U6p0n30eS6E0Rc~2Uehenbg1c6u2Ua|158.eG1z8~1Eeee!brbq0;6qcud_d 1q1C009 e66o1_eaa*6Cbe0nfvec0z0n060#em1g150(0U1-bg0k0+2Yfz1qbI5.0n323ea80A0Wedc@bq1qfse8fQ6r2tf$fi15eL8*a$bk0|2X5*be0Z91971g2g1u2P6X1E2g0!2@fZ0|0Z0Ua4f}6ufh8:c{cz6W8^ee3G3+0|e32Qf-f(0Rfu96ec069 0Sfj0of:g38,f?gcbq0O60eY6Z6SghcB97gag8f~f2g18^g39^g61EfC0Yf~fYfc6CfNfP6CfS1_5A5q040T0n0%0n0L000D000B0n0c000j000Xeeg g{g}h20n000vh5g~0,h1h3hdg|6d7Odzg/ffa27p0!9}9 g.5C5U0:0J2N0S1GdA19grc~fvc?eN0Hga6YfggH2X5{hAg~hahf00h3g`h3h09YhA1wgp9 dX8~eIeZa2hFf~fA2teegxgzf:fqhLg-hOg_hSh8hQh8h0hRhXhlhNg/h`hzg/6U6Yhs5wh900i65C0neRc~f;0?0U0Wf=0@8/eYgL8?c~0)0T3G0nbm7L1ge)1f6q0W18090-0V09dl3pe;d=04d+1ge3g|esc,1nhD1q6qe`ia3D1~1,1.1:dV7m7$cKcX7x0!0;182Edgb1dxcc5=9varat2%bWi:i=2ui@di857-i`18iKbRhkifbm0(6r2M9C6,h/emewcCeR6Actf4c^a#g,gGgA8^6T2O110p2Ua#0(0*0~0AfC0,93bh0}10ee0`fU00fYa46qf}8/h?gI0nhw2Od e16(iM1adE0@0_0{04.