Derniers messages sur Zeste de Savoirhttps://zestedesavoir.com/forums/2024-02-06T04:12:40+01:00Les derniers messages parus sur le forum de Zeste de Savoir.Algorithme pour trouver les dépendances, message #2539032024-02-06T04:12:40+01:00Wizix/@Wizixhttps://zestedesavoir.com/forums/sujet/17323/algorithme-pour-trouver-les-dependances/?page=1#p253903<p><a href="/@Aabu" rel="nofollow" class="ping ping-link">@<span class="ping-username">Aabu</span></a>, merci c’est exactement ce que je cherchais ! En plus un paquet python existe déjà dans la std pour faire ça : <a href="https://docs.python.org/3/library/graphlib.html">graphlib</a> (même si tu dis que ce n’est pas trop compliqué, c’est toujours ça de moins à faire) <img src="/static/smileys/svg/smile.svg" alt=":)" class="smiley"></p>
<figure><blockquote>
<p>Par curiosité, tu fais de l’Ada en pro ou en perso ?</p>
</blockquote><figcaption><a href="https://zestedesavoir.com/forums/sujet/17323/algorithme-pour-trouver-les-dependances/?page=1#p253902">Heziode</a></figcaption></figure>
<p>Les deux ! J’ai la chance d’avoir trouvé un travail qui me permet de faire de l’Ada tous les jours comme langage principal et je continue à explorer ses possibilités et son efficacité à la maison. </p>Algorithme pour trouver les dépendances, message #2539022024-02-05T16:45:39+01:00Heziode/@Heziodehttps://zestedesavoir.com/forums/sujet/17323/algorithme-pour-trouver-les-dependances/?page=1#p253902<p>Bonjour,</p>
<p>Ta problématique est en effet plus lié à un problème de graphe de dépendance que d’Ada.
Comme le dit <a href="/@Aabu" rel="nofollow" class="ping ping-link">@<span class="ping-username">Aabu</span></a>, l’emploi d’un algorithme de tri topologique semble être la meilleure option ici.</p>
<p>Sinon, tu génères un <code>.ads</code> par type, et comme tu sais pour un type <span class="math math-inline"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi></mrow><annotation encoding="application/x-tex">n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathdefault">n</span></span></span></span></span> de qui il dépend, tu as juste à faire les <code>with …;</code> qui correspond au début de ton unité de compilation.</p>
<p>Par curiosité, tu fais de l’Ada en pro ou en perso ?</p>Algorithme pour trouver les dépendances, message #2539002024-02-05T10:13:22+01:00Aabu/@Aabuhttps://zestedesavoir.com/forums/sujet/17323/algorithme-pour-trouver-les-dependances/?page=1#p253900<p>Salut,</p>
<p>Normalement, ton graphe de dépendance devrait être orienté et acyclique (donc sans boucle). Dans ce cas-là, on peut obtenir assez facilement un tri topologique, qui est le résultat que tu cherches à obtenir. C’est une liste linéaire des noeuds du graphe de dépendance qui respecte les relations de dépendances.</p>
<p>Ce n’est pas très compliqué à programmer, puisqu’on peut obtenir un tri topologique avec un algo proche d’un parcours en profondeur. Voir par exemple <a href="https://fr.wikipedia.org/wiki/Tri_topologique">ce qu’on trouve sur Wikipédia</a> à ce sujet.</p>
<p>Je fais aussi ma publicité au passage, puisque j’ai écrit un article sur un sujet proche : <a href="https://zestedesavoir.com/articles/3547/shabiller-dans-le-bon-ordre-grace-aux-mathematiques/">S’habiller dans le bon ordre grâce aux mathématiques</a>. Dans cet article, j’utilise l’algorithme de Kahn.</p>Algorithme pour trouver les dépendances, message #2538982024-02-05T09:44:04+01:00Wizix/@Wizixhttps://zestedesavoir.com/forums/sujet/17323/algorithme-pour-trouver-les-dependances/?page=1#p253898<p>Bonjour,<br>
J’écris en ce moment un générateur de code Ada pour de l’embarqué. Il permet de générer la description de messages (des types Ada) reçus et envoyés par un microcontrôleur dont le logiciel est fait en Ada.</p>
<p>Les messages sont des records (dans d’autre langage appelé "struct") qui ont des champs qui possèdes tous un type. Ça peut être des tableaux de records, des entiers…</p>
<p>Chaque type est donné dans un fichier. Par exemple un type allant de 0 à 127 appelé A, sera dans un fichier A.range.yaml. Un autre type B qui est un tableau de 15 éléments de type A sera dans un autre fichier B.array.yaml. Les fichiers YAML étant les points d’entrés du logiciel.</p>
<p>Pour cet exemple, il faut que mon logiciel me sorte comme fichier ads le fichier suivant :</p>
<div class="hljs-code-div hljs-code-ada"><div class="hljs-line-numbers"><span data-count="1"></span><span data-count="2"></span><span data-count="3"></span><span data-count="4"></span></div><pre><code class="hljs language-ada"><span class="hljs-keyword">type</span> <span class="hljs-type">A_T </span><span class="hljs-keyword">is</span> <span class="hljs-keyword">range</span> <span class="hljs-number">0</span> .. <span class="hljs-number">127</span>;
<span class="hljs-keyword">type</span> <span class="hljs-type">B_Index_T </span><span class="hljs-keyword">is</span> <span class="hljs-keyword">range</span> <span class="hljs-number">1</span> .. <span class="hljs-number">15</span>;
<span class="hljs-keyword">type</span> <span class="hljs-type">B_T </span><span class="hljs-keyword">is</span> <span class="hljs-keyword">array</span> (B_Index_T) <span class="hljs-keyword">of</span> A_T;
</code></pre></div>
<p>Dans ce cas là c’est assez simple, A n’ayant pas de dépendance par définition se retrouve forcément au début du fichier, suivi de B qui a forcément une dépendance (par définition encore une fois).</p>
<p>Mais si je prends un cas plus complexe, avec une structure qui contient des tableaux et ces tableaux qui contiennent d’autres structures avec eux-mêmes d’autres types composés… La question se pose alors :</p>
<p>Comment déterminer l’ordre dans lequel le générateur doit définir les types pour que le fichier Ada compile ?</p>
<p>J’imagine qu’il faut se pencher sur les graphs… Mais j’avoue être complètement novice dans ce vaste domaine. Auriez-vous des pistes ? Ou mêmes des idées d’algorithmes ?</p>
<p>Je vous remercie.</p>Aide algorithme machine learning, message #2538942024-02-04T12:02:33+01:00Berdes/@Berdeshttps://zestedesavoir.com/forums/sujet/17322/aide-algorithme-machine-learning/?page=1#p253894<figure><blockquote>
<p>J’ai pensé à faire un modèle de prédiction (en commençant par le random forest) de réponse positive par traitement qui va me donner une probabilité, et prendre à la fin le traitement avec la plus haute probabilité. Est-ce que vous pensez que je suis sur la bonne voie ? Est-ce qu’il y a mieux à mettre en place dans ce cas de figure ?</p>
</blockquote><figcaption><a href="https://zestedesavoir.com/forums/sujet/17322/aide-algorithme-machine-learning/?page=1#p253890">Léa</a></figcaption></figure>
<p>L’approche de prédire la probabilité de réponse à chaque traitement me semble raisonnable. En dehors des random forests, il y a aussi toute une classe de modèles qui généralisent une régression linéaire qui appliquent des fonctions non-linéaires aux entrées (par exemple <a href="https://en.wikipedia.org/wiki/Generalized_additive_model">GAM</a>) ou qui permettent des interactions non-linéaires entre variables (par exemple <a href="https://en.wikipedia.org/wiki/Multivariate_adaptive_regression_spline">MARS</a>). Ça peut être aussi intéressant de regarder de ce côté là si tu as suffisamment de données.</p>
<figure><blockquote>
<p>Je ne sais pas comment tester ce modèle car le traitement prédit ne correspond pas forcément au traitement qui a réellement été donné au patient dans mon jeu de données, donc je ne peux pas connaître la réponse 0/1 à cet ensemble patient / traitement à tous les coups.</p>
</blockquote><figcaption><a href="https://zestedesavoir.com/forums/sujet/17322/aide-algorithme-machine-learning/?page=1#p253890">Léa</a></figcaption></figure>
<p>Le traitement réellement donné au patient n’est pas forcément le meilleur traitement, même si la réponse à été positive. Ce que tu veux tester, c’est à quel point ton modèle arrive à prédire si un traitement va être positif ou non. Attention à bien séparer aléatoirement tes données en un ensemble d’entrainement et un ensemble de validation pour pouvoir vérifier que ton modèle n’a pas de problèmes de surapprentissage.</p>Aide algorithme machine learning, message #2538932024-02-03T14:56:37+01:00ache/@achehttps://zestedesavoir.com/forums/sujet/17322/aide-algorithme-machine-learning/?page=1#p253893<p>J’avais pensé à <a href="https://fr.wikipedia.org/wiki/Algorithme_ID3">l’algorithme ID3</a> en premier lieu pour commencer en faisant des classes sur les ages. Mais il existe certainement mieux.</p>
<blockquote>
<p>Je ne sais pas comment tester ce modèle car le traitement prédit ne correspond pas forcément au traitement qui a réellement été donné au patient dans mon jeu de données, donc je ne peux pas connaître la réponse 0/1 à cet ensemble patient / traitement à tous les coups.</p>
</blockquote>
<p>Là par-contre, ça va vraiment poser problème. L’apprentissage automatique n’est pas magique. Si les données de bases ne sont pas de qualité le résultat que tu obtiendras ne pourra pas être meilleur que les données de base<sup id="fnref-1-h6U-aLTPr"><a href="#fn-1-h6U-aLTPr" class="footnote-ref">1</a></sup>.</p>
<div class="footnotes">
<hr>
<ol>
<li id="fn-1-h6U-aLTPr">Si tu as d’autres connaissances sur le sujet tu « peux » obtenir de meilleur résultats mais seulement mais ces performances seront plus le fruit de tes connaissances supplémentaire que du jeu de donnée de base.<a href="#fnref-1-h6U-aLTPr" class="footnote-backref" title="Retourner au texte de la note 1">↩</a></li>
</ol>
</div>Aide algorithme machine learning, message #2538902024-02-02T11:19:25+01:00Léa/@L%C3%A9ahttps://zestedesavoir.com/forums/sujet/17322/aide-algorithme-machine-learning/?page=1#p253890<p>Bonjour à tous,</p>
<p>Dans le cadre d’un projet scolaire, je dois analyser un jeu de données avec des patients (avec des caractéristiques : sexe, âge, fumeur 0/1, etc.) qui ont reçu différents traitements (un par patient) avec une réponse à ce traitement 1/0.</p>
<p>Ex : </p>
<p>Patient 1 | Homme | 45 ans | Fumeur 0 | Diabète 0 | Obésité 1 | Traitement A | Réponse 1</p>
<p>Patient 2 | Homme | 20 ans | Fumeur 1 | Diabète 0 | Obésité 0 | Traitement B | Réponse 0</p>
<p>Patient 3 | Homme | 57 ans | Fumeur 1 | Diabète 1 | Obésité 0 | Traitement C | Réponse 0</p>
<p>Patient 4 | Femme | 49 ans | Fumeur 1 | Diabète 0 | Obésité 0 | Traitement B | Réponse 0</p>
<p>Patient 5 | Femme | 42 ans | Fumeur 0 | Diabète 0 | Obésité 1 | Traitement A | Réponse 0</p>
<p>Patient 6 | Femme | 34 ans | Fumeur 0 | Diabète 0 | Obésité 0 | Traitement C | Réponse 1</p>
<p>Je souhaite mettre en place un modèle qui va prédire le meilleur traitement (avec la meilleur probabilité de réponse positive) à mettre en place pour chaque nouveau patient qui va arriver.</p>
<p>J’ai pensé à faire un modèle de prédiction (en commençant par le random forest) de réponse positive par traitement qui va me donner une probabilité, et prendre à la fin le traitement avec la plus haute probabilité. Est-ce que vous pensez que je suis sur la bonne voie ? Est-ce qu’il y a mieux à mettre en place dans ce cas de figure ?</p>
<p>Je ne sais pas comment tester ce modèle car le traitement prédit ne correspond pas forcément au traitement qui a réellement été donné au patient dans mon jeu de données, donc je ne peux pas connaître la réponse 0/1 à cet ensemble patient / traitement à tous les coups.</p>
<p>En vous remerciant par avance si vous avez des idées.</p>itinéraire le plus court, message #2496432023-03-19T22:41:49+01:00Arius/@Ariushttps://zestedesavoir.com/forums/sujet/16868/itineraire-le-plus-court/?page=2#p249643<p>Par contre, on va arrêter avec les réponses sarcastiques, svp. </p>
<p>Il n’y a rien de bien méchant ou provocant dans ce que <a href="/@adri1" rel="nofollow" class="ping ping-link">@<span class="ping-username">adri1</span></a> a dit et, même si je peux concevoir que cela ait mal été interprété, ce genre de réponse ne peut mener qu’à une joute de piqûres écrites. Ce qui n’est ni désiré ni désirable. </p>itinéraire le plus court, message #2496412023-03-19T19:41:46+01:00ache/@achehttps://zestedesavoir.com/forums/sujet/16868/itineraire-le-plus-court/?page=2#p249641<blockquote>
<p>Le texte de Wikipedia n’est pas suffisamment clair (pour moi, en tout cas).</p>
</blockquote>
<p>Oui, je peux comprendre. Wikipédia semble parfois un peu abrupt et dur à appréhender.</p>
<blockquote>
<p>Le titre n’est pas très original, mais j’aime la présentation.</p>
</blockquote>
<p>Je comprends, c’est pas mal en effet. Je viens de finir de le lire, il est agréable à lire.</p>
<p><a href="/@adri1" rel="nofollow" class="ping ping-link">@<span class="ping-username">adri1</span></a>: Tiens t’as vu, le site aussi il utilise le terme « visiter ». On a tous très mal choisi dis donc.</p>itinéraire le plus court, message #2496372023-03-19T16:41:57+01:00PierrotLeFou/@PierrotLeFouhttps://zestedesavoir.com/forums/sujet/16868/itineraire-le-plus-court/?page=2#p249637<p>Le texte de Wikipedia n’est pas suffisamment clair (pour moi, en tout cas).</p>
<p>J’ai trouvé ce site qui explique mieux cet algorithme:</p>
<p><a href="https://haltode.fr/algo/structure/graphe/plus_court_chemin/dijkstra.html">Algorithme de Dijkstra</a>.</p>
<p>Le titre n’est pas très original, mais j’aime la présentation.</p>itinéraire le plus court, message #2496332023-03-19T09:00:35+01:00ache/@achehttps://zestedesavoir.com/forums/sujet/16868/itineraire-le-plus-court/?page=2#p249633<p>La relaxation est une opération sur les arrêtes.
Pas sur les distances.<br>
C’est celle-ci dans le code de <a href="/@PierrotLeFou" rel="nofollow" class="ping ping-link">@<span class="ping-username">PierrotLeFou</span></a>.</p>
<div class="hljs-code-div hljs-code-py"><div class="hljs-line-numbers"><span data-count="1"></span><span data-count="2"></span></div><pre><code class="hljs language-py"><span class="hljs-keyword">if</span> cumulatif + distance < acces[noeud]:
acces[noeud] = cumulatif + distance
</code></pre></div>
<p>Si tu trouves une référence qui parle de relaxation des distances, tu peux m’en faire part si tu veux.</p>
<p>Bref, étant donné qu’une distance ne peut qu’augmenter, alors oui, si un arc mets à jour une distance dans un sens il ne le fera jamais dans l’autre sens dans l’algorithme de Dijkstra.</p>itinéraire le plus court, message #2496322023-03-19T02:10:13+01:00adri1/@adri1https://zestedesavoir.com/forums/sujet/16868/itineraire-le-plus-court/?page=2#p249632<blockquote>
<p>Oui si tu veux dans l’idée mais, c’est techniquement faux dans les graphes non orienté car dès que tu visites (ou sélectionne) un nouveau nœud (pas la source donc, ni la destination d’ailleurs), tu relaxes également l’arête qui t’a permis de venir depuis le nœud sélectionné précédent. Bref, techniquement, tu “parcoures” (ou visite, le terme est normalement « relexer ») un arc au maximum 2 fois avec Dijkstra.</p>
</blockquote>
<p>??? On ne relaxe pas les arêtes, mais la distance qui permet d’atteindre un nœud donné. Le fait que le graphe soit orienté ou non ne change absolument rien en pratique, revenir au nœud (N) précédent à partir du nœud courant va forcément conduire à une distance plus grande pour atteindre ce nœud (N). De fait, l’arête en question n’est jamais considérée dans le sens de retour vers le nœud précédent.</p>itinéraire le plus court, message #2496312023-03-19T01:53:20+01:00ache/@achehttps://zestedesavoir.com/forums/sujet/16868/itineraire-le-plus-court/?page=2#p249631<blockquote>
<p>Un problème assez clair avec ton programme en l’état et justement le fait que dijkstra implémente à moitié l’algo, puis que tu te visites le graphe une seconde fois (contraire donc à l’esprit de Dijkstra) pour retrouver le plus court chemin.</p>
</blockquote>
<p>Le problème claire est que Dijkstra sélectionne le nœud de distance minimum. </p>
<p>Cette histoire de parcourt n’est pas très choquant pour moi mais généralement on stocke le prédécesseur de chaque nœud.
On retrouver ainsi le chemin en parcourant les prédécesseurs depuis le nœud de destination jusqu’à la source.
Ça évite de parcourir toutes les arrêtes.</p>
<p>Un prédécesseur est le nœud depuis lequel on a mis à jour la distance.
Il est mis à jour en même temps que la distance.</p>
<blockquote>
<p>Le choix de mots était pas judicieux, ça c’est sûr…</p>
</blockquote>
<p>L’algorithme de Dijkstra est fondé sur un parcourt en largeur et le terme « visiter » est le terme couramment utilisé pour le parcourt en largeur.</p>
<p>Par Wikipédia, par les cours à la fac et par <a href="https://zestedesavoir.com/tutoriels/681/a-la-decouverte-des-algorithmes-de-graphe/727_bases-de-la-theorie-des-graphes/3353_parcourir-un-graphe/#2-10504_le-parcours-en-largeur-et-le-buzz">ZdS</a>.
Je ne suis pas convaincu qu’on puisse dire qu’il est <strong>sûr</strong> que le choix du mot n’était pas judicieux.
Je te laisse moinssoyer. </p>itinéraire le plus court, message #2496302023-03-19T00:25:19+01:00Gil Cot/@Gil%20Cothttps://zestedesavoir.com/forums/sujet/16868/itineraire-le-plus-court/?page=2#p249630<p>Je trouve perso que le choix de l’infini est intéressant pour l’algo en elle-même… Ça oblige justement à bien comprendre au lieu de juste transposer : l’implémentation dans le langage choisi va alors forcément nécessiter une adaptation en terme de structure de données (même quand on a de l’infini à dispo, on n’est pas en train de faire du calcul formel… d’ailleurs me semble avoir déjà vu une implémentation qui utilisait des zéros.) </p>itinéraire le plus court, message #2496292023-03-18T23:55:39+01:00ache/@achehttps://zestedesavoir.com/forums/sujet/16868/itineraire-le-plus-court/?page=2#p249629<blockquote>
<p>Pour pouvoir rejeter cette branche, il a fallu qu’on se rendre jusqu’à c en passant par b. Donc, le noeud c est visité plus d’une fois.</p>
</blockquote>
<p>Non, le nœud est visité (ou sélectionné si tu veux) au plus une seule fois. Mais ses arêtes peuvent être relaxées plus d’une fois (la mise à jour des distances). En sommes, <em>dans mon idée</em>, relaxer les arêtes d’un nœud ne nous fait pas “voyager”, on met seulement à jour les distances.</p>
<blockquote>
<p>Je pense que ce qui est important, ce n’est pas de visiter un sommet une seule fois, mais de parcourir un arc une seule fois.</p>
</blockquote>
<p>Oui si tu veux dans l’idée mais, c’est techniquement faux dans les graphes non orienté car dès que tu visites (ou sélectionne) un nouveau nœud (pas la source donc, ni la destination d’ailleurs), tu relaxes également l’arête qui t’a permis de venir depuis le nœud sélectionné précédent. Bref, techniquement, tu “parcoures” (ou visite, le terme est normalement « relexer ») un <em>arc</em> au maximum 2 fois avec Dijkstra.</p>itinéraire le plus court, message #2496282023-03-18T18:38:34+01:00adri1/@adri1https://zestedesavoir.com/forums/sujet/16868/itineraire-le-plus-court/?page=2#p249628<blockquote>
<p>Pour pouvoir rejeter cette branche, il a fallu qu’on se rendre jusqu’à c en
passant par b. Donc, le noeud <code>c</code> est visité plus d’une fois.</p>
</blockquote>
<p>Ce que <a href="/@ache" rel="nofollow" class="ping ping-link">@<span class="ping-username">ache</span></a> voulait dire par "un nœud n’est visité qu’une seule fois" est
qu’on itère sur les voisins d’un nœud donné qu’une seule fois (au plus). On
peut évidemment <em>arriver</em> sur le même nœud plusieurs fois. Le choix de mots
était pas judicieux, ça c’est sûr…</p>
<blockquote>
<p>Pourquoi Dijkstra demande qu’on assigne une valeur infinie comme distance initiale du début à chaque sommet si ce n’est pour comparer avec les autres sous-graphes se rendant à ce sommet.</p>
</blockquote>
<p>Cette astuce est justement pour pouvoir comparer aux autres visites, comme tu
le dis. Personnellement je pense pas que ce soit si élégant que ça, ça empêche
l’algorithme de fonctionner sur des types qui n’ont pas d’infini à disposition
(les entiers par exemple, ou bien on pourrait même imaginer utiliser
l’algorithme sur une mesure de distance un peu particulière qui demande son
propre type et qui n’a pas d’infini). J’utiliserais plutôt une map pour
conserver les chemins les plus cours connus jusqu’en chaque sommet, si le
sommet est pas dans cette map c’est qu’on l’a pas encore rencontré (équivalent
de la distance "infinie" utilisée dans certaines descriptions de l’algorithme).</p>
<blockquote>
<p>Je pense que ce qui est important, ce n’est pas de visiter un sommet une seule fois, mais de parcourir un arc une seule fois.</p>
</blockquote>
<p>Oui. <a href="/@ache" rel="nofollow" class="ping ping-link">@<span class="ping-username">ache</span></a> a mal choisi ses mots je pense, mais c’est effectivement ce que Dijkstra garanti.</p>
<blockquote>
<p>Et je pense que c’est ce que fait mon code.</p>
</blockquote>
<p>Encore une fois, vérifier ton code n’est pas le sujet de ce topic. C’est ce que
je veux dire quand je dis que commenter sur ton code est hors-sujet. Il y a
plusieurs raisons pour lesquelles le fait que tu as posté ton propre code a été
mal reçu.</p>
<ul>
<li>Le but de ce forum n’est jamais de donner du code tout fait. On est là pour
aider la personne qui a posé la question à comprendre comment arriver à une
solution, pas lui donner la solution.</li>
<li>Tu as posté une implémentation avant même que l’OP n’ait daigné nous donner
une description claire de son projet, il est aussi de coutume sur ce forum
que l’OP participe activement à la discussion et montre ses efforts avant que
l’on offre des réponses détaillées.</li>
<li>Le code que tu as posté n’est pas de bonne qualité, et ça c’est assez gênant.
Si on doit débugger les codes des intervenants en plus de celui de l’OP, on
s’en sort pas. Personnellement, j’ai arrêté de lire en détail quand j’ai vu
que la fonction <code>dijkstra</code> modifie une de ses variables d’entrée d’une manière
assez obscure (i.e. il faut lire le code pour comprendre ce qui est fait) au
lieu de retourner le plus court chemin entre deux points (ce que l’algo de
Dijkstra est sensé faire !).</li>
</ul>
<p>Cela dit, vu que l’OP nous a fait faux-bond et qu’on ne le reverra sans doute
même pas, autant utiliser ce sujet… Un problème assez clair avec ton
programme en l’état et justement le fait que <code>dijkstra</code> implémente à moitié
l’algo, puis que tu te visites le graphe une seconde fois (contraire donc à
l’esprit de Dijkstra) pour retrouver le plus court chemin. Il n’y a aucune
raison de faire ça, il est beaucoup plus simple de sauvegarder le chemin
parcouru pendant l’exécution même de l’algorithme de Dijkstra.</p>itinéraire le plus court, message #2496272023-03-18T17:51:38+01:00PierrotLeFou/@PierrotLeFouhttps://zestedesavoir.com/forums/sujet/16868/itineraire-le-plus-court/?page=2#p249627<blockquote>
<p> b > c: 6 # on rejette cette branche comme on peut atteindre <code>c</code> en 5.</p>
</blockquote>
<p>Pour pouvoir rejeter cette branche, il a fallu qu’on se rendre jusqu’à <code>c</code> en passant par <code>b</code>.
Donc, le noeud `c est visité plus d’une fois.</p>
<p>Pourqqoi Dijkstra demande qu’on assigne une valeur infinie comme distance initiale du début à chaque sommet si ce n’est pour comparer avec les autres sous-graphes se rendant à ce sommet.</p>
<p>Je pense que ce qui est important, ce n’est pas de visiter un sommet une seule fois, mais de parcourir un arc une seule fois.</p>
<p>Et je pense que c’est ce que fait mon code.</p>itinéraire le plus court, message #2496172023-03-17T20:10:22+01:00adri1/@adri1https://zestedesavoir.com/forums/sujet/16868/itineraire-le-plus-court/?page=2#p249617<figure><blockquote>
<p>Il semble que je ne comprenne pas bien l’algo de Dijkstra. Pour le petit graphe suivant:</p>
<div class="hljs-code-div hljs-code-python"><div class="hljs-line-numbers"><span data-count="1"></span><span data-count="2"></span><span data-count="3"></span><span data-count="4"></span><span data-count="5"></span><span data-count="6"></span></div><pre><code class="hljs language-python">a b <span class="hljs-number">4</span>
a c <span class="hljs-number">5</span>
b c <span class="hljs-number">2</span>
b d <span class="hljs-number">9</span>
c d <span class="hljs-number">5</span>
a d <span class="hljs-number">0</span>
</code></pre></div>
<p>La dernière ligne démarre l’algo et indique que 'a' est le début et 'd' est la fin.</p>
<p>Selon ma compréhension de l’algo, il ne devrait pas regarder les suivants de 'c' car c’est la branche 'a’->’b' qui est minimale.
Et pourtant, il faut passer par 'c' pour un chemin minimal.</p>
</blockquote><figcaption><a href="https://zestedesavoir.com/forums/sujet/16868/itineraire-le-plus-court/?page=2#p249615">PierrotLeFou</a></figcaption></figure>
<p>Avec ce graphe, l’algo de Dijkstra va se comporter grosso-modo de la façon suivante. On part de <code>a</code>, les points atteignables sont les suivants :</p>
<div class="hljs-code-div hljs-code-text"><div class="hljs-line-numbers"><span data-count="1"></span><span data-count="2"></span></div><pre><code class="hljs language-text">a > b: 4
a > c: 5
</code></pre></div>
<p>Le chemin le plus court est <code>a > b</code>, donc on se place en <code>b</code> et regarde ce qui se passe :</p>
<div class="hljs-code-div hljs-code-text"><div class="hljs-line-numbers"><span data-count="1"></span><span data-count="2"></span><span data-count="3"></span><span data-count="4"></span></div><pre><code class="hljs language-text">a > b: 4
b > c: 6 # on rejette cette branche comme on peut atteindre `c` en 5.
b > d: 13
a > c: 5
</code></pre></div>
<p>On sait déjà qu’on peut atteindre <code>d</code> en <code>13</code>, voyons si on peut faire moins.
La branche la plus courte est à présent <code>a > c</code>, donc on se place en <code>c</code></p>
<div class="hljs-code-div hljs-code-text"><div class="hljs-line-numbers"><span data-count="1"></span><span data-count="2"></span><span data-count="3"></span><span data-count="4"></span></div><pre><code class="hljs language-text">a > b: 4
b > d: 13
a > c: 5
c > d: 10
</code></pre></div>
<p>On sait qu’on peut atteindre <code>d</code> en <code>10</code>. On a aussi atteint <code>d</code> dans chacun
des sous-graphes, donc on peut s’arrêter là, et on sait que la réponse est
<code>a > c > d: 10</code>.</p>
<p>Je ne commente pas sur ton code comme c’est hors-sujet…</p>
<p>L’intérêt de Dijkstra est que si il y avait en plus un sommet <code>e</code> tel que <code>a > e: 10</code> (par exemple), on ne considérerait jamais cette branche comme on a atteint la cible avec cette distance. Ou bien si on avait un sous-graphe dans ce genre :</p>
<div class="hljs-code-div hljs-code-text"><div class="hljs-line-numbers"><span data-count="1"></span><span data-count="2"></span><span data-count="3"></span><span data-count="4"></span></div><pre><code class="hljs language-text">a > e: 8
e > f: 11
e > g: 10
e > h: 15
</code></pre></div>
<p>on irait jamais plus profondément que ce premier "sondage" de la branche <code>a > e</code>.</p>itinéraire le plus court, message #2496152023-03-17T18:54:47+01:00PierrotLeFou/@PierrotLeFouhttps://zestedesavoir.com/forums/sujet/16868/itineraire-le-plus-court/?page=2#p249615<p>Je ne sais pas si je peux continuer ici …</p>
<p>Mon code avait effectivement des bugs:</p>
<ul>
<li>Je ne transmettais pas la valeur cumulée au sommet suivant.</li>
<li>je faisait le parcours à partir du début pour trouver le chemin le plus court. Il faut le faire à partir de la fin vers le début.</li>
</ul>
<p>Ensuite, il était inutile de retourner les longueurs minimales, puisqu’on retrouve dans <code>acess</code> cette valeur pour le sommet de sortie.</p>
<p>Pour des graphes orientés, je suppose qu’il ne faut pas enregistrer la distance dans les deux directions. Mais je devrais accumuler dans <code>acces</code> le sommet associé à la dernière valeur qu’on y a placée.</p>
<p>J’appelle toujours ma fonction dijkstra même si ce n’en est pas un. Voici mon nouveau code:</p>
<div class="hljs-code-div hljs-code-python"><div class="hljs-line-numbers"><span data-count="1"></span><span data-count="2"></span><span data-count="3"></span><span data-count="4"></span><span data-count="5"></span><span data-count="6"></span><span data-count="7"></span><span data-count="8"></span><span data-count="9"></span><span data-count="10"></span><span data-count="11"></span><span data-count="12"></span><span data-count="13"></span><span data-count="14"></span><span data-count="15"></span><span data-count="16"></span><span data-count="17"></span><span data-count="18"></span><span data-count="19"></span><span data-count="20"></span><span data-count="21"></span><span data-count="22"></span><span data-count="23"></span><span data-count="24"></span><span data-count="25"></span><span data-count="26"></span><span data-count="27"></span><span data-count="28"></span><span data-count="29"></span><span data-count="30"></span><span data-count="31"></span><span data-count="32"></span><span data-count="33"></span><span data-count="34"></span><span data-count="35"></span><span data-count="36"></span><span data-count="37"></span><span data-count="38"></span><span data-count="39"></span><span data-count="40"></span><span data-count="41"></span><span data-count="42"></span></div><pre><code class="hljs language-python"><span class="hljs-comment"># Algorithme de Dijkstra.</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">dijkstra</span>(<span class="hljs-params">graphe, acces, cumulatif, sommet, sortie</span>):</span>
<span class="hljs-keyword">if</span> sommet == sortie: <span class="hljs-keyword">return</span>
<span class="hljs-keyword">for</span> noeud, distance <span class="hljs-keyword">in</span> graphe[sommet].items():
<span class="hljs-keyword">if</span> cumulatif + distance < acces[noeud]:
acces[noeud] = cumulatif + distance
dijkstra(graphe, acces, cumulatif+distance, noeud, sortie)
<span class="hljs-comment"># Saisie des données.</span>
graphe = {}
acces = {}
<span class="hljs-keyword">while</span> <span class="hljs-literal">True</span>:
sommet1, sommet2, distance = <span class="hljs-built_in">input</span>(<span class="hljs-string">"> "</span>).split()
distance = <span class="hljs-built_in">int</span>(distance)
<span class="hljs-keyword">if</span> distance <= <span class="hljs-number">0</span>: <span class="hljs-keyword">break</span>
acces[sommet1] =<span class="hljs-built_in">float</span>(<span class="hljs-string">'inf'</span>)
acces[sommet2] = <span class="hljs-built_in">float</span>(<span class="hljs-string">'inf'</span>)
<span class="hljs-keyword">if</span> sommet1 <span class="hljs-keyword">not</span> <span class="hljs-keyword">in</span> graphe.keys():
graphe[sommet1] = {}
graphe[sommet1][sommet2] = distance
<span class="hljs-keyword">if</span> sommet2 <span class="hljs-keyword">not</span> <span class="hljs-keyword">in</span> graphe.keys():
graphe[sommet2] = {}
graphe[sommet2][sommet1] = distance
acces[sommet1] = <span class="hljs-number">0</span>
<span class="hljs-comment"># Retrouver le plus court chemin.</span>
dijkstra(graphe, acces, <span class="hljs-number">0</span>, sommet1, sommet2)
chemin = [sommet2]
minimum = acces[sommet2]
<span class="hljs-keyword">if</span> minimum < <span class="hljs-built_in">float</span>(<span class="hljs-string">'inf'</span>):
<span class="hljs-built_in">print</span>(<span class="hljs-string">"La longueur du chemin minimum est"</span>, minimum)
<span class="hljs-keyword">while</span> sommet1 != sommet2:
<span class="hljs-keyword">for</span> sommet, distance <span class="hljs-keyword">in</span> graphe[sommet2].items():
<span class="hljs-keyword">if</span> minimum - distance == acces[sommet]:
chemin.append(sommet)
sommet2 = sommet
minimum -= distance
<span class="hljs-keyword">break</span>
chemin.reverse()
<span class="hljs-built_in">print</span>(chemin)
<span class="hljs-keyword">else</span>:
<span class="hljs-built_in">print</span>(<span class="hljs-string">f"Pas de chemin entre <span class="hljs-subst">{sommet1}</span> et <span class="hljs-subst">{sommet2}</span>"</span>)
</code></pre></div>
<p>Il semble que je ne comprenne pas bien l’algo de Dijkstra. Pour le petit graphe suivant:</p>
<div class="hljs-code-div hljs-code-python"><div class="hljs-line-numbers"><span data-count="1"></span><span data-count="2"></span><span data-count="3"></span><span data-count="4"></span><span data-count="5"></span><span data-count="6"></span></div><pre><code class="hljs language-python">a b <span class="hljs-number">4</span>
a c <span class="hljs-number">5</span>
b c <span class="hljs-number">2</span>
b d <span class="hljs-number">9</span>
c d <span class="hljs-number">5</span>
a d <span class="hljs-number">0</span>
</code></pre></div>
<p>La dernière ligne démarre l’algo et indique que 'a' est le début et 'd' est la fin.</p>
<p>Selon ma compréhension de l’algo, il ne devrait pas regarder les suivants de 'c' car c’est la branche 'a’->’b' qui est minimale.
Et pourtant, il faut passer par 'c' pour un chemin minimal.</p>itinéraire le plus court, message #2496112023-03-17T14:38:15+01:00Arius/@Ariushttps://zestedesavoir.com/forums/sujet/16868/itineraire-le-plus-court/?page=2#p249611<p>Bonjour,</p>
<p>J’invite les participants à plus de tact dans leurs posts respectifs. </p>
<p><a href="/@PierrotLeFou" rel="nofollow" class="ping ping-link">@<span class="ping-username">PierrotLeFou</span></a> Je ne crois pas qu’il soit nécessaire de vouloir supprimer son compte ou masquer ses posts (que j’ai rétabli afin de ne pas nuire à la lecture du sujet, même si le code fourni est problématique). </p>
<p>Je pense, au contraire, qu’une discussion honnête permettra tant à l’OP qu’aux autres intervenants de mieux comprendre le problème et les solutions éventuelles (et par extension, toutes les remarques sur le code que tu as fourni sont bonnes à prendre). La critique constructive n’est jamais une mauvaise chose et, si une réponse te semble problématique, signaler le post permettra — comme c’est le cas ici - à un membre du staff d’intervenir pour calmer le jeu mais il n’est pas nécessaire de partir dans la confrontation ou inversement, de fuir le débat. Les gens ne sont généralement pas méchants sur ZdS. <img src="/static/smileys/svg/clin.svg" alt=";)" class="smiley"> </p>itinéraire le plus court, message #2496102023-03-17T13:45:07+01:00Gil Cot/@Gil%20Cothttps://zestedesavoir.com/forums/sujet/16868/itineraire-le-plus-court/?page=2#p249610<p>Pierrot, je m’excuse si mon message t’a offensé ; ce n’était pas le but.
Pas besoin de supprimer ton compte pour fuir ou faire plaisir à quelques personnes.</p>
<p>Pour un message problématique, tu peux le « signaler » pour que la modération le masque. Mais, pour soi, je trouve plus simple et plus rapide d’éditer son message pour supprimer la partie problématique (et indiquer qu’on a modifié pour que le fil ne soit pas étrange pour les personnes qui viendront plus tard.) </p>