<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="fr">
	<id>http://os-vps418.infomaniak.ch:1250/mediawiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Theodet</id>
	<title>Wiki du LAMA (UMR 5127) - Contributions [fr]</title>
	<link rel="self" type="application/atom+xml" href="http://os-vps418.infomaniak.ch:1250/mediawiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Theodet"/>
	<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php/Sp%C3%A9cial:Contributions/Theodet"/>
	<updated>2026-04-16T06:39:10Z</updated>
	<subtitle>Contributions</subtitle>
	<generator>MediaWiki 1.39.4</generator>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=VISI301_CMI_:_projet_de_recherche_et_d%C3%A9veloppement&amp;diff=13489</id>
		<title>VISI301 CMI : projet de recherche et développement</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=VISI301_CMI_:_projet_de_recherche_et_d%C3%A9veloppement&amp;diff=13489"/>
		<updated>2021-11-19T10:42:10Z</updated>

		<summary type="html">&lt;p&gt;Theodet : Typo et modification mineure de lien GitHub&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* Cours du semestre 3 du parcours CMI informatique (licence info) et, jusqu&#039;en 2021, CMI mathématique (licence math).&lt;br /&gt;
&lt;br /&gt;
* Responsables pour 2021--2022 : Pierre Hyvernat et Jacques-Olivier Lachaud&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Descriptif =&lt;br /&gt;
&lt;br /&gt;
L&#039;objectif de ce cours est de développer des compétences dans différents domaines de l&#039;algorithmique et la programmation Python, au travers du développement d&#039;un jeu. Les étudiants découvrent aussi les outils modernes de développement collaboratif (gestionnaire de version, pull requests, intégration continue). 8 séances sont prévues dans l&#039;EDT mais il est attendu du travail personnel supplémentaire. Les projets se font par binôme ou trinôme. Le travail est évalué sur la base d&#039;une démo et du rendu sur le serveur GitHub.&lt;br /&gt;
&lt;br /&gt;
Les étudiants rencontreront à intervalle régulier leurs enseignants tuteurs pour le projet afin de rendre compte de leur avancée dans leur projet (démarche similaire à celle des Travaux Personnels Encadrés). Le type de jeu choisi est laissé volontairement assez libre, de manière à ce que les étudiants développent leur imagination ainsi que leur capacités de réflexion et discussion collaboratives (brain-storming). Ils pourront aussi faire des recherches pour affiner leur modèle de jeu choisi.&lt;br /&gt;
&lt;br /&gt;
= Objectifs =&lt;br /&gt;
&lt;br /&gt;
L&#039;idée est de réaliser un jeu en python. L&#039;objectif est de finir avec un jeu simple mais fonctionnel. (Par exemple, il est préférable de n&#039;avoir qu&#039;un seul niveau à avoir 99 niveau si le personnage ne peut pas encore se déplacer...)&lt;br /&gt;
&lt;br /&gt;
Voici quelques exemples de jeux dont vous pouvez vous inspirer :&lt;br /&gt;
* jeu en mode &amp;quot;tour par tour&amp;quot; sur une grille discrète&lt;br /&gt;
** [http://www.ehttps://en.wikipedia.org/wiki/NetHack nethack]&lt;br /&gt;
** [https://en.wikipedia.org/wiki/Sokoban sokoban]&lt;br /&gt;
** [https://en.wikipedia.org/wiki/Boulder_Dash boulder dash]&lt;br /&gt;
** pacman&lt;br /&gt;
&lt;br /&gt;
* jeu en mode &amp;quot;temps réel&amp;quot; avec des coordonnées flottantes&lt;br /&gt;
** [https://en.wikipedia.org/wiki/XPilot xpilot]&lt;br /&gt;
** [https://en.wikipedia.org/wiki/Breakout_clone casse briques]&lt;br /&gt;
** agar.io&lt;br /&gt;
&lt;br /&gt;
* [https://en.wikipedia.org/wiki/Colossal_Cave_Adventure jeu d&#039;aventure en mode &amp;quot;textuel&amp;quot;]&lt;br /&gt;
&lt;br /&gt;
Le type de jeu que vous choisirez aura des conséquences sur le type de code que vous écrirez. Attention, les jeux &amp;quot;textuels&amp;quot; nécessitent, encore plus que les autres, une histoire bien racontée !&lt;br /&gt;
&lt;br /&gt;
Quel que soit votre choix, nous donnerons probablement des consignes supplémentaires.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Si vous ne trouvez pas d&#039;idée, nous imposerons un jeu du premier type avec les consignes suivantes :&lt;br /&gt;
* la carte est représenté par une ou plusieurs grilles de jeu,&lt;br /&gt;
* un ou plusieurs personnages se déplacent dans la grille (le(s) joueur(s), le(s) monstre(s)),&lt;br /&gt;
* actions en tour par tour,&lt;br /&gt;
* des niveaux générés aléatoirement.&lt;br /&gt;
&lt;br /&gt;
Cela permettra de développer pas mal d&#039;aspects différents de l&#039;algorithmique et de la programmation:&lt;br /&gt;
* structures de données pour représenter les plans de jeu, les personnages, les objets éventuels&lt;br /&gt;
* algorithmes de graphes pour générer des niveaux labyrinthiques&lt;br /&gt;
* programmation graphique pour afficher le décor et les éléments de jeu&lt;br /&gt;
* interfaces homme-machine pour diriger le jeu&lt;br /&gt;
* un peu d&#039;intelligence artificielle pour faire jouer les personnages non joueurs (monstres, ennemis, amis ).&lt;br /&gt;
* entrées/sorties pour sauvegarder le jeu/ les niveaux&lt;br /&gt;
&lt;br /&gt;
= Ressources =&lt;br /&gt;
&lt;br /&gt;
On pourra se baser sur [https://www.pygame.org/news pygame] , une bibliothèque Python conçue pour faire des jeux.&lt;br /&gt;
&lt;br /&gt;
* [https://inventwithpython.com/pygame/chapters/ chapitres ]&lt;br /&gt;
* [https://inventwithpython.com/makinggames.pdf Livre]&lt;br /&gt;
&lt;br /&gt;
Cela permet de faire facilement:&lt;br /&gt;
* les boucles d&#039;interactions&lt;br /&gt;
* les affichages graphiques&lt;br /&gt;
* la gestion du clavier ou de la souris.&lt;br /&gt;
&lt;br /&gt;
= Contraintes =&lt;br /&gt;
&lt;br /&gt;
* le projet sera fait en python (plus simple, développement plus rapide)&lt;br /&gt;
* les binômes (ou trinôme) seront tirés aléatoirement pour mélanger les promotions (CMI-math et CMI-info)&lt;br /&gt;
* vous utiliserez une plateforme de développement collaboratif [https://www.github.com Github]&lt;br /&gt;
&lt;br /&gt;
= Critères d&#039;évaluation =&lt;br /&gt;
&lt;br /&gt;
* Conception du jeu, réflexion initiale, originalité du jeu&lt;br /&gt;
* Réalisation, fluidité, ressenti général&lt;br /&gt;
* Intérêt du jeu, jouabilité, progressivité, richesse&lt;br /&gt;
* Méthodologie, régularité de l&#039;avancement, communication avec les tuteurs&lt;br /&gt;
* Rendu final, doc utilisateur, packaging, installation&lt;br /&gt;
* Autonomie, recherches personnelles, montée en compétence&lt;br /&gt;
&lt;br /&gt;
= résumé des commandes git de base =&lt;br /&gt;
  configuration (une seule fois sur votre machine)&lt;br /&gt;
  ------------------------------------------------&lt;br /&gt;
  &lt;br /&gt;
    $ git config --global user.name &amp;quot;PRENOM NOM&amp;quot;&lt;br /&gt;
    $ git config --global user.email &amp;quot;MON@ADRESSE.EMAIL&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  information (à utiliser sans modération)&lt;br /&gt;
  ----------------------------------------&lt;br /&gt;
  &lt;br /&gt;
    $ git status&lt;br /&gt;
    affiche l&#039;état du dépot (en fait, de la branche courante) : nouveaux &lt;br /&gt;
    fichiers, fichiers modifiés, etc.&lt;br /&gt;
  &lt;br /&gt;
    $ git log&lt;br /&gt;
    affiche la liste des commits du dépot (en fait, de la branche &lt;br /&gt;
    courante)&lt;br /&gt;
  &lt;br /&gt;
    $ git diff&lt;br /&gt;
    ou&lt;br /&gt;
    $ git diff FICHIERS&lt;br /&gt;
    affiche les différences entre le dépot actuel et le dernier commit &lt;br /&gt;
    (éventuellement, seulement pour les fichiers donnés en argument)&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  sauvegarde des modifications (&amp;quot;commit&amp;quot;)&lt;br /&gt;
  ---------------------------------------&lt;br /&gt;
  &lt;br /&gt;
    $ git add FICHIERS&lt;br /&gt;
    demande à git de gérer les fichiers FICHIERS&lt;br /&gt;
    (On peut donner plusieurs fichiers en même temps, ou utiliser les &lt;br /&gt;
    motifs du shell comme &amp;quot;git add *.py&amp;quot;)&lt;br /&gt;
    ATTENTION : le fichier n&#039;est pas sauvegardé par cette commande&lt;br /&gt;
  &lt;br /&gt;
    $ git commit&lt;br /&gt;
    ou plus souvent&lt;br /&gt;
    $ git commit -a -m &amp;quot;MESSAGE&amp;quot;&lt;br /&gt;
    enregistre l&#039;état du dépot (en fait, de la branche courante)&lt;br /&gt;
       - l&#039;option &#039;-a&#039; permet d&#039;enregistrer __tous__ les fichiers &lt;br /&gt;
         modifiés. Sans elle, il faut faire &amp;quot;git add FICHIERS&amp;quot; avant le &lt;br /&gt;
         &amp;quot;git commit&amp;quot;&lt;br /&gt;
         ATTENTION, les nouveaux fichiers ne sont pas ajoutés par l&#039;option &lt;br /&gt;
         &#039;-a&#039;, il faut impérativement faire &amp;quot;git add FICHIERS&amp;quot; pour les &lt;br /&gt;
         nouveaux fichiers.&lt;br /&gt;
       - l&#039;option &#039;-m &amp;quot;MESSAGE&amp;quot;&#039; permet de donner une description de ce &lt;br /&gt;
         commit&lt;br /&gt;
         Sans cette option, un éditeur de texte (probablement vi) sera &lt;br /&gt;
         lancé pour taper la description du commit. (Si vous ne savez pas &lt;br /&gt;
         utiliser vi, vous pouvez configurer un autre éditeur avec&lt;br /&gt;
         $ git config --global core.editor &amp;quot;MON_EDITEUR_FAVORI&amp;quot;&lt;br /&gt;
         )&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  communication avec un autre dépot&lt;br /&gt;
  ---------------------------------&lt;br /&gt;
  &lt;br /&gt;
    $ git pull REMOTE&lt;br /&gt;
    ou&lt;br /&gt;
    $ git pull&lt;br /&gt;
    récupère l&#039;état du dépot (en fait de la branche) depuis REMOTE&lt;br /&gt;
    Si un dépot distant est configuré (automatiquement si vous avez &lt;br /&gt;
    récupéré le dépot avec &amp;quot;git clone URL&amp;quot;), vous pouvez omettre REMOTE&lt;br /&gt;
  &lt;br /&gt;
    $ git push REMOTE&lt;br /&gt;
    ou&lt;br /&gt;
    $ git push&lt;br /&gt;
    envoie l&#039;état du dépot (en fait de la branche) vers REMOTE.&lt;br /&gt;
    Si un dépot distant est configuré (automatiquement si vous avez &lt;br /&gt;
    récupéré le dépot avec &amp;quot;git clone URL&amp;quot;), vous pouvez omettre REMOTE&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  importer un nouveau dépot (&amp;quot;fork&amp;quot;, &amp;quot;clone&amp;quot;)&lt;br /&gt;
  -------------------------------------------&lt;br /&gt;
    $ git clone URL&lt;br /&gt;
    récupère un dépot git dans un nouveau répertoire dans le répertoire &lt;br /&gt;
    courant.&lt;br /&gt;
    Typiquement, URL est récupérée sur github (&amp;quot;Clone or download&amp;quot;)&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  revenir en arrière&lt;br /&gt;
  ------------------&lt;br /&gt;
  &lt;br /&gt;
    $ git checkout HASH&lt;br /&gt;
    remet le dépot dans l&#039;état correspondant au commit de hash HASH&lt;br /&gt;
    Le hash d&#039;un commit est affiché par &amp;quot;git log&amp;quot;. Ça ressemble à &lt;br /&gt;
    ddca8e4f15958e4f5151c5e23c4d673a132334b2&lt;br /&gt;
    (il faut donner au moins les 4 premiers caractères du hash...)&lt;br /&gt;
  &lt;br /&gt;
    ATTENTION, ceci n&#039;est possible que si vous n&#039;avez aucun changement non &lt;br /&gt;
    enregistré.&lt;br /&gt;
  &lt;br /&gt;
    ATTENTION, il est déconseillé de modifier les fichiers lorsque le &lt;br /&gt;
    dépot est dans un état antérieur. Au besoin, vous pouvez faire&lt;br /&gt;
    $ git reset --hard&lt;br /&gt;
    pour remettre votre dépot dans l&#039;état exact du commit correspondant.&lt;br /&gt;
  &lt;br /&gt;
    $ git checkout master&lt;br /&gt;
    ou&lt;br /&gt;
    $ git checkout -&lt;br /&gt;
    remet le dépot dans l&#039;état final&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  Utilisation typique&lt;br /&gt;
  -------------------&lt;br /&gt;
  &lt;br /&gt;
  0/ création d&#039;un dépot vide depuis github (&amp;quot;New&amp;quot; depuis la page &lt;br /&gt;
  &amp;quot;Repositories&amp;quot; de votre compte github)&lt;br /&gt;
  &lt;br /&gt;
  ou bien&lt;br /&gt;
  &lt;br /&gt;
  0&#039;/ récupération d&#039;un dépot existant avec &amp;quot;git clone URL&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  Lors d&#039;une séance de travail :&lt;br /&gt;
  &lt;br /&gt;
  1/ synchronisation pour récupérer les changement du dépot central (sur &lt;br /&gt;
  github)&lt;br /&gt;
    $ git pull&lt;br /&gt;
  Normalement, il n&#039;y aura jamais de conflit à cette étape.&lt;br /&gt;
  &lt;br /&gt;
  2/ visualiser les nouveautés avec&lt;br /&gt;
    $ git log&lt;br /&gt;
  &lt;br /&gt;
  3/ travail, modification de fichiers, création de fichiers, etc.&lt;br /&gt;
  &lt;br /&gt;
  4/ lorsque vos modifications fonctionnent et sont finies :&lt;br /&gt;
    $ git add NOUVEAUX_FICHIERS&lt;br /&gt;
    $ git commit -a -m &amp;quot;MESSAGE&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
  5/ sauvegarde sur le dépot central&lt;br /&gt;
    $ git push&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  5/ en cas de conflit (parce que quelqu&#039;un a modifié le dépot central &lt;br /&gt;
  entre temps), résolution du conflit et nouveau commit :&lt;br /&gt;
    $ git commit -a -m &amp;quot;RESOLUTION CONFLIT&amp;quot;&lt;br /&gt;
    $ git push&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  Pour aller plus loin&lt;br /&gt;
  --------------------&lt;br /&gt;
  &lt;br /&gt;
  Lorsque vous maitrisez les commandes et concepts précédents, vous pouvez &lt;br /&gt;
  vous renseigner sur&lt;br /&gt;
  &lt;br /&gt;
    - les &amp;quot;branches&amp;quot; qui permettent d&#039;avoir plusieurs versions du dépots &lt;br /&gt;
      &amp;quot;en parallèle&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
    - les &amp;quot;remotes&amp;quot; qui permettent de communiquer avec plusieurs dépots &lt;br /&gt;
      lors des &amp;quot;git pull&amp;quot; et &amp;quot;git push&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
    - &amp;quot;git stash&amp;quot; qui permet de mettre de coté des modification &lt;br /&gt;
      momentanément&lt;br /&gt;
  &lt;br /&gt;
    - les &amp;quot;pull-requests&amp;quot;, qui permettent d&#039;avoir plusieurs dépots &lt;br /&gt;
      principaux, et d&#039;échanger des modifications entre eux. (Ceci est un &lt;br /&gt;
      mécanisme propre à github)&lt;br /&gt;
&lt;br /&gt;
= Equipes (2021-2022) =&lt;br /&gt;
&lt;br /&gt;
* Paul AUBRY, Alexandre DESBOS,  Nolan SANMARTI&lt;br /&gt;
* Andrien MONTMAYEUR, Maxent BERNIER,  Baptiste GRIVA&lt;br /&gt;
* Théo CONNETABLE, Emilien BOITOUZET, Lucas POLICASTRO&lt;br /&gt;
&lt;br /&gt;
= Sujets réalisés (2020-2021) =&lt;br /&gt;
&lt;br /&gt;
Responsables pour 2020--2021 : Jacques-Olivier Lachaud et Pierre Hyvernat&lt;br /&gt;
&lt;br /&gt;
* Théo GUESDON, Evan L&#039;HUISSIER, et Aurélien PARDO [https://github.com/Kroklethon/TotalCMIWar Total CMI War]&lt;br /&gt;
* Louise BOLLARD, Romain NEGRO et Julien DUCREY [https://github.com/romain22222/PROJET-CMI-LABYRINTHE Labyrinthe]&lt;br /&gt;
* Romain PAJEAN, Hugo REY et Simon MARSAN [https://github.com/Hearstgo/LostColor LostColor]&lt;br /&gt;
* Juliette NEYRAT, Simon PICHENOT et Léa DEVAUX [https://github.com/JediSim/color_mario Color Mario]&lt;br /&gt;
* Simon LEONARD, Florian DUFAURE, Reham NASSIF [https://github.com/Matows/slowed Slow motion]&lt;br /&gt;
&lt;br /&gt;
= Sujets réalisés (2019-2020) =&lt;br /&gt;
&lt;br /&gt;
Responsables pour 2019--2020 : Jacques-Olivier Lachaud et Pierre Hyvernat&lt;br /&gt;
&lt;br /&gt;
* Loïc Dornel et Anne Perez [https://github.com/CreeperStone72/visi301 Le donjon d&#039;Azorius]&lt;br /&gt;
* Yohann Thepault et Ewan Rakotoanosy [https://github.com/ythepaut/visi301_univdefender UnivDefender]&lt;br /&gt;
* Lucas Chardonnet et François D&#039;alayer [https://github.com/LucCha42/VISI301 GooDoo]&lt;br /&gt;
* Christophe Carmagnac et Martin Rialhe-Badet [https://github.com/445654/Escape Escape]&lt;br /&gt;
* Romain THEODET et Sarah Crumiere [https://github.com/RomainTHD/CruCru.io CruCru.io]&lt;br /&gt;
&lt;br /&gt;
= Sujets réalisés (2018-2019) =&lt;br /&gt;
&lt;br /&gt;
Responsables pour 2018--2019 : Jacques-Olivier Lachaud et Pierre Hyvernat&lt;br /&gt;
&lt;br /&gt;
* Rémi Bouvier et Nils Ruet [https://github.com/NilsRuet/VISI301 SnowForest]&lt;br /&gt;
* Tristan Porteries et Robin Wagner [https://github.com/panzergame/CrazyClass Crazy Class]&lt;br /&gt;
&lt;br /&gt;
= Sujets réalisés (2017-2018) =&lt;br /&gt;
&lt;br /&gt;
Responsables pour 2017--2018 : Jacques-Olivier Lachaud et Pierre Hyvernat&lt;br /&gt;
&lt;br /&gt;
* Ambroise Decouttère et Raphaël Tournafond,  [https://github.com/Ambrdctr/MazeRunner MazeRunner]&lt;/div&gt;</summary>
		<author><name>Theodet</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=13488</id>
		<title>Génération et résolution de labyrinthes II</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=13488"/>
		<updated>2021-11-19T10:40:38Z</updated>

		<summary type="html">&lt;p&gt;Theodet : Changement d&amp;#039;URL GitHub&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__FORCETOC__[[Fichier:labyrinthe_photo.png|vignette|300px|Exemple de labyrinthe généré et résolu. En rouge foncé, l&#039;entrée. En vert, la sortie. En bleu, le chemin entre le départ et l&#039;arrivée. En rouge clair, les cellules visitées lors de la résolution.|alt=&amp;quot;Labyrinthe&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
L&#039;objectif de ce projet est de générer des labyrinthes aussi grands et complexes que possible.&lt;br /&gt;
Nous allons voir comment toujours avoir un chemin entre l&#039;entrée et la sortie, et comment trouver la sortie une fois notre labyrinthe généré.&lt;br /&gt;
&lt;br /&gt;
== Représentation ==&lt;br /&gt;
&lt;br /&gt;
=== Propriétés ===&lt;br /&gt;
&lt;br /&gt;
Tout d&#039;abord, de manière assez informelle, un labyrinthe est une grille de cellules reliées, ou non, entre elles.&lt;br /&gt;
&lt;br /&gt;
Deux cellules sont reliées entre elles par une &#039;&#039;&#039;porte&#039;&#039;&#039;, ou séparées par un &#039;&#039;&#039;mur&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Tout labyrinthe a &#039;&#039;&#039;une entrée&#039;&#039;&#039; et &#039;&#039;&#039;une sortie&#039;&#039;&#039;, et quelle que soit l&#039;entrée ou la sortie, le chemin entre ces deux cellules est &#039;&#039;&#039;unique&#039;&#039;&#039;.&lt;br /&gt;
Nous verrons cependant que ce dernier point peut varier, et introduire de nouvelles formes de labyrinthe.&lt;br /&gt;
&lt;br /&gt;
=== Modélisation en graphe ===&lt;br /&gt;
&lt;br /&gt;
En théorie des graphes, un graphe est un ensemble de &#039;&#039;&#039;points&#039;&#039;&#039; (ou nœuds ou sommets) reliés ensemble par des &#039;&#039;&#039;lignes&#039;&#039;&#039; (ou liens ou arêtes).&lt;br /&gt;
&lt;br /&gt;
[[Fichier:graphe_cyclique.png|vignette|left|300px|Exemple de graphe connexe cyclique non orienté|alt=Graphe cyclique]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Un graphe peut être dit &#039;&#039;&#039;connexe&#039;&#039;&#039; (d&#039;un seul tenant) ou &#039;&#039;&#039;non connexe&#039;&#039;&#039; (en plusieurs morceaux).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Un graphe peut aussi être &#039;&#039;&#039;cyclique&#039;&#039;&#039; s&#039;il existe au moins un chemin formant une boucle ou &#039;&#039;&#039;acyclique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Enfin, un graphe peut être &#039;&#039;&#039;orienté&#039;&#039;&#039; (si les arêtes sont à sens unique) ou &#039;&#039;&#039;non orienté&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Arbre.PNG|vignette|left|300px|Exemple d&#039;arbre|alt=Arbre]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Un &#039;&#039;&#039;arbre&#039;&#039;&#039; est un graphe connexe, acyclique et non orienté.&lt;br /&gt;
&lt;br /&gt;
Chaque feuille n&#039;est connectée qu&#039;à un seul autre nœud, et chaque sommet interne relie au moins deux nœuds.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:labyrinthe_avec_arbre.png|vignette|right|300px|Exemple de labyrinthe avec son arbre. Pour plus de simplicité, à chaque nœud est attribué une position.|alt=Labyrinthe avec arbre]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
En plaçant un sommet sur chaque cellule de notre labyrinthe, et en reliant deux sommets par une arête si leurs cellules sont séparées par une porte, il devient possible de dessiner un arbre à partir de n&#039;importe quel labyrinthe.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Sur notre graphe, un arête est donc un passage dans notre labyrinthe.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Génération ==&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe rectangulaire de largeur &amp;lt;math&amp;gt; L &amp;lt;/math&amp;gt; et de hauteur &amp;lt;math&amp;gt; H &amp;lt;/math&amp;gt; contient exactement &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; portes.&lt;br /&gt;
&lt;br /&gt;
Du point de vue du graphe, il y a donc &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; arêtes.&lt;br /&gt;
&lt;br /&gt;
Maintenant, comment répartir toutes ces portes de manière à ce que toutes les cellules soient accessibles et qu&#039;il n&#039;existe qu&#039;un unique chemin entre l&#039;entrée et la sortie ?&lt;br /&gt;
&lt;br /&gt;
De nombreux algorithmes existent, dont le parcours en profondeur et l&#039;algorithme de Kruskal.&lt;br /&gt;
Chaque algorithme est différent et produit des labyrinthes visuellement différents.&lt;br /&gt;
&lt;br /&gt;
=== Parcours en profondeur ===&lt;br /&gt;
&lt;br /&gt;
[[Fichier:recursive_backtracker.gif|vignette|left|500px|Illustration du parcours en profondeur|alt=Parcours en profondeur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
L&#039;algorithme du parcours en profondeur (ou &amp;quot;recursive backtracker&amp;quot; en anglais) commence sur une cellule aléatoire dans le labyrinthe.&lt;br /&gt;
&lt;br /&gt;
Il suffit ensuite de se diriger dans une direction aléatoire et de casse le mur face à soi, tout en marquant la cellule précédente comme visitée.&lt;br /&gt;
&lt;br /&gt;
Lorsque plus aucune direction n&#039;est disponible, l&#039;algorithme &amp;quot;remonte&amp;quot; à la position précédente : c&#039;est le backtracking.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:pile.png|vignette|300px|Représentation d&#039;une pile de positions|alt=Pile]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Une implémentation possible et pertinente pour sauvegarder l&#039;historique des positions est la &#039;&#039;&#039;pile&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Une pile est une liste dans laquelle seul le dernier élément peut être récupéré.&lt;br /&gt;
&lt;br /&gt;
Une pile est donc principalement composée de 2 méthodes :&lt;br /&gt;
* &amp;lt;code&amp;gt;push : elt -&amp;gt; ∅&amp;lt;/code&amp;gt; : ajoute un élément à la pile&lt;br /&gt;
* &amp;lt;code&amp;gt;pop : ∅ -&amp;gt; elt&amp;lt;/code&amp;gt; : retourne le sommet de notre pile en retirant cet élément&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;implémentation de la pile proposée, une erreur sera levée si la méthode méthode &amp;lt;code&amp;gt;pop&amp;lt;/code&amp;gt; est appelée sur une pile vide.&lt;br /&gt;
&lt;br /&gt;
=== Kruskal ===&lt;br /&gt;
&lt;br /&gt;
[[Fichier:kruskal.gif|vignette|left|500px|Illustration de l&#039;algorithme de Kruskal.|alt=Kruskal]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Alors que le parcours en profondeur s&#039;intéressait aux sommets, l&#039;algorithme de Kruskal s&#039;applique lui sur les arêtes.&lt;br /&gt;
&lt;br /&gt;
Tout d&#039;abord, chaque cellule se voit attributée un identifiant unique, dans un labyrinthe empli de murs.&lt;br /&gt;
&lt;br /&gt;
Un mur aléatoire est ensuite choisi. Si les cellules séparées par ce mur ont des identifiants différents, le même identifiant leur sera associé, et il faudra alors abattre le mur.&lt;br /&gt;
&lt;br /&gt;
Sinon, un autre mur sera choisi.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:union_find.png|vignette|300px|Représentation d&#039;une structure Union-Find avec find(a,b) et find(b,c).|alt=Union-Find]]&lt;br /&gt;
&lt;br /&gt;
Pour mettre en œuvre cet algorithme, la structure la plus adaptée à utiliser est une structure de données appelée &#039;&#039;&#039;Union-Find&#039;&#039;&#039;, qui permet de mettre en relation des éléments partageant un même représentant (ou un même identifiant).&lt;br /&gt;
&lt;br /&gt;
Il existe plusieurs variantes d&#039;Union-Find, dont notamment la compression de chemin, qui permet de n&#039;avoir qu&#039;un ou deux éléments à parcourir pour obtenir le représentant d&#039;un élément.&lt;br /&gt;
&lt;br /&gt;
Union-Find fonctionne comme un arbre. &#039;a&#039; a un représentant &#039;A&#039;, etc..., qui lui même a un représentant &#039;&amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt;&#039;, qui est son propre représentant.&lt;br /&gt;
&lt;br /&gt;
Union-Find est composé de deux méthodes :&lt;br /&gt;
* &amp;lt;code&amp;gt;union : a, b -&amp;gt; ∅&amp;lt;/code&amp;gt; : associe à &#039;a&#039; et &#039;b&#039; le même représentant, par exemple &#039;A&#039; le représentant de &#039;a&#039;&lt;br /&gt;
* &amp;lt;code&amp;gt;find : a -&amp;gt; r&amp;lt;/code&amp;gt; : tant que l&#039;élément n&#039;est pas son propre représentant, &amp;lt;code&amp;gt;find&amp;lt;/code&amp;gt; est appliqué au représentant de l&#039;élément.&amp;lt;br&amp;gt; On commence donc par find(a), puis find(A) (si &#039;A&#039; est le représentant de &#039;a&#039;), etc... La méthode de la compression de chemin permet d&#039;éviter trop de récursivité en écrivant : représentant de &#039;a&#039; = &#039;r&#039;.&lt;br /&gt;
&lt;br /&gt;
Pour les plus curieux, cette structure de données est décrite plus en détails dans un cours d&#039;INFO602 qu&#039;il est possible de retrouver [https://www.lama.univ-savoie.fr/mediawiki/images/f/fa/INFO602-Lesson-3.pdf ici].&lt;br /&gt;
&lt;br /&gt;
=== Labyrinthes cycliques ===&lt;br /&gt;
&lt;br /&gt;
Il est possible, en retirant un certain pourcentage de murs, de créer des labyrinthes cycliques à partir des labyrinthes acycliques générés auparavant.&lt;br /&gt;
&lt;br /&gt;
Cependant, certains algorithmes de résolution n&#039;adopteront pas le même comportement, voire ne fonctionneront même plus du tout.&lt;br /&gt;
&lt;br /&gt;
=== Comparaison ===&lt;br /&gt;
&lt;br /&gt;
Il est possible de comparer un labyrinthe généré avec l&#039;algorithme du parcours en profondeur à un labyrinthe généré avec l&#039;algorithme de Kruskal.&amp;lt;br&amp;gt;&lt;br /&gt;
Alors que ces deux algorithmes n&#039;ont bien tous les deux qu&#039;une unique solution, ils apparaissent néanmoins différents visuellement, et adoptent chacun leur propre structure.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:recursive_backtracker_comparaison.png|vignette|left|500px|Parcours en profondeur. Notons la &amp;quot;netteté&amp;quot; des chemins.|alt=Parcours en profondeur]]&lt;br /&gt;
[[Fichier:kruskal_comparaison.png|vignette|right|500px|Algorithme de Kruskal. Les murs de taille 1 sont bien plus fréquents.|alt=Kruskal]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Résolution ==&lt;br /&gt;
&lt;br /&gt;
Il existe là encore de nombreux algorithmes de résolution de labyrinthes, plus ou moins efficaces, et surtout ne fonctionnant pas tous dans les mêmes conditions.&lt;br /&gt;
&lt;br /&gt;
=== Parcours en profondeur ===&lt;br /&gt;
&lt;br /&gt;
Cet algorithme est quasiment identique à celui du parcours en profondeur pour la génération.&lt;br /&gt;
&lt;br /&gt;
Il est très efficace et trouvera une solution en minimisant le nombre de cases visitées.&lt;br /&gt;
&lt;br /&gt;
Il s&#039;adapte aux labyrinthes cycliques. En cas de boucle, il ne fera pas la boucle vu que l&#039;intersection a déjà été visitées, il reviendra sur ses pas.&lt;br /&gt;
&lt;br /&gt;
Il s&#039;adapte aux labyrinthes sans solution. En effet, s&#039;il n&#039;y a pas de sortie, il va revenir à sa position de départ sans position précédente (pile vide) et en ayant parcouru toutes les cases.&lt;br /&gt;
&lt;br /&gt;
=== Mur droit ===&lt;br /&gt;
&lt;br /&gt;
Cet algorithme va suivre de la main droite le mur de droite.&lt;br /&gt;
&lt;br /&gt;
Il est relativement inefficace, et va visiter un grand nombre de cases.&lt;br /&gt;
&lt;br /&gt;
Il s&#039;adapte assez mal aux labyrinthes cycliques. En effet, si la sortie n&#039;est pas dans la même boucle que l&#039;entrée, il ne la trouvera jamais.&lt;br /&gt;
&lt;br /&gt;
Il ne s&#039;adapte pas aux labyrinthes sans solution, et fera le tour de la grille à l&#039;infini.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:labyrinthe_exp_exhaust.png|vignette|left|500px|Labyrinthe résolu en utilisant le parcours en profondeur. &amp;lt;br&amp;gt; 660 cellules visitées, 1179 déplacements, chemin de 142 cellules.|alt=Parcours en profondeur]]&lt;br /&gt;
[[Fichier:labyrinthe_right_hand.png|vignette|right|500px|Labyrinthe résolu en utilisant le mur droit. &amp;lt;br&amp;gt; 1068 cellules visitées, 1995 déplacements, chemin de 142 cellules.|alt=Mur droit]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
On remarquera que des deux algorithmes, celui du mur droit explorera toutes les cellules situées en dessous du chemin optimal. Il sera donc plus efficace lorsque le chemin de solution est vers le bas de la grille.&lt;br /&gt;
&lt;br /&gt;
== Bilan personnel ==&lt;br /&gt;
&lt;br /&gt;
Ce projet m&#039;a permis de découvrir plusieurs structures de données qui, avec plusieurs années de recul, m&#039;ont réellement été utiles.&lt;br /&gt;
&lt;br /&gt;
J&#039;ai aussi pu me familiariser avec Tkinter, avec la programmation orientée objets en Python (notamment héritage et méthodes statiques) et avec le multithreading, le projet ayant été pensé et codé en parallèle avant d&#039;être entièrement refait plus &amp;quot;monolithique&amp;quot; une semaine avant l&#039;oral.&lt;br /&gt;
&lt;br /&gt;
J&#039;ai aussi pu comprendre la complexité mathématique derrière un labyrinthe, et aborder certains aspects des graphes.&lt;br /&gt;
&lt;br /&gt;
Pour résumer, ce projet a vraiment pris tout son sens en L3, où certains concepts m&#039;ont enfin été expliqués et où j&#039;ai enfin pu avoir le recul nécessaire pour saisir l&#039;essence même de la problématique.&lt;br /&gt;
&lt;br /&gt;
== Code source ==&lt;br /&gt;
 &lt;br /&gt;
Le code source est disponible sur Github à [https://github.com/RomainTHD/Labyrinthe_VISI201 cette adresse]. N&#039;hésitez pas à jeter un œil aux autres projets en cours 😉&lt;br /&gt;
&lt;br /&gt;
Il suffit d&#039;avoir installé Python 3 et Tkinter.&lt;br /&gt;
&lt;br /&gt;
== Sources et liens utiles ==&lt;br /&gt;
&lt;br /&gt;
Génération&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#Fusion_al%C3%A9atoire_de_chemins Kruskal (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Maze_generation_algorithm#Randomized_Kruskal&#039;s_algorithm Kruskal (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#Exploration_exhaustive Parcours en profondeur (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Maze_generation_algorithm#Randomized_Depth-First_Search Parcours en profondeur (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Résolution&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#R%C3%A9solution Résolution générale (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Maze_solving_algorithm#Wall_follower Mur droit (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Structures de données&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Union-find Union-Find / Disjoint-Set (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Stack_(abstract_data_type) Pile / Stack (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Queue_(abstract_data_type) File / Queue (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Python&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://docs.python.org/3.6/reference/datamodel.html Classes et types de variables personnalisés (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [http://effbot.org/tkinterbook/canvas.htm Canvas Tkinter (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;/div&gt;</summary>
		<author><name>Theodet</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=12723</id>
		<title>Génération et résolution de labyrinthes II</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=12723"/>
		<updated>2021-04-09T20:23:27Z</updated>

		<summary type="html">&lt;p&gt;Theodet : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__FORCETOC__[[Fichier:labyrinthe_photo.png|vignette|300px|Exemple de labyrinthe généré et résolu. En rouge foncé, l&#039;entrée. En vert, la sortie. En bleu, le chemin entre le départ et l&#039;arrivée. En rouge clair, les cellules visitées lors de la résolution.|alt=&amp;quot;Labyrinthe&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
L&#039;objectif de ce projet est de générer des labyrinthes aussi grands et complexes que possible.&lt;br /&gt;
Nous allons voir comment toujours avoir un chemin entre l&#039;entrée et la sortie, et comment trouver la sortie une fois notre labyrinthe généré.&lt;br /&gt;
&lt;br /&gt;
== Représentation ==&lt;br /&gt;
&lt;br /&gt;
=== Propriétés ===&lt;br /&gt;
&lt;br /&gt;
Tout d&#039;abord, de manière assez informelle, un labyrinthe est une grille de cellules reliées, ou non, entre elles.&lt;br /&gt;
&lt;br /&gt;
Deux cellules sont reliées entre elles par une &#039;&#039;&#039;porte&#039;&#039;&#039;, ou séparées par un &#039;&#039;&#039;mur&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Tout labyrinthe a &#039;&#039;&#039;une entrée&#039;&#039;&#039; et &#039;&#039;&#039;une sortie&#039;&#039;&#039;, et quelle que soit l&#039;entrée ou la sortie, le chemin entre ces deux cellules est &#039;&#039;&#039;unique&#039;&#039;&#039;.&lt;br /&gt;
Nous verrons cependant que ce dernier point peut varier, et introduire de nouvelles formes de labyrinthe.&lt;br /&gt;
&lt;br /&gt;
=== Modélisation en graphe ===&lt;br /&gt;
&lt;br /&gt;
En théorie des graphes, un graphe est un ensemble de &#039;&#039;&#039;points&#039;&#039;&#039; (ou nœuds ou sommets) reliés ensemble par des &#039;&#039;&#039;lignes&#039;&#039;&#039; (ou liens ou arêtes).&lt;br /&gt;
&lt;br /&gt;
[[Fichier:graphe_cyclique.png|vignette|left|300px|Exemple de graphe connexe cyclique non orienté|alt=Graphe cyclique]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Un graphe peut être dit &#039;&#039;&#039;connexe&#039;&#039;&#039; (d&#039;un seul tenant) ou &#039;&#039;&#039;non connexe&#039;&#039;&#039; (en plusieurs morceaux).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Un graphe peut aussi être &#039;&#039;&#039;cyclique&#039;&#039;&#039; s&#039;il existe au moins un chemin formant une boucle ou &#039;&#039;&#039;acyclique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Enfin, un graphe peut être &#039;&#039;&#039;orienté&#039;&#039;&#039; (si les arêtes sont à sens unique) ou &#039;&#039;&#039;non orienté&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Arbre.PNG|vignette|left|300px|Exemple d&#039;arbre|alt=Arbre]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Un &#039;&#039;&#039;arbre&#039;&#039;&#039; est un graphe connexe, acyclique et non orienté.&lt;br /&gt;
&lt;br /&gt;
Chaque feuille n&#039;est connectée qu&#039;à un seul autre nœud, et chaque sommet interne relie au moins deux nœuds.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:labyrinthe_avec_arbre.png|vignette|right|300px|Exemple de labyrinthe avec son arbre. Pour plus de simplicité, à chaque nœud est attribué une position.|alt=Labyrinthe avec arbre]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
En plaçant un sommet sur chaque cellule de notre labyrinthe, et en reliant deux sommets par une arête si leurs cellules sont séparées par une porte, il devient possible de dessiner un arbre à partir de n&#039;importe quel labyrinthe.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Sur notre graphe, un arête est donc un passage dans notre labyrinthe.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Génération ==&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe rectangulaire de largeur &amp;lt;math&amp;gt; L &amp;lt;/math&amp;gt; et de hauteur &amp;lt;math&amp;gt; H &amp;lt;/math&amp;gt; contient exactement &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; portes.&lt;br /&gt;
&lt;br /&gt;
Du point de vue du graphe, il y a donc &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; arêtes.&lt;br /&gt;
&lt;br /&gt;
Maintenant, comment répartir toutes ces portes de manière à ce que toutes les cellules soient accessibles et qu&#039;il n&#039;existe qu&#039;un unique chemin entre l&#039;entrée et la sortie ?&lt;br /&gt;
&lt;br /&gt;
De nombreux algorithmes existent, dont le parcours en profondeur et l&#039;algorithme de Kruskal.&lt;br /&gt;
Chaque algorithme est différent et produit des labyrinthes visuellement différents.&lt;br /&gt;
&lt;br /&gt;
=== Parcours en profondeur ===&lt;br /&gt;
&lt;br /&gt;
[[Fichier:recursive_backtracker.gif|vignette|left|500px|Illustration du parcours en profondeur|alt=Parcours en profondeur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
L&#039;algorithme du parcours en profondeur (ou &amp;quot;recursive backtracker&amp;quot; en anglais) commence sur une cellule aléatoire dans le labyrinthe.&lt;br /&gt;
&lt;br /&gt;
Il suffit ensuite de se diriger dans une direction aléatoire et de casse le mur face à soi, tout en marquant la cellule précédente comme visitée.&lt;br /&gt;
&lt;br /&gt;
Lorsque plus aucune direction n&#039;est disponible, l&#039;algorithme &amp;quot;remonte&amp;quot; à la position précédente : c&#039;est le backtracking.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:pile.png|vignette|300px|Représentation d&#039;une pile de positions|alt=Pile]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Une implémentation possible et pertinente pour sauvegarder l&#039;historique des positions est la &#039;&#039;&#039;pile&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Une pile est une liste dans laquelle seul le dernier élément peut être récupéré.&lt;br /&gt;
&lt;br /&gt;
Une pile est donc principalement composée de 2 méthodes :&lt;br /&gt;
* &amp;lt;code&amp;gt;push : elt -&amp;gt; ∅&amp;lt;/code&amp;gt; : ajoute un élément à la pile&lt;br /&gt;
* &amp;lt;code&amp;gt;pop : ∅ -&amp;gt; elt&amp;lt;/code&amp;gt; : retourne le sommet de notre pile en retirant cet élément&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;implémentation de la pile proposée, une erreur sera levée si la méthode méthode &amp;lt;code&amp;gt;pop&amp;lt;/code&amp;gt; est appelée sur une pile vide.&lt;br /&gt;
&lt;br /&gt;
=== Kruskal ===&lt;br /&gt;
&lt;br /&gt;
[[Fichier:kruskal.gif|vignette|left|500px|Illustration de l&#039;algorithme de Kruskal.|alt=Kruskal]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Alors que le parcours en profondeur s&#039;intéressait aux sommets, l&#039;algorithme de Kruskal s&#039;applique lui sur les arêtes.&lt;br /&gt;
&lt;br /&gt;
Tout d&#039;abord, chaque cellule se voit attributée un identifiant unique, dans un labyrinthe empli de murs.&lt;br /&gt;
&lt;br /&gt;
Un mur aléatoire est ensuite choisi. Si les cellules séparées par ce mur ont des identifiants différents, le même identifiant leur sera associé, et il faudra alors abattre le mur.&lt;br /&gt;
&lt;br /&gt;
Sinon, un autre mur sera choisi.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:union_find.png|vignette|300px|Représentation d&#039;une structure Union-Find avec find(a,b) et find(b,c).|alt=Union-Find]]&lt;br /&gt;
&lt;br /&gt;
Pour mettre en œuvre cet algorithme, la structure la plus adaptée à utiliser est une structure de données appelée &#039;&#039;&#039;Union-Find&#039;&#039;&#039;, qui permet de mettre en relation des éléments partageant un même représentant (ou un même identifiant).&lt;br /&gt;
&lt;br /&gt;
Il existe plusieurs variantes d&#039;Union-Find, dont notamment la compression de chemin, qui permet de n&#039;avoir qu&#039;un ou deux éléments à parcourir pour obtenir le représentant d&#039;un élément.&lt;br /&gt;
&lt;br /&gt;
Union-Find fonctionne comme un arbre. &#039;a&#039; a un représentant &#039;A&#039;, etc..., qui lui même a un représentant &#039;&amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt;&#039;, qui est son propre représentant.&lt;br /&gt;
&lt;br /&gt;
Union-Find est composé de deux méthodes :&lt;br /&gt;
* &amp;lt;code&amp;gt;union : a, b -&amp;gt; ∅&amp;lt;/code&amp;gt; : associe à &#039;a&#039; et &#039;b&#039; le même représentant, par exemple &#039;A&#039; le représentant de &#039;a&#039;&lt;br /&gt;
* &amp;lt;code&amp;gt;find : a -&amp;gt; r&amp;lt;/code&amp;gt; : tant que l&#039;élément n&#039;est pas son propre représentant, &amp;lt;code&amp;gt;find&amp;lt;/code&amp;gt; est appliqué au représentant de l&#039;élément.&amp;lt;br&amp;gt; On commence donc par find(a), puis find(A) (si &#039;A&#039; est le représentant de &#039;a&#039;), etc... La méthode de la compression de chemin permet d&#039;éviter trop de récursivité en écrivant : représentant de &#039;a&#039; = &#039;r&#039;.&lt;br /&gt;
&lt;br /&gt;
Pour les plus curieux, cette structure de données est décrite plus en détails dans un cours d&#039;INFO602 qu&#039;il est possible de retrouver [https://www.lama.univ-savoie.fr/mediawiki/images/f/fa/INFO602-Lesson-3.pdf ici].&lt;br /&gt;
&lt;br /&gt;
=== Labyrinthes cycliques ===&lt;br /&gt;
&lt;br /&gt;
Il est possible, en retirant un certain pourcentage de murs, de créer des labyrinthes cycliques à partir des labyrinthes acycliques générés auparavant.&lt;br /&gt;
&lt;br /&gt;
Cependant, certains algorithmes de résolution n&#039;adopteront pas le même comportement, voire ne fonctionneront même plus du tout.&lt;br /&gt;
&lt;br /&gt;
=== Comparaison ===&lt;br /&gt;
&lt;br /&gt;
Il est possible de comparer un labyrinthe généré avec l&#039;algorithme du parcours en profondeur à un labyrinthe généré avec l&#039;algorithme de Kruskal.&amp;lt;br&amp;gt;&lt;br /&gt;
Alors que ces deux algorithmes n&#039;ont bien tous les deux qu&#039;une unique solution, ils apparaissent néanmoins différents visuellement, et adoptent chacun leur propre structure.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:recursive_backtracker_comparaison.png|vignette|left|500px|Parcours en profondeur. Notons la &amp;quot;netteté&amp;quot; des chemins.|alt=Parcours en profondeur]]&lt;br /&gt;
[[Fichier:kruskal_comparaison.png|vignette|right|500px|Algorithme de Kruskal. Les murs de taille 1 sont bien plus fréquents.|alt=Kruskal]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Résolution ==&lt;br /&gt;
&lt;br /&gt;
Il existe là encore de nombreux algorithmes de résolution de labyrinthes, plus ou moins efficaces, et surtout ne fonctionnant pas tous dans les mêmes conditions.&lt;br /&gt;
&lt;br /&gt;
=== Parcours en profondeur ===&lt;br /&gt;
&lt;br /&gt;
Cet algorithme est quasiment identique à celui du parcours en profondeur pour la génération.&lt;br /&gt;
&lt;br /&gt;
Il est très efficace et trouvera une solution en minimisant le nombre de cases visitées.&lt;br /&gt;
&lt;br /&gt;
Il s&#039;adapte aux labyrinthes cycliques. En cas de boucle, il ne fera pas la boucle vu que l&#039;intersection a déjà été visitées, il reviendra sur ses pas.&lt;br /&gt;
&lt;br /&gt;
Il s&#039;adapte aux labyrinthes sans solution. En effet, s&#039;il n&#039;y a pas de sortie, il va revenir à sa position de départ sans position précédente (pile vide) et en ayant parcouru toutes les cases.&lt;br /&gt;
&lt;br /&gt;
=== Mur droit ===&lt;br /&gt;
&lt;br /&gt;
Cet algorithme va suivre de la main droite le mur de droite.&lt;br /&gt;
&lt;br /&gt;
Il est relativement inefficace, et va visiter un grand nombre de cases.&lt;br /&gt;
&lt;br /&gt;
Il s&#039;adapte assez mal aux labyrinthes cycliques. En effet, si la sortie n&#039;est pas dans la même boucle que l&#039;entrée, il ne la trouvera jamais.&lt;br /&gt;
&lt;br /&gt;
Il ne s&#039;adapte pas aux labyrinthes sans solution, et fera le tour de la grille à l&#039;infini.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:labyrinthe_exp_exhaust.png|vignette|left|500px|Labyrinthe résolu en utilisant le parcours en profondeur. &amp;lt;br&amp;gt; 660 cellules visitées, 1179 déplacements, chemin de 142 cellules.|alt=Parcours en profondeur]]&lt;br /&gt;
[[Fichier:labyrinthe_right_hand.png|vignette|right|500px|Labyrinthe résolu en utilisant le mur droit. &amp;lt;br&amp;gt; 1068 cellules visitées, 1995 déplacements, chemin de 142 cellules.|alt=Mur droit]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
On remarquera que des deux algorithmes, celui du mur droit explorera toutes les cellules situées en dessous du chemin optimal. Il sera donc plus efficace lorsque le chemin de solution est vers le bas de la grille.&lt;br /&gt;
&lt;br /&gt;
== Bilan personnel ==&lt;br /&gt;
&lt;br /&gt;
Ce projet m&#039;a permis de découvrir plusieurs structures de données qui, avec plusieurs années de recul, m&#039;ont réellement été utiles.&lt;br /&gt;
&lt;br /&gt;
J&#039;ai aussi pu me familiariser avec Tkinter, avec la programmation orientée objets en Python (notamment héritage et méthodes statiques) et avec le multithreading, le projet ayant été pensé et codé en parallèle avant d&#039;être entièrement refait plus &amp;quot;monolithique&amp;quot; une semaine avant l&#039;oral.&lt;br /&gt;
&lt;br /&gt;
J&#039;ai aussi pu comprendre la complexité mathématique derrière un labyrinthe, et aborder certains aspects des graphes.&lt;br /&gt;
&lt;br /&gt;
Pour résumer, ce projet a vraiment pris tout son sens en L3, où certains concepts m&#039;ont enfin été expliqués et où j&#039;ai enfin pu avoir le recul nécessaire pour saisir l&#039;essence même de la problématique.&lt;br /&gt;
&lt;br /&gt;
== Code source ==&lt;br /&gt;
 &lt;br /&gt;
Le code source est disponible sur Github à [https://github.com/Rominos111/Labyrinthe_VISI201 cette adresse]. N&#039;hésitez pas à jeter un œil aux autres projets en cours 😉&lt;br /&gt;
&lt;br /&gt;
Il suffit d&#039;avoir installé Python 3 et Tkinter.&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
&lt;br /&gt;
Génération&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#Fusion_al%C3%A9atoire_de_chemins Kruskal (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Maze_generation_algorithm#Randomized_Kruskal&#039;s_algorithm Kruskal (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#Exploration_exhaustive Parcours en profondeur (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Maze_generation_algorithm#Randomized_Depth-First_Search Parcours en profondeur (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Résolution&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#R%C3%A9solution Résolution générale (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Maze_solving_algorithm#Wall_follower Mur droit (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Structures de données&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Union-find Union-Find / Disjoint-Set (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Stack_(abstract_data_type) Pile / Stack (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Queue_(abstract_data_type) File / Queue (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Python&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://docs.python.org/3.6/reference/datamodel.html Classes et types de variables personnalisés (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [http://effbot.org/tkinterbook/canvas.htm Canvas Tkinter (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;/div&gt;</summary>
		<author><name>Theodet</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11879</id>
		<title>Génération et résolution de labyrinthes II</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11879"/>
		<updated>2019-05-22T17:33:02Z</updated>

		<summary type="html">&lt;p&gt;Theodet : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__FORCETOC__[[Fichier:labyrinthe_photo.png|vignette|300px|Exemple de labyrinthe généré et résolu. En rouge foncé, l&#039;entrée. En vert, la sortie. En bleu, le chemin entre le départ et l&#039;arrivée. En rouge clair, les cellules visitées lors de la résolution.|alt=&amp;quot;Labyrinthe&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
L&#039;objectif de ce projet est de générer des labyrinthes aussi grands et complexes que possible. Nous allons voir comment toujours avoir un chemin entre l&#039;entrée et la sortie, et comment trouver la sortie une fois notre labyrinthe généré.&lt;br /&gt;
&lt;br /&gt;
== Représentation ==&lt;br /&gt;
&lt;br /&gt;
=== Propriétés ===&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe est une grille de cellules reliées, ou non, entre elles.&lt;br /&gt;
&lt;br /&gt;
Deux cellules sont reliées entre elles par une &#039;&#039;&#039;porte&#039;&#039;&#039;, ou séparées par un &#039;&#039;&#039;mur&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Tout labyrinthe a &#039;&#039;&#039;une entrée&#039;&#039;&#039; et &#039;&#039;&#039;une sortie&#039;&#039;&#039;, et quelle que soit l&#039;entrée ou la sortie, le chemin entre ces deux cellules est &#039;&#039;&#039;unique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Modélisation en graphe ===&lt;br /&gt;
&lt;br /&gt;
En théorie des graphes, un graphe est un ensemble de &#039;&#039;&#039;points&#039;&#039;&#039; (ou nœuds ou sommets) reliés ensemble par des &#039;&#039;&#039;lignes&#039;&#039;&#039; (ou liens ou arêtes).&lt;br /&gt;
&lt;br /&gt;
[[Fichier:graphe_cyclique.png|vignette|left|300px|Exemple de graphe connexe cyclique non orienté|alt=Graphe cyclique]]&lt;br /&gt;
&lt;br /&gt;
Un graphe peut être &#039;&#039;&#039;connexe&#039;&#039;&#039; (en un seul morceau) ou &#039;&#039;&#039;non connexe&#039;&#039;&#039; (en plusieurs morceaux).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Un graphe peut aussi être &#039;&#039;&#039;cyclique&#039;&#039;&#039; si les points sont reliés en formant une boucle ou &#039;&#039;&#039;acyclique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Enfin, un graphe peut être &#039;&#039;&#039;orienté&#039;&#039;&#039; (si les arêtes sont à sens unique) ou &#039;&#039;&#039;non orienté&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Arbre.PNG|vignette|left|300px|Exemple d&#039;arbre|alt=Arbre]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Un &#039;&#039;&#039;arbre&#039;&#039;&#039; est un graphe connexe, acyclique et non orienté.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
En plaçant un point sur chaque cellule de notre labyrinthe, et en reliant deux cellules séparées par une porte, on peut dessiner un arbre à partir de n&#039;importe quel labyrinthe.&lt;br /&gt;
&lt;br /&gt;
Sur notre graphe, un arête est donc un passage dans notre labyrinthe.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:labyrinthe_avec_arbre.png|vignette|centre|300px|Exemple de labyrinthe avec son arbre. Pour plus de simplicité, on attribue à chaque nœud une position.|alt=Labyrinthe avec arbre]]&lt;br /&gt;
&lt;br /&gt;
== Génération ==&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe rectangulaire de largeur &amp;lt;math&amp;gt; L &amp;lt;/math&amp;gt; et de hauteur &amp;lt;math&amp;gt; H &amp;lt;/math&amp;gt; contient exactement &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; portes.&lt;br /&gt;
&lt;br /&gt;
Du point de vue du graphe, il y a donc &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; arêtes.&lt;br /&gt;
&lt;br /&gt;
Maintenant, comment répartir toutes ces portes de façon à ce que toutes les cellules soient accessibles et qu&#039;il n&#039;existe qu&#039;un unique chemin entre l&#039;entrée et la sortie ?&lt;br /&gt;
&lt;br /&gt;
De nombreux algorithmes existent, dont le parcours en profondeur et l&#039;algorithme de Kruskal.&lt;br /&gt;
Chaque algorithme est différent et produit des labyrinthes visuellement différents.&lt;br /&gt;
&lt;br /&gt;
=== Parcours en profondeur ===&lt;br /&gt;
&lt;br /&gt;
[[Fichier:recursive_backtracker.gif|vignette|left|500px|Illustration du parcours en profondeur|alt=Parcours en profondeur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;algorithme du parcours en profondeur (&amp;quot;recursive backtracker&amp;quot; en anglais), on commence sur une cellule aléatoire dans le labyrinthe.&lt;br /&gt;
&lt;br /&gt;
On se dirige dans une direction aléatoire et on casse le mur en face, tout en marquant la cellule précédente comme visitée.&lt;br /&gt;
&lt;br /&gt;
Lorsque aucune direction n&#039;est disponible, on remonte à la position précédente.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:pile.png|vignette|300px|Représentation d&#039;une pile de positions|alt=Pile]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pour sauvegarder l&#039;historique des positions, on peut utiliser une &#039;&#039;&#039;pile&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Une pile est une liste dans laquelle seul le dernier élément peut être récupéré.&lt;br /&gt;
&lt;br /&gt;
Une pile contient 2 méthodes :&lt;br /&gt;
* push(elem) : ajoute elem à la pile&lt;br /&gt;
* pop() -&amp;gt; elem : retourne le dernier élément de la pile (elem dans notre cas)&lt;br /&gt;
&lt;br /&gt;
Dans mon implémentation de la pile, une erreur est levée si l&#039;on appelle la méthode pop sur une pile vide.&lt;br /&gt;
&lt;br /&gt;
=== Kruskal ===&lt;br /&gt;
&lt;br /&gt;
[[Fichier:kruskal.gif|vignette|left|500px|Illustration de l&#039;algorithme de Kruskal.|alt=Kruskal]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Alors que pour le parcours en profondeur on partait des cellules, l&#039;algorithme de Kruskal s&#039;applique sur des murs.&lt;br /&gt;
&lt;br /&gt;
On attribue à chaque cellule un identifiant unique.&lt;br /&gt;
&lt;br /&gt;
On choisit un mur aléatoire. Si les cellules séparées par ce mur ont des identifiants différents, on leur associe le même identifiant et on casse le mur.&lt;br /&gt;
&lt;br /&gt;
Sinon, on passe à un autre mur.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:union_find.png|vignette|300px|Représentation d&#039;une structure Union-Find avec find(a,b) et find(b,c).|alt=Union-Find]]&lt;br /&gt;
&lt;br /&gt;
Pour mettre en œuvre cet algorithme, on utilise une structure de données appelée &#039;&#039;&#039;Union-Find&#039;&#039;&#039;, qui permet de mettre en relation des éléments partageant un même représentant (ou un même identifiant).&lt;br /&gt;
&lt;br /&gt;
Il existe plusieurs variantes d&#039;Union-Find, dont notamment la compression de chemin, qui permet de n&#039;avoir qu&#039;un ou deux éléments à parcourir pour obtenir le représentant d&#039;un élément.&lt;br /&gt;
&lt;br /&gt;
Union-Find fonctionne comme un arbre. &#039;a&#039; a un représentant &#039;A&#039;, etc..., qui lui même a un représentant &#039;&amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt;&#039;, qui est son propre représentant.&lt;br /&gt;
&lt;br /&gt;
Union-Find est composé de deux méthodes :&lt;br /&gt;
* union(a, b) : associe à &#039;a&#039; et &#039;b&#039; le même représentant, par exemple &#039;A&#039; le représentant de &#039;a&#039;&lt;br /&gt;
* find(a) -&amp;gt; &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; : tant que l&#039;élément n&#039;est pas son propre représentant, on applique find au représentant de l&#039;élément.&amp;lt;br&amp;gt; On commence donc par find(a), puis find(A) (si &#039;A&#039; est le représentant de &#039;a&#039;), etc... La méthode de la compression de chemin permet d&#039;éviter trop de récursivité en écrivant : représentant de &#039;a&#039; = &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Labyrinthes cycliques ===&lt;br /&gt;
&lt;br /&gt;
Il est possible, en retirant un certain pourcentage de murs, de créer des labyrinthes cycliques à partir des labyrinthes acycliques générés auparavant.&lt;br /&gt;
&lt;br /&gt;
Cependant, certains algorithmes de résolution n&#039;adopteront pas le même comportement.&lt;br /&gt;
&lt;br /&gt;
=== Comparaison ===&lt;br /&gt;
&lt;br /&gt;
Si nous comparons un labyrinthe généré avec l&#039;algorithme du parcours en profondeur à un labyrinthe généré avec l&#039;algorithme de Kruskal, bien qu&#039;ils aient tous les deux une solution unique, ils apparaissent néanmoins différents visuellement.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:recursive_backtracker_comparaison.png|vignette|left|500px|Parcours en profondeur.&amp;lt;br&amp;gt;On remarque des chemins proprement dessinés.|alt=Parcours en profondeur]]&lt;br /&gt;
[[Fichier:kruskal_comparaison.png|vignette|right|500px|Algorithme de Kruskal.&amp;lt;br&amp;gt;On remarque des murs de 1 de longueur çà et là.|alt=Kruskal]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Résolution ==&lt;br /&gt;
&lt;br /&gt;
Il existe là encore de nombreux algorithmes de résolution de labyrinthes, plus ou moins efficaces, et surtout ne fonctionnant pas tous dans les mêmes conditions.&lt;br /&gt;
&lt;br /&gt;
=== Parcours en profondeur ===&lt;br /&gt;
&lt;br /&gt;
Cet algorithme est quasiment identique à celui du parcours en profondeur pour la génération.&lt;br /&gt;
&lt;br /&gt;
Il est très efficace et trouvera une solution en minimisant le nombre de cases visitées.&lt;br /&gt;
&lt;br /&gt;
Il s&#039;adapte aux labyrinthes cycliques. En cas de boucle, il ne fera pas la boucle vu que l&#039;intersection a déjà été visitées, il reviendra sur ses pas.&lt;br /&gt;
&lt;br /&gt;
Il s&#039;adapte aux labyrinthes sans solution. En effet, s&#039;il n&#039;y a pas de sortie, il va revenir à sa position de départ sans position précédente (pile vide) et en ayant parcouru toutes les cases.&lt;br /&gt;
&lt;br /&gt;
=== Mur droit ===&lt;br /&gt;
&lt;br /&gt;
Cet algorithme va suivre de la main droite le mur de droite.&lt;br /&gt;
&lt;br /&gt;
Il est relativement inefficace, et va visiter un grand nombre de cases.&lt;br /&gt;
&lt;br /&gt;
Il s&#039;adapte assez mal aux labyrinthes cycliques. En effet, si la sortie n&#039;est pas dans la même boucle que l&#039;entrée, il ne la trouvera jamais.&lt;br /&gt;
&lt;br /&gt;
Il ne s&#039;adapte pas aux labyrinthes sans solution, et fera le tour de la grille à l&#039;infini.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:labyrinthe_exp_exhaust.png|vignette|left|500px|Labyrinthe résolu en utilisant le parcours en profondeur. &amp;lt;br&amp;gt; 660 cellules visitées, 1179 déplacements, chemin de 142 cellules.|alt=Parcours en profondeur]]&lt;br /&gt;
[[Fichier:labyrinthe_right_hand.png|vignette|right|500px|Labyrinthe résolu en utilisant le mur droit. &amp;lt;br&amp;gt; 1068 cellules visitées, 1995 déplacements, chemin de 142 cellules.|alt=Mur droit]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
On remarquera que des deux algorithmes, celui du mur droit explorera toutes les cellules situées en dessous du chemin optimal. Il sera donc plus efficace lorsque le chemin de solution est vers le bas de la grille.&lt;br /&gt;
&lt;br /&gt;
== Bilan personnel ==&lt;br /&gt;
&lt;br /&gt;
Ce projet m&#039;a permis de découvrir plusieurs structures de données qui me seront utiles à l&#039;avenir.&lt;br /&gt;
&lt;br /&gt;
J&#039;ai aussi pu me familiariser avec tkinter, avec la programmation orientée objets en Python (notamment héritage et méthodes statiques) et avec le multithreading (j&#039;avais codé mon projet en programmation parallèle avant de le refaire entièrement un un seul thread une semaine avant l&#039;oral).&lt;br /&gt;
&lt;br /&gt;
J&#039;ai aussi pu comprendre la complexité mathématique derrière un labyrinthe.&lt;br /&gt;
&lt;br /&gt;
== Code source ==&lt;br /&gt;
&lt;br /&gt;
Mon projet total contenant plusieurs milliers de lignes de code réparties dans une dizaine de fichiers, je ne peux évidemment pas l&#039;insérer directement dans cette page.&lt;br /&gt;
&lt;br /&gt;
Le code source est disponible sur Github à [https://github.com/Rominos111/Labyrinthe_VISI201 cette adresse]&lt;br /&gt;
&lt;br /&gt;
Il suffit d&#039;avoir installé Python 3 et tkinter.&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
&lt;br /&gt;
Génération&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#Fusion_al%C3%A9atoire_de_chemins Kruskal (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Maze_generation_algorithm#Randomized_Kruskal&#039;s_algorithm Kruskal (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#Exploration_exhaustive Parcours en profondeur (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Maze_generation_algorithm#Randomized_Depth-First_Search Parcours en profondeur (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Résolution&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#R%C3%A9solution Résolution générale (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Maze_solving_algorithm#Wall_follower Mur droit (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Structures de données&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Union-find Union-Find / Disjoint-Set (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Stack_(abstract_data_type) Pile / Stack (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Queue_(abstract_data_type) File / Queue (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Python&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://docs.python.org/3.6/reference/datamodel.html Classes et types de variables personnalisés (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [http://effbot.org/tkinterbook/canvas.htm Canvas Tkinter (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;/div&gt;</summary>
		<author><name>Theodet</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11878</id>
		<title>Génération et résolution de labyrinthes II</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11878"/>
		<updated>2019-05-22T17:30:06Z</updated>

		<summary type="html">&lt;p&gt;Theodet : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__FORCETOC__[[Fichier:labyrinthe_photo.png|vignette|300px|Exemple de labyrinthe généré et résolu. En rouge foncé, l&#039;entrée. En vert, la sortie. En bleu, le chemin entre le départ et l&#039;arrivée. En rouge clair, les cellules visitées lors de la résolution.|alt=&amp;quot;Labyrinthe&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
On veut générer des labyrinthes aussi grands et complexes que possible, avec des murs dans une grille carré. Comment faire pour qu&#039;il y ait toujours un chemin de l&#039;entrée à la sortie ? Comment faire pour qu&#039;il n&#039;y ait qu&#039;un chemin ? Et comment trouver la sortie quand on est perdu dans le labyrinthe ?&lt;br /&gt;
&lt;br /&gt;
== Représentation ==&lt;br /&gt;
&lt;br /&gt;
=== Propriétés ===&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe est une grille de cellules reliées, ou non, entre elles.&lt;br /&gt;
&lt;br /&gt;
Deux cellules sont reliées entre elles par une &#039;&#039;&#039;porte&#039;&#039;&#039;, ou séparées par un &#039;&#039;&#039;mur&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Tout labyrinthe a &#039;&#039;&#039;une entrée&#039;&#039;&#039; et &#039;&#039;&#039;une sortie&#039;&#039;&#039;, et quelle que soit l&#039;entrée ou la sortie, le chemin entre ces deux cellules est &#039;&#039;&#039;unique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Modélisation en graphe ===&lt;br /&gt;
&lt;br /&gt;
En théorie des graphes, un graphe est un ensemble de &#039;&#039;&#039;points&#039;&#039;&#039; (ou nœuds ou sommets) reliés ensemble par des &#039;&#039;&#039;lignes&#039;&#039;&#039; (ou liens ou arêtes).&lt;br /&gt;
&lt;br /&gt;
[[Fichier:graphe_cyclique.png|vignette|left|300px|Exemple de graphe connexe cyclique non orienté|alt=Graphe cyclique]]&lt;br /&gt;
&lt;br /&gt;
Un graphe peut être &#039;&#039;&#039;connexe&#039;&#039;&#039; (en un seul morceau) ou &#039;&#039;&#039;non connexe&#039;&#039;&#039; (en plusieurs morceaux).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Un graphe peut aussi être &#039;&#039;&#039;cyclique&#039;&#039;&#039; si les points sont reliés en formant une boucle ou &#039;&#039;&#039;acyclique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Enfin, un graphe peut être &#039;&#039;&#039;orienté&#039;&#039;&#039; (si les arêtes sont à sens unique) ou &#039;&#039;&#039;non orienté&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Arbre.PNG|vignette|left|300px|Exemple d&#039;arbre|alt=Arbre]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Un &#039;&#039;&#039;arbre&#039;&#039;&#039; est un graphe connexe, acyclique et non orienté.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
En plaçant un point sur chaque cellule de notre labyrinthe, et en reliant deux cellules séparées par une porte, on peut dessiner un arbre à partir de n&#039;importe quel labyrinthe.&lt;br /&gt;
&lt;br /&gt;
Sur notre graphe, un arête est donc un passage dans notre labyrinthe.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:labyrinthe_avec_arbre.png|vignette|centre|300px|Exemple de labyrinthe avec son arbre. Pour plus de simplicité, on attribue à chaque nœud une position.|alt=Labyrinthe avec arbre]]&lt;br /&gt;
&lt;br /&gt;
== Génération ==&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe rectangulaire de largeur &amp;lt;math&amp;gt; L &amp;lt;/math&amp;gt; et de hauteur &amp;lt;math&amp;gt; H &amp;lt;/math&amp;gt; contient exactement &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; portes.&lt;br /&gt;
&lt;br /&gt;
Du point de vue du graphe, il y a donc &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; arêtes.&lt;br /&gt;
&lt;br /&gt;
Maintenant, comment répartir toutes ces portes de façon à ce que toutes les cellules soient accessibles et qu&#039;il n&#039;existe qu&#039;un unique chemin entre l&#039;entrée et la sortie ?&lt;br /&gt;
&lt;br /&gt;
De nombreux algorithmes existent, dont le parcours en profondeur et l&#039;algorithme de Kruskal.&lt;br /&gt;
Chaque algorithme est différent et produit des labyrinthes visuellement différents.&lt;br /&gt;
&lt;br /&gt;
=== Parcours en profondeur ===&lt;br /&gt;
&lt;br /&gt;
[[Fichier:recursive_backtracker.gif|vignette|left|500px|Illustration du parcours en profondeur|alt=Parcours en profondeur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;algorithme du parcours en profondeur (&amp;quot;recursive backtracker&amp;quot; en anglais), on commence sur une cellule aléatoire dans le labyrinthe.&lt;br /&gt;
&lt;br /&gt;
On se dirige dans une direction aléatoire et on casse le mur en face, tout en marquant la cellule précédente comme visitée.&lt;br /&gt;
&lt;br /&gt;
Lorsque aucune direction n&#039;est disponible, on remonte à la position précédente.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:pile.png|vignette|300px|Représentation d&#039;une pile de positions|alt=Pile]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pour sauvegarder l&#039;historique des positions, on peut utiliser une &#039;&#039;&#039;pile&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Une pile est une liste dans laquelle seul le dernier élément peut être récupéré.&lt;br /&gt;
&lt;br /&gt;
Une pile contient 2 méthodes :&lt;br /&gt;
* push(elem) : ajoute elem à la pile&lt;br /&gt;
* pop() -&amp;gt; elem : retourne le dernier élément de la pile (elem dans notre cas)&lt;br /&gt;
&lt;br /&gt;
Dans mon implémentation de la pile, une erreur est levée si l&#039;on appelle la méthode pop sur une pile vide.&lt;br /&gt;
&lt;br /&gt;
=== Kruskal ===&lt;br /&gt;
&lt;br /&gt;
[[Fichier:kruskal.gif|vignette|left|500px|Illustration de l&#039;algorithme de Kruskal.|alt=Kruskal]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Alors que pour le parcours en profondeur on partait des cellules, l&#039;algorithme de Kruskal s&#039;applique sur des murs.&lt;br /&gt;
&lt;br /&gt;
On attribue à chaque cellule un identifiant unique.&lt;br /&gt;
&lt;br /&gt;
On choisit un mur aléatoire. Si les cellules séparées par ce mur ont des identifiants différents, on leur associe le même identifiant et on casse le mur.&lt;br /&gt;
&lt;br /&gt;
Sinon, on passe à un autre mur.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:union_find.png|vignette|300px|Représentation d&#039;une structure Union-Find avec find(a,b) et find(b,c).|alt=Union-Find]]&lt;br /&gt;
&lt;br /&gt;
Pour mettre en œuvre cet algorithme, on utilise une structure de données appelée &#039;&#039;&#039;Union-Find&#039;&#039;&#039;, qui permet de mettre en relation des éléments partageant un même représentant (ou un même identifiant).&lt;br /&gt;
&lt;br /&gt;
Il existe plusieurs variantes d&#039;Union-Find, dont notamment la compression de chemin, qui permet de n&#039;avoir qu&#039;un ou deux éléments à parcourir pour obtenir le représentant d&#039;un élément.&lt;br /&gt;
&lt;br /&gt;
Union-Find fonctionne comme un arbre. &#039;a&#039; a un représentant &#039;A&#039;, etc..., qui lui même a un représentant &#039;&amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt;&#039;, qui est son propre représentant.&lt;br /&gt;
&lt;br /&gt;
Union-Find est composé de deux méthodes :&lt;br /&gt;
* union(a, b) : associe à &#039;a&#039; et &#039;b&#039; le même représentant, par exemple &#039;A&#039; le représentant de &#039;a&#039;&lt;br /&gt;
* find(a) -&amp;gt; &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; : tant que l&#039;élément n&#039;est pas son propre représentant, on applique find au représentant de l&#039;élément.&amp;lt;br&amp;gt; On commence donc par find(a), puis find(A) (si &#039;A&#039; est le représentant de &#039;a&#039;), etc... La méthode de la compression de chemin permet d&#039;éviter trop de récursivité en écrivant : représentant de &#039;a&#039; = &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Labyrinthes cycliques ===&lt;br /&gt;
&lt;br /&gt;
Il est possible, en retirant un certain pourcentage de murs, de créer des labyrinthes cycliques à partir des labyrinthes acycliques générés auparavant.&lt;br /&gt;
&lt;br /&gt;
Cependant, certains algorithmes de résolution n&#039;adopteront pas le même comportement.&lt;br /&gt;
&lt;br /&gt;
=== Comparaison ===&lt;br /&gt;
&lt;br /&gt;
Si nous comparons un labyrinthe généré avec l&#039;algorithme du parcours en profondeur à un labyrinthe généré avec l&#039;algorithme de Kruskal, bien qu&#039;ils aient tous les deux une solution unique, ils apparaissent néanmoins différents visuellement.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:recursive_backtracker_comparaison.png|vignette|left|500px|Parcours en profondeur.&amp;lt;br&amp;gt;On remarque des chemins proprement dessinés.|alt=Parcours en profondeur]]&lt;br /&gt;
[[Fichier:kruskal_comparaison.png|vignette|right|500px|Algorithme de Kruskal.&amp;lt;br&amp;gt;On remarque des murs de 1 de longueur çà et là.|alt=Kruskal]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Résolution ==&lt;br /&gt;
&lt;br /&gt;
Il existe là encore de nombreux algorithmes de résolution de labyrinthes, plus ou moins efficaces, et surtout ne fonctionnant pas tous dans les mêmes conditions.&lt;br /&gt;
&lt;br /&gt;
=== Parcours en profondeur ===&lt;br /&gt;
&lt;br /&gt;
Cet algorithme est quasiment identique à celui du parcours en profondeur pour la génération.&lt;br /&gt;
&lt;br /&gt;
Il est très efficace et trouvera une solution en minimisant le nombre de cases visitées.&lt;br /&gt;
&lt;br /&gt;
Il s&#039;adapte aux labyrinthes cycliques. En cas de boucle, il ne fera pas la boucle vu que l&#039;intersection a déjà été visitées, il reviendra sur ses pas.&lt;br /&gt;
&lt;br /&gt;
Il s&#039;adapte aux labyrinthes sans solution. En effet, s&#039;il n&#039;y a pas de sortie, il va revenir à sa position de départ sans position précédente (pile vide) et en ayant parcouru toutes les cases.&lt;br /&gt;
&lt;br /&gt;
=== Mur droit ===&lt;br /&gt;
&lt;br /&gt;
Cet algorithme va suivre de la main droite le mur de droite.&lt;br /&gt;
&lt;br /&gt;
Il est relativement inefficace, et va visiter un grand nombre de cases.&lt;br /&gt;
&lt;br /&gt;
Il s&#039;adapte assez mal aux labyrinthes cycliques. En effet, si la sortie n&#039;est pas dans la même boucle que l&#039;entrée, il ne la trouvera jamais.&lt;br /&gt;
&lt;br /&gt;
Il ne s&#039;adapte pas aux labyrinthes sans solution, et fera le tour de la grille à l&#039;infini.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:labyrinthe_exp_exhaust.png|vignette|left|500px|Labyrinthe résolu en utilisant le parcours en profondeur. &amp;lt;br&amp;gt; 660 cellules visitées, 1179 déplacements, chemin de 142 cellules.|alt=Parcours en profondeur]]&lt;br /&gt;
[[Fichier:labyrinthe_right_hand.png|vignette|right|500px|Labyrinthe résolu en utilisant le mur droit. &amp;lt;br&amp;gt; 1068 cellules visitées, 1995 déplacements, chemin de 142 cellules.|alt=Mur droit]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
On remarquera que des deux algorithmes, celui du mur droit explorera toutes les cellules situées en dessous du chemin optimal. Il sera donc plus efficace lorsque le chemin de solution est vers le bas de la grille.&lt;br /&gt;
&lt;br /&gt;
== Bilan personnel ==&lt;br /&gt;
&lt;br /&gt;
Ce projet m&#039;a permis de découvrir plusieurs structures de données qui me seront utiles à l&#039;avenir.&lt;br /&gt;
&lt;br /&gt;
J&#039;ai aussi pu me familiariser avec tkinter, avec la programmation orientée objets en Python (notamment héritage et méthodes statiques) et avec le multithreading (j&#039;avais codé mon projet en programmation parallèle avant de le refaire entièrement un un seul thread une semaine avant l&#039;oral).&lt;br /&gt;
&lt;br /&gt;
J&#039;ai aussi pu comprendre la complexité mathématique derrière un labyrinthe.&lt;br /&gt;
&lt;br /&gt;
== Code source ==&lt;br /&gt;
&lt;br /&gt;
Mon projet total contenant plusieurs milliers de lignes de code réparties dans une dizaine de fichiers, je ne peux évidemment pas l&#039;insérer directement dans cette page.&lt;br /&gt;
&lt;br /&gt;
Le code source est disponible sur Github à [https://github.com/Rominos111/Labyrinthe_VISI201 cette adresse]&lt;br /&gt;
&lt;br /&gt;
Il suffit d&#039;avoir installé Python 3 et tkinter.&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
&lt;br /&gt;
Génération&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#Fusion_al%C3%A9atoire_de_chemins Kruskal (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Maze_generation_algorithm#Randomized_Kruskal&#039;s_algorithm Kruskal (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#Exploration_exhaustive Parcours en profondeur (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Maze_generation_algorithm#Randomized_Depth-First_Search Parcours en profondeur (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Résolution&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#R%C3%A9solution Résolution générale (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Maze_solving_algorithm#Wall_follower Mur droit (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Structures de données&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Union-find Union-Find / Disjoint-Set (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Stack_(abstract_data_type) Pile / Stack (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Queue_(abstract_data_type) File / Queue (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Python&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://docs.python.org/3.6/reference/datamodel.html Classes et types de variables personnalisés (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [http://effbot.org/tkinterbook/canvas.htm Canvas Tkinter (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;/div&gt;</summary>
		<author><name>Theodet</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11870</id>
		<title>Génération et résolution de labyrinthes II</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11870"/>
		<updated>2019-05-22T12:40:53Z</updated>

		<summary type="html">&lt;p&gt;Theodet : /* Résolution */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__FORCETOC__[[Fichier:labyrinthe_photo.png|vignette|300px|Labyrinthe généré avec Kruskal et résolu avec le parcours en profondeur. En rouge foncé, l&#039;entrée. En vert, la sortie. En bleu, le chemin. En rouge clair, les cellules visitées lors de la résolution.|alt=&amp;quot;Labyrinthe&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
On veut générer des labyrinthes aussi grands et complexes que possible, avec des murs dans une grille carré. Comment faire pour qu&#039;il y ait toujours un chemin de l&#039;entrée à la sortie ? Comment faire pour qu&#039;il n&#039;y ait qu&#039;un chemin ? Et comment trouver la sortie quand on est perdu dans le labyrinthe ?&lt;br /&gt;
&lt;br /&gt;
== Représentation ==&lt;br /&gt;
&lt;br /&gt;
=== Propriétés ===&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe est une grille de cellules reliées, ou non, entre elles.&lt;br /&gt;
&lt;br /&gt;
Deux cellules sont reliées entre elles par une &#039;&#039;&#039;porte&#039;&#039;&#039;, ou séparées par un &#039;&#039;&#039;mur&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Tout labyrinthe a &#039;&#039;&#039;une entrée&#039;&#039;&#039; et &#039;&#039;&#039;une sortie&#039;&#039;&#039;, et quelle que soit l&#039;entrée ou la sortie, le chemin entre ces deux cellules est &#039;&#039;&#039;unique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Modélisation en graphe ===&lt;br /&gt;
&lt;br /&gt;
En théorie des graphes, un graphe est un ensemble de &#039;&#039;&#039;points&#039;&#039;&#039; (ou nœuds ou sommets) reliés ensemble par des &#039;&#039;&#039;lignes&#039;&#039;&#039; (ou liens ou arêtes).&lt;br /&gt;
&lt;br /&gt;
[[Fichier:graphe_cyclique.png|vignette|left|300px|Exemple de graphe connexe cyclique non orienté|alt=Graphe cyclique]]&lt;br /&gt;
&lt;br /&gt;
Un graphe peut être &#039;&#039;&#039;connexe&#039;&#039;&#039; (en un seul morceau) ou &#039;&#039;&#039;non connexe&#039;&#039;&#039; (en plusieurs morceaux).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Un graphe peut aussi être &#039;&#039;&#039;cyclique&#039;&#039;&#039; si les points sont reliés en formant une boucle ou &#039;&#039;&#039;acyclique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Enfin, un graphe peut être &#039;&#039;&#039;orienté&#039;&#039;&#039; (si les arêtes sont à sens unique) ou &#039;&#039;&#039;non orienté&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Arbre.PNG|vignette|left|300px|Exemple d&#039;arbre|alt=Arbre]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Un &#039;&#039;&#039;arbre&#039;&#039;&#039; est un graphe connexe, acyclique et non orienté.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
En plaçant un point sur chaque cellule de notre labyrinthe, et en reliant deux cellules séparées par une porte, on peut dessiner un arbre à partir de n&#039;importe quel labyrinthe.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:labyrinthe_avec_arbre.png|vignette|centre|300px|Exemple de labyrinthe avec son arbre. Pour plus de simplicité, on attribue à chaque nœud une position.|alt=Labyrinthe avec arbre]]&lt;br /&gt;
&lt;br /&gt;
== Génération ==&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe rectangulaire de largeur &amp;lt;math&amp;gt; L &amp;lt;/math&amp;gt; et de hauteur &amp;lt;math&amp;gt; H &amp;lt;/math&amp;gt; contient exactement &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; portes.&lt;br /&gt;
&lt;br /&gt;
Du point de vue du graphe, il y a donc &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; arêtes.&lt;br /&gt;
&lt;br /&gt;
Maintenant, comment répartir toutes ces portes de façon à ce que toutes les cellules soient accessibles et qu&#039;il n&#039;existe qu&#039;un unique chemin entre l&#039;entrée et la sortie ?&lt;br /&gt;
&lt;br /&gt;
De nombreux algorithmes existent, dont le parcours en profondeur et l&#039;algorithme de Kruskal.&lt;br /&gt;
Chaque algorithme est différent et produit des labyrinthes visuellement différents.&lt;br /&gt;
&lt;br /&gt;
En effet, si nous comparons un labyrinthe généré avec l&#039;algorithme du parcours en profondeur à un labyrinthe généré avec l&#039;algorithme de Kruskal, bien qu&#039;ils aient tous les deux une solution unique, ils apparaissent néanmoins différents visuellement.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:recursive_backtracker_comparaison.png|vignette|left|500px|Parcours en profondeur.&amp;lt;br&amp;gt;On remarque des chemins proprement dessinés.|alt=Parcours en profondeur]]&lt;br /&gt;
[[Fichier:kruskal_comparaison.png|vignette|right|500px|Algorithme de Kruskal.&amp;lt;br&amp;gt;On remarque des murs de 1 de longueur çà et là.|alt=Kruskal]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Parcours en profondeur ===&lt;br /&gt;
&lt;br /&gt;
[[Fichier:recursive_backtracker.gif|vignette|left|500px|Illustration du parcours en profondeur|alt=Parcours en profondeur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;algorithme du parcours en profondeur (&amp;quot;recursive backtracker&amp;quot; en anglais), on commence sur une cellule aléatoire dans le labyrinthe.&lt;br /&gt;
&lt;br /&gt;
On se dirige dans une direction aléatoire et on casse le mur en face, tout en marquant la cellule précédente comme visitée.&lt;br /&gt;
&lt;br /&gt;
Lorsque aucune direction n&#039;est disponible, on remonte à la position précédente.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:pile.png|vignette|300px|Représentation d&#039;une pile de positions|alt=Pile]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pour sauvegarder l&#039;historique des positions, on peut utiliser une &#039;&#039;&#039;pile&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Une pile est une liste dans laquelle seul le dernier élément peut être récupéré.&lt;br /&gt;
&lt;br /&gt;
Une pile contient 2 méthodes :&lt;br /&gt;
* push(elem) : ajoute elem à la pile&lt;br /&gt;
* pop() -&amp;gt; elem : retourne le dernier élément de la pile (elem dans notre cas)&lt;br /&gt;
&lt;br /&gt;
Dans mon implémentation de la pile, une erreur est levée si l&#039;on appelle la méthode pop sur une pile vide.&lt;br /&gt;
&lt;br /&gt;
=== Kruskal ===&lt;br /&gt;
&lt;br /&gt;
[[Fichier:kruskal.gif|vignette|left|500px|Illustration de l&#039;algorithme de Kruskal.|alt=Kruskal]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Alors que pour le parcours en profondeur on partait des cellules, l&#039;algorithme de Kruskal s&#039;applique sur des murs.&lt;br /&gt;
&lt;br /&gt;
On attribue à chaque cellule un identifiant unique.&lt;br /&gt;
&lt;br /&gt;
On choisit un mur aléatoire. Si les cellules séparées par ce mur ont des identifiants différents, on leur associe le même identifiant et on casse le mur.&lt;br /&gt;
&lt;br /&gt;
Sinon, on passe à un autre mur.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:union_find.png|vignette|300px|Représentation d&#039;une structure Union-Find avec find(a,b) et find(b,c).|alt=Union-Find]]&lt;br /&gt;
&lt;br /&gt;
Pour mettre en œuvre cet algorithme, on utilise une structure de données appelée &#039;&#039;&#039;Union-Find&#039;&#039;&#039;, qui permet de mettre en relation des éléments partageant un même représentant (ou un même identifiant).&lt;br /&gt;
&lt;br /&gt;
Il existe plusieurs variantes d&#039;Union-Find, dont notamment la compression de chemin, qui permet de n&#039;avoir qu&#039;un ou deux éléments à parcourir pour obtenir le représentant d&#039;un élément.&lt;br /&gt;
&lt;br /&gt;
Union-Find fonctionne comme un arbre. &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; a un représentant &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;, etc..., qui lui même a un représentant &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt;, qui est son propre représentant.&lt;br /&gt;
&lt;br /&gt;
Union-Find est composé de deux méthodes :&lt;br /&gt;
* union(a, b) : associe à &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; et &amp;lt;math&amp;gt;b&amp;lt;/math&amp;gt; le même représentant, par exemple &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; le représentant de &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt;&lt;br /&gt;
* find(a) -&amp;gt; &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; : tant que l&#039;élément n&#039;est pas son propre représentant, on applique find au représentant de l&#039;élément.&amp;lt;br&amp;gt; On commence donc par find(a), puis find(A) (si &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; est le représentant de &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt;), etc... La méthode de la compression de chemin permet d&#039;éviter trop de récursivité en écrivant : représentant de &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; := &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Labyrinthes cycliques ===&lt;br /&gt;
&lt;br /&gt;
Il est possible, en retirant un certain pourcentage de murs, de créer des labyrinthes cycliques à partir des labyrinthes acycliques générés auparavant.&lt;br /&gt;
&lt;br /&gt;
Cependant, certains algorithmes de résolution n&#039;adopteront pas le même comportement.&lt;br /&gt;
&lt;br /&gt;
== Résolution ==&lt;br /&gt;
&lt;br /&gt;
Il existe là encore de nombreux algorithmes de résolution de labyrinthes, plus ou moins efficaces, et surtout ne fonctionnant pas tous dans les mêmes conditions.&lt;br /&gt;
&lt;br /&gt;
=== Parcours en profondeur ===&lt;br /&gt;
&lt;br /&gt;
Cet algorithme est quasiment identique à celui du parcours en profondeur pour la génération.&lt;br /&gt;
&lt;br /&gt;
Il est très efficace et trouvera une solution en minimisant le nombre de cases visitées.&lt;br /&gt;
&lt;br /&gt;
Il s&#039;adapte aux labyrinthes cycliques. En cas de boucle, il ne fera pas la boucle vu que l&#039;intersection a déjà été visitées, il reviendra sur ses pas.&lt;br /&gt;
&lt;br /&gt;
Il s&#039;adapte aux labyrinthes sans solution. En effet, s&#039;il n&#039;y a pas de sortie, il va revenir à sa position de départ sans position précédente (pile vide) et en ayant parcouru toutes les cases.&lt;br /&gt;
&lt;br /&gt;
=== Mur droit ===&lt;br /&gt;
&lt;br /&gt;
Cet algorithme va suivre de la main droite le mur de droite.&lt;br /&gt;
&lt;br /&gt;
Il est relativement inefficace, et va visiter un grand nombre de cases.&lt;br /&gt;
&lt;br /&gt;
Il s&#039;adapte assez mal aux labyrinthes cycliques. En effet, si la sortie n&#039;est pas dans la même boucle que l&#039;entrée, il ne la trouvera jamais.&lt;br /&gt;
&lt;br /&gt;
Il ne s&#039;adapte pas aux labyrinthes sans solution, et fera le tour de la grille à l&#039;infini.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:labyrinthe_exp_exhaust.png|vignette|left|500px|Labyrinthe résolu en utilisant le parcours en profondeur. &amp;lt;br&amp;gt; 660 cellules visitées, 1179 déplacements, chemin de 142 cellules.|alt=Parcours en profondeur]]&lt;br /&gt;
[[Fichier:labyrinthe_right_hand.png|vignette|right|500px|Labyrinthe résolu en utilisant le mur droit. &amp;lt;br&amp;gt; 1068 cellules visitées, 1995 déplacements, chemin de 142 cellules.|alt=Mur droit]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
On remarquera que des deux algorithmes, celui du mur droit explorera toutes les cellules situées en dessous du chemin optimal. Il sera donc plus efficace lorsque le chemin de solution est vers le bas de la grille.&lt;br /&gt;
&lt;br /&gt;
== Code source ==&lt;br /&gt;
&lt;br /&gt;
Mon projet total contenant plusieurs milliers de lignes de code réparties dans une dizaine de fichiers, je ne peux évidemment pas l&#039;insérer directement dans cette page.&lt;br /&gt;
&lt;br /&gt;
Le code source est disponible sur Github à [https://github.com/Rominos111/Labyrinthe_VISI201 cette adresse]&lt;br /&gt;
&lt;br /&gt;
Il suffit d&#039;avoir installé Python 3 et tkinter.&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
&lt;br /&gt;
Génération&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#Fusion_al%C3%A9atoire_de_chemins Kruskal (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Maze_generation_algorithm#Randomized_Kruskal&#039;s_algorithm Kruskal (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#Exploration_exhaustive Parcours en profondeur (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Maze_generation_algorithm#Randomized_Depth-First_Search Parcours en profondeur (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Résolution&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#R%C3%A9solution Résolution générale (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Maze_solving_algorithm#Wall_follower Mur droit (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Structures de données&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Union-find Union-Find / Disjoint-Set (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Stack_(abstract_data_type) Pile / Stack (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Queue_(abstract_data_type) File / Queue (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Python&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://docs.python.org/3.6/reference/datamodel.html Classes et types de variables personnalisés (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [http://effbot.org/tkinterbook/canvas.htm Canvas Tkinter (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;/div&gt;</summary>
		<author><name>Theodet</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11831</id>
		<title>Génération et résolution de labyrinthes II</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11831"/>
		<updated>2019-05-20T06:51:31Z</updated>

		<summary type="html">&lt;p&gt;Theodet : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__FORCETOC__[[Fichier:labyrinthe_photo.png|vignette|300px|Labyrinthe généré avec Kruskal et résolu avec le parcours en profondeur. En rouge foncé, l&#039;entrée. En vert, la sortie. En bleu, le chemin. En rouge clair, les cellules visitées lors de la résolution.|alt=&amp;quot;Labyrinthe&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
On veut générer des labyrinthes aussi grands et complexes que possible, avec des murs dans une grille carré. Comment faire pour qu&#039;il y ait toujours un chemin de l&#039;entrée à la sortie ? Comment faire pour qu&#039;il n&#039;y ait qu&#039;un chemin ? Et comment trouver la sortie quand on est perdu dans le labyrinthe ?&lt;br /&gt;
&lt;br /&gt;
== Représentation ==&lt;br /&gt;
&lt;br /&gt;
=== Propriétés ===&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe est une grille de cellules reliées, ou non, entre elles.&lt;br /&gt;
&lt;br /&gt;
Deux cellules sont reliées entre elles par une &#039;&#039;&#039;porte&#039;&#039;&#039;, ou séparées par un &#039;&#039;&#039;mur&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Tout labyrinthe a &#039;&#039;&#039;une entrée&#039;&#039;&#039; et &#039;&#039;&#039;une sortie&#039;&#039;&#039;, et quelle que soit l&#039;entrée ou la sortie, le chemin entre ces deux cellules est &#039;&#039;&#039;unique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Modélisation en graphe ===&lt;br /&gt;
&lt;br /&gt;
En théorie des graphes, un graphe est un ensemble de &#039;&#039;&#039;points&#039;&#039;&#039; (ou nœuds ou sommets) reliés ensemble par des &#039;&#039;&#039;lignes&#039;&#039;&#039; (ou liens ou arêtes).&lt;br /&gt;
&lt;br /&gt;
[[Fichier:graphe_cyclique.png|vignette|left|300px|Exemple de graphe connexe cyclique non orienté|alt=Graphe cyclique]]&lt;br /&gt;
&lt;br /&gt;
Un graphe peut être &#039;&#039;&#039;connexe&#039;&#039;&#039; (en un seul morceau) ou &#039;&#039;&#039;non connexe&#039;&#039;&#039; (en plusieurs morceaux).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Un graphe peut aussi être &#039;&#039;&#039;cyclique&#039;&#039;&#039; si les points sont reliés en formant une boucle ou &#039;&#039;&#039;acyclique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Enfin, un graphe peut être &#039;&#039;&#039;orienté&#039;&#039;&#039; (si les arêtes sont à sens unique) ou &#039;&#039;&#039;non orienté&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Arbre.PNG|vignette|left|300px|Exemple d&#039;arbre|alt=Arbre]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Un &#039;&#039;&#039;arbre&#039;&#039;&#039; est un graphe connexe, acyclique et non orienté.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
En plaçant un point sur chaque cellule de notre labyrinthe, et en reliant deux cellules séparées par une porte, on peut dessiner un arbre à partir de n&#039;importe quel labyrinthe.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:labyrinthe_avec_arbre.png|vignette|centre|300px|Exemple de labyrinthe avec son arbre. Pour plus de simplicité, on attribue à chaque nœud une position.|alt=Labyrinthe avec arbre]]&lt;br /&gt;
&lt;br /&gt;
== Génération ==&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe rectangulaire de largeur &amp;lt;math&amp;gt; L &amp;lt;/math&amp;gt; et de hauteur &amp;lt;math&amp;gt; H &amp;lt;/math&amp;gt; contient exactement &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; portes.&lt;br /&gt;
&lt;br /&gt;
Du point de vue du graphe, il y a donc &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; arêtes.&lt;br /&gt;
&lt;br /&gt;
Maintenant, comment répartir toutes ces portes de façon à ce que toutes les cellules soient accessibles et qu&#039;il n&#039;existe qu&#039;un unique chemin entre l&#039;entrée et la sortie ?&lt;br /&gt;
&lt;br /&gt;
De nombreux algorithmes existent, dont le parcours en profondeur et l&#039;algorithme de Kruskal.&lt;br /&gt;
Chaque algorithme est différent et produit des labyrinthes visuellement différents.&lt;br /&gt;
&lt;br /&gt;
En effet, si nous comparons un labyrinthe généré avec l&#039;algorithme du parcours en profondeur à un labyrinthe généré avec l&#039;algorithme de Kruskal, bien qu&#039;ils aient tous les deux une solution unique, ils apparaissent néanmoins différents visuellement.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:recursive_backtracker_comparaison.png|vignette|left|500px|Parcours en profondeur.&amp;lt;br&amp;gt;On remarque des chemins proprement dessinés.|alt=Parcours en profondeur]]&lt;br /&gt;
[[Fichier:kruskal_comparaison.png|vignette|right|500px|Algorithme de Kruskal.&amp;lt;br&amp;gt;On remarque des murs de 1 de longueur çà et là.|alt=Kruskal]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Parcours en profondeur ===&lt;br /&gt;
&lt;br /&gt;
[[Fichier:recursive_backtracker.gif|vignette|left|500px|Illustration du parcours en profondeur|alt=Parcours en profondeur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;algorithme du parcours en profondeur (&amp;quot;recursive backtracker&amp;quot; en anglais), on commence sur une cellule aléatoire dans le labyrinthe.&lt;br /&gt;
&lt;br /&gt;
On se dirige dans une direction aléatoire et on casse le mur en face, tout en marquant la cellule précédente comme visitée.&lt;br /&gt;
&lt;br /&gt;
Lorsque aucune direction n&#039;est disponible, on remonte à la position précédente.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:pile.png|vignette|300px|Représentation d&#039;une pile de positions|alt=Pile]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pour sauvegarder l&#039;historique des positions, on peut utiliser une &#039;&#039;&#039;pile&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Une pile est une liste dans laquelle seul le dernier élément peut être récupéré.&lt;br /&gt;
&lt;br /&gt;
Une pile contient 2 méthodes :&lt;br /&gt;
* push(elem) : ajoute elem à la pile&lt;br /&gt;
* pop() -&amp;gt; elem : retourne le dernier élément de la pile (elem dans notre cas)&lt;br /&gt;
&lt;br /&gt;
Dans mon implémentation de la pile, une erreur est levée si l&#039;on appelle la méthode pop sur une pile vide.&lt;br /&gt;
&lt;br /&gt;
=== Kruskal ===&lt;br /&gt;
&lt;br /&gt;
[[Fichier:kruskal.gif|vignette|left|500px|Illustration de l&#039;algorithme de Kruskal.|alt=Kruskal]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Alors que pour le parcours en profondeur on partait des cellules, l&#039;algorithme de Kruskal s&#039;applique sur des murs.&lt;br /&gt;
&lt;br /&gt;
On attribue à chaque cellule un identifiant unique.&lt;br /&gt;
&lt;br /&gt;
On choisit un mur aléatoire. Si les cellules séparées par ce mur ont des identifiants différents, on leur associe le même identifiant et on casse le mur.&lt;br /&gt;
&lt;br /&gt;
Sinon, on passe à un autre mur.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:union_find.png|vignette|300px|Représentation d&#039;une structure Union-Find avec find(a,b) et find(b,c).|alt=Union-Find]]&lt;br /&gt;
&lt;br /&gt;
Pour mettre en œuvre cet algorithme, on utilise une structure de données appelée &#039;&#039;&#039;Union-Find&#039;&#039;&#039;, qui permet de mettre en relation des éléments partageant un même représentant (ou un même identifiant).&lt;br /&gt;
&lt;br /&gt;
Il existe plusieurs variantes d&#039;Union-Find, dont notamment la compression de chemin, qui permet de n&#039;avoir qu&#039;un ou deux éléments à parcourir pour obtenir le représentant d&#039;un élément.&lt;br /&gt;
&lt;br /&gt;
Union-Find fonctionne comme un arbre. &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; a un représentant &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;, etc..., qui lui même a un représentant &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt;, qui est son propre représentant.&lt;br /&gt;
&lt;br /&gt;
Union-Find est composé de deux méthodes :&lt;br /&gt;
* union(a, b) : associe à &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; et &amp;lt;math&amp;gt;b&amp;lt;/math&amp;gt; le même représentant, par exemple &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; le représentant de &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt;&lt;br /&gt;
* find(a) -&amp;gt; &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; : tant que l&#039;élément n&#039;est pas son propre représentant, on applique find au représentant de l&#039;élément.&amp;lt;br&amp;gt; On commence donc par find(a), puis find(A) (si &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; est le représentant de &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt;), etc... La méthode de la compression de chemin permet d&#039;éviter trop de récursivité en écrivant : représentant de &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; := &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Labyrinthes cycliques ===&lt;br /&gt;
&lt;br /&gt;
Il est possible, en retirant un certain pourcentage de murs, de créer des labyrinthes cycliques à partir des labyrinthes acycliques générés auparavant.&lt;br /&gt;
&lt;br /&gt;
Cependant, certains algorithmes de résolution n&#039;adopteront pas le même comportement.&lt;br /&gt;
&lt;br /&gt;
== Résolution ==&lt;br /&gt;
&lt;br /&gt;
Il existe là encore de nombreux algorithmes de résolution de labyrinthes, plus ou moins efficaces, et surtout ne fonctionnant pas tous dans les mêmes conditions.&lt;br /&gt;
&lt;br /&gt;
=== Parcours en profondeur ===&lt;br /&gt;
&lt;br /&gt;
Cet algorithme est quasiment identique à celui du parcours en profondeur pour la génération.&lt;br /&gt;
&lt;br /&gt;
Il est très efficace et trouvera une solution en minimisant le nombre de cases visitées.&lt;br /&gt;
&lt;br /&gt;
Il s&#039;adapte aux labyrinthes cycliques. En cas de boucle, il ne fera pas la boucle vu que l&#039;intersection a déjà été visitées, il reviendra sur ses pas.&lt;br /&gt;
&lt;br /&gt;
Il s&#039;adapte aux labyrinthes sans solution. En effet, s&#039;il n&#039;y a pas de sortie, il va revenir à sa position de départ sans position précédente (pile vide) et en ayant parcouru toutes les cases.&lt;br /&gt;
&lt;br /&gt;
=== Mur droit ===&lt;br /&gt;
&lt;br /&gt;
Cet algorithme va suivre de la main droite le mur de droite.&lt;br /&gt;
&lt;br /&gt;
Il est relativement inefficace, et va visiter un grand nombre de cases.&lt;br /&gt;
&lt;br /&gt;
Il s&#039;adapte assez mal aux labyrinthes cycliques. En effet, si la sortie n&#039;est pas dans la même boucle que l&#039;entrée, il ne la trouvera jamais.&lt;br /&gt;
&lt;br /&gt;
Il ne s&#039;adapte pas aux labyrinthes sans solution, et fera le tour de la grille à l&#039;infini.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:labyrinthe_exp_exhaust.png|vignette|left|500px|Labyrinthe résolu en utilisant le parcours en profondeur. &amp;lt;br&amp;gt; 660 cellules visitées, 1179 déplacements, chemin de 142 cellules.|alt=Parcours en profondeur]]&lt;br /&gt;
[[Fichier:labyrinthe_right_hand.png|vignette|right|500px|Labyrinthe résolu en utilisant le mur droit. &amp;lt;br&amp;gt; 1068 cellules visitées, 1995 déplacements, chemin de 142 cellules.|alt=Mur droit]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Code source ==&lt;br /&gt;
&lt;br /&gt;
Mon projet total contenant plusieurs milliers de lignes de code réparties dans une dizaine de fichiers, je ne peux évidemment pas l&#039;insérer directement dans cette page.&lt;br /&gt;
&lt;br /&gt;
Le code source est disponible sur Github à [https://github.com/Rominos111/Labyrinthe_VISI201 cette adresse]&lt;br /&gt;
&lt;br /&gt;
Il suffit d&#039;avoir installé Python 3 et tkinter.&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
&lt;br /&gt;
Génération&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#Fusion_al%C3%A9atoire_de_chemins Kruskal (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Maze_generation_algorithm#Randomized_Kruskal&#039;s_algorithm Kruskal (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#Exploration_exhaustive Parcours en profondeur (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Maze_generation_algorithm#Randomized_Depth-First_Search Parcours en profondeur (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Résolution&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#R%C3%A9solution Résolution générale (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Maze_solving_algorithm#Wall_follower Mur droit (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Structures de données&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Union-find Union-Find / Disjoint-Set (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Stack_(abstract_data_type) Pile / Stack (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Queue_(abstract_data_type) File / Queue (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Python&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://docs.python.org/3.6/reference/datamodel.html Classes et types de variables personnalisés (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [http://effbot.org/tkinterbook/canvas.htm Canvas Tkinter (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;/div&gt;</summary>
		<author><name>Theodet</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11830</id>
		<title>Génération et résolution de labyrinthes II</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11830"/>
		<updated>2019-05-20T06:47:19Z</updated>

		<summary type="html">&lt;p&gt;Theodet : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__FORCETOC__[[Fichier:labyrinthe_photo.png|vignette|300px|Labyrinthe généré avec Kruskal et résolu avec le parcours en profondeur. En route foncé, l&#039;entrée. En vert, la sortie. En bleu, le chemin. En rouge clair, les cellules visitées lors de la résolution.|alt=&amp;quot;Labyrinthe&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
On veut générer des labyrinthes aussi grands et complexes que possible, avec des murs dans une grille carré. Comment faire pour qu&#039;il y ait toujours un chemin de l&#039;entrée à la sortie ? Comment faire pour qu&#039;il n&#039;y ait qu&#039;un chemin ? Et comment trouver la sortie quand on est perdu dans le labyrinthe ?&lt;br /&gt;
&lt;br /&gt;
== Représentation ==&lt;br /&gt;
&lt;br /&gt;
=== Propriétés ===&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe est une grille de cellules reliées, ou non, entre elles.&lt;br /&gt;
&lt;br /&gt;
Deux cellules sont reliées entre elles par une &#039;&#039;&#039;porte&#039;&#039;&#039;, ou séparées par un &#039;&#039;&#039;mur&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Tout labyrinthe a &#039;&#039;&#039;une entrée&#039;&#039;&#039; et &#039;&#039;&#039;une sortie&#039;&#039;&#039;, et quelle que soit l&#039;entrée ou la sortie, le chemin entre ces deux cellules est &#039;&#039;&#039;unique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Modélisation en graphe ===&lt;br /&gt;
&lt;br /&gt;
En théorie des graphes, un graphe est un ensemble de &#039;&#039;&#039;points&#039;&#039;&#039; (ou nœuds ou sommets) reliés ensemble par des &#039;&#039;&#039;lignes&#039;&#039;&#039; (ou liens ou arêtes).&lt;br /&gt;
&lt;br /&gt;
[[Fichier:graphe_cyclique.png|vignette|left|300px|Exemple de graphe connexe cyclique non orienté|alt=Graphe cyclique]]&lt;br /&gt;
&lt;br /&gt;
Un graphe peut être &#039;&#039;&#039;connexe&#039;&#039;&#039; (en un seul morceau) ou &#039;&#039;&#039;non connexe&#039;&#039;&#039; (en plusieurs morceaux).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Un graphe peut aussi être &#039;&#039;&#039;cyclique&#039;&#039;&#039; si les points sont reliés en formant une boucle ou &#039;&#039;&#039;acyclique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Enfin, un graphe peut être &#039;&#039;&#039;orienté&#039;&#039;&#039; (si les arêtes sont à sens unique) ou &#039;&#039;&#039;non orienté&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Arbre.PNG|vignette|left|300px|Exemple d&#039;arbre|alt=Arbre]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Un &#039;&#039;&#039;arbre&#039;&#039;&#039; est un graphe connexe, acyclique et non orienté.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
En plaçant un point sur chaque cellule de notre labyrinthe, et en reliant deux cellules séparées par une porte, on peut dessiner un arbre à partir de n&#039;importe quel labyrinthe.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:labyrinthe_avec_arbre.png|vignette|centre|300px|Exemple de labyrinthe avec son arbre. Pour plus de simplicité, on attribue à chaque nœud une position.|alt=Labyrinthe avec arbre]]&lt;br /&gt;
&lt;br /&gt;
== Génération ==&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe rectangulaire de largeur &amp;lt;math&amp;gt; L &amp;lt;/math&amp;gt; et de hauteur &amp;lt;math&amp;gt; H &amp;lt;/math&amp;gt; contient exactement &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; portes.&lt;br /&gt;
&lt;br /&gt;
Du point de vue du graphe, il y a donc &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; arêtes.&lt;br /&gt;
&lt;br /&gt;
Maintenant, comment répartir toutes ces portes de façon à ce que toutes les cellules soient accessibles et qu&#039;il n&#039;existe qu&#039;un unique chemin entre l&#039;entrée et la sortie ?&lt;br /&gt;
&lt;br /&gt;
De nombreux algorithmes existent, dont le parcours en profondeur et l&#039;algorithme de Kruskal.&lt;br /&gt;
Chaque algorithme est différent et produit des labyrinthes visuellement différents.&lt;br /&gt;
&lt;br /&gt;
En effet, si nous comparons un labyrinthe généré avec l&#039;algorithme du parcours en profondeur à un labyrinthe généré avec l&#039;algorithme de Kruskal, bien qu&#039;ils aient tous les deux une solution unique, ils apparaissent néanmoins différents visuellement.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:recursive_backtracker_comparaison.png|vignette|left|500px|Parcours en profondeur.&amp;lt;br&amp;gt;On remarque des chemins proprement dessinés.|alt=Parcours en profondeur]]&lt;br /&gt;
[[Fichier:kruskal_comparaison.png|vignette|right|500px|Algorithme de Kruskal.&amp;lt;br&amp;gt;On remarque des murs de 1 de longueur çà et là.|alt=Kruskal]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Parcours en profondeur ===&lt;br /&gt;
&lt;br /&gt;
[[Fichier:recursive_backtracker.gif|vignette|left|500px|Illustration du parcours en profondeur|alt=Parcours en profondeur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;algorithme du parcours en profondeur (&amp;quot;recursive backtracker&amp;quot; en anglais), on commence sur une cellule aléatoire dans le labyrinthe.&lt;br /&gt;
&lt;br /&gt;
On se dirige dans une direction aléatoire et on casse le mur en face, tout en marquant la cellule précédente comme visitée.&lt;br /&gt;
&lt;br /&gt;
Lorsque aucune direction n&#039;est disponible, on remonte à la position précédente.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:pile.png|vignette|300px|Représentation d&#039;une pile de positions|alt=Pile]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pour sauvegarder l&#039;historique des positions, on peut utiliser une &#039;&#039;&#039;pile&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Une pile est une liste dans laquelle seul le dernier élément peut être récupéré.&lt;br /&gt;
&lt;br /&gt;
Une pile contient 2 méthodes :&lt;br /&gt;
* push(elem) : ajoute elem à la pile&lt;br /&gt;
* pop() -&amp;gt; elem : retourne le dernier élément de la pile (elem dans notre cas)&lt;br /&gt;
&lt;br /&gt;
Dans mon implémentation de la pile, une erreur est levée si l&#039;on appelle la méthode pop sur une pile vide.&lt;br /&gt;
&lt;br /&gt;
=== Kruskal ===&lt;br /&gt;
&lt;br /&gt;
[[Fichier:kruskal.gif|vignette|left|500px|Illustration de l&#039;algorithme de Kruskal.|alt=Kruskal]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Alors que pour le parcours en profondeur on partait des cellules, l&#039;algorithme de Kruskal s&#039;applique sur des murs.&lt;br /&gt;
&lt;br /&gt;
On attribue à chaque cellule un identifiant unique.&lt;br /&gt;
&lt;br /&gt;
On choisit un mur aléatoire. Si les cellules séparées par ce mur ont des identifiants différents, on leur associe le même identifiant et on casse le mur.&lt;br /&gt;
&lt;br /&gt;
Sinon, on passe à un autre mur.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:union_find.png|vignette|300px|Représentation d&#039;une structure Union-Find avec find(a,b) et find(b,c).|alt=Union-Find]]&lt;br /&gt;
&lt;br /&gt;
Pour mettre en œuvre cet algorithme, on utilise une structure de données appelée &#039;&#039;&#039;Union-Find&#039;&#039;&#039;, qui permet de mettre en relation des éléments partageant un même représentant (ou un même identifiant).&lt;br /&gt;
&lt;br /&gt;
Il existe plusieurs variantes d&#039;Union-Find, dont notamment la compression de chemin, qui permet de n&#039;avoir qu&#039;un ou deux éléments à parcourir pour obtenir le représentant d&#039;un élément.&lt;br /&gt;
&lt;br /&gt;
Union-Find fonctionne comme un arbre. &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; a un représentant &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;, etc..., qui lui même a un représentant &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt;, qui est son propre représentant.&lt;br /&gt;
&lt;br /&gt;
Union-Find est composé de deux méthodes :&lt;br /&gt;
* union(a, b) : associe à &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; et &amp;lt;math&amp;gt;b&amp;lt;/math&amp;gt; le même représentant, par exemple &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; le représentant de &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt;&lt;br /&gt;
* find(a) -&amp;gt; &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; : tant que l&#039;élément n&#039;est pas son propre représentant, on applique find au représentant de l&#039;élément.&amp;lt;br&amp;gt; On commence donc par find(a), puis find(A) (si &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; est le représentant de &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt;), etc... La méthode de la compression de chemin permet d&#039;éviter trop de récursivité en écrivant : représentant de &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; := &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Labyrinthes cycliques ===&lt;br /&gt;
&lt;br /&gt;
Il est possible, en retirant un certain pourcentage de murs, de créer des labyrinthes cycliques à partir des labyrinthes acycliques générés auparavant.&lt;br /&gt;
&lt;br /&gt;
Cependant, certains algorithmes de résolution n&#039;adopteront pas le même comportement.&lt;br /&gt;
&lt;br /&gt;
== Résolution ==&lt;br /&gt;
&lt;br /&gt;
Il existe là encore de nombreux algorithmes de résolution de labyrinthes, plus ou moins efficaces, et surtout ne fonctionnant pas tous dans les mêmes conditions.&lt;br /&gt;
&lt;br /&gt;
=== Parcours en profondeur ===&lt;br /&gt;
&lt;br /&gt;
Cet algorithme est quasiment identique à celui du parcours en profondeur pour la génération.&lt;br /&gt;
&lt;br /&gt;
Il est très efficace et trouvera une solution en minimisant le nombre de cases visitées.&lt;br /&gt;
&lt;br /&gt;
Il s&#039;adapte aux labyrinthes cycliques. En cas de boucle, il ne fera pas la boucle vu que l&#039;intersection a déjà été visitées, il reviendra sur ses pas.&lt;br /&gt;
&lt;br /&gt;
Il s&#039;adapte aux labyrinthes sans solution. En effet, s&#039;il n&#039;y a pas de sortie, il va revenir à sa position de départ sans position précédente (pile vide) et en ayant parcouru toutes les cases.&lt;br /&gt;
&lt;br /&gt;
=== Mur droit ===&lt;br /&gt;
&lt;br /&gt;
Cet algorithme va suivre de la main droite le mur de droite.&lt;br /&gt;
&lt;br /&gt;
Il est relativement inefficace, et va visiter un grand nombre de cases.&lt;br /&gt;
&lt;br /&gt;
Il s&#039;adapte assez mal aux labyrinthes cycliques. En effet, si la sortie n&#039;est pas dans la même boucle que l&#039;entrée, il ne la trouvera jamais.&lt;br /&gt;
&lt;br /&gt;
Il ne s&#039;adapte pas aux labyrinthes sans solution, et fera le tour de la grille à l&#039;infini.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:labyrinthe_exp_exhaust.png|vignette|left|500px|Labyrinthe résolu en utilisant le parcours en profondeur. &amp;lt;br&amp;gt; 660 cellules visitées, 1179 déplacements, chemin de 142 cellules.|alt=Parcours en profondeur]]&lt;br /&gt;
[[Fichier:labyrinthe_right_hand.png|vignette|right|500px|Labyrinthe résolu en utilisant le mur droit. &amp;lt;br&amp;gt; 1068 cellules visitées, 1995 déplacements, chemin de 142 cellules.|alt=Mur droit]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Code source ==&lt;br /&gt;
&lt;br /&gt;
Mon projet total contenant plusieurs milliers de lignes de code réparties dans une dizaine de fichiers, je ne peux évidemment pas l&#039;insérer directement dans cette page.&lt;br /&gt;
&lt;br /&gt;
Le code source est disponible sur Github à [https://github.com/Rominos111/Labyrinthe_VISI201 cette adresse]&lt;br /&gt;
&lt;br /&gt;
Il suffit d&#039;avoir installé Python 3 et tkinter.&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
&lt;br /&gt;
Génération&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#Fusion_al%C3%A9atoire_de_chemins Kruskal (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Maze_generation_algorithm#Randomized_Kruskal&#039;s_algorithm Kruskal (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#Exploration_exhaustive Parcours en profondeur (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Maze_generation_algorithm#Randomized_Depth-First_Search Parcours en profondeur (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Résolution&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#R%C3%A9solution Résolution générale (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Maze_solving_algorithm#Wall_follower Mur droit (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Structures de données&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Union-find Union-Find / Disjoint-Set (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Stack_(abstract_data_type) Pile / Stack (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Queue_(abstract_data_type) File / Queue (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Python&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://docs.python.org/3.6/reference/datamodel.html Classes et types de variables personnalisés (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [http://effbot.org/tkinterbook/canvas.htm Canvas Tkinter (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;/div&gt;</summary>
		<author><name>Theodet</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Dilemme_du_prisonnier&amp;diff=11792</id>
		<title>Dilemme du prisonnier</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Dilemme_du_prisonnier&amp;diff=11792"/>
		<updated>2019-05-19T21:21:48Z</updated>

		<summary type="html">&lt;p&gt;Theodet : Juste 2 ou 3 fautes de français et vu que je suis gentil je veux pas que les profs les voient lol&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
Le dilemme du prisonnier à été inventé en 1950 par Albert William Tucker et fait partie de la théorie des jeux qui est un domaine des mathématiques étudiant les interactions entre différents individus qui sont conscients ou non de ces interactions. Ils devront donc faire des choix dont ils sont conscients ou non lors de ces interactions.&lt;br /&gt;
&lt;br /&gt;
== Le dilemme du prisonnier ==&lt;br /&gt;
&lt;br /&gt;
Les individus sont soumis dans le dilemme du prisonnier à une interaction où ils ont deux choix : soit ils coopèrent avec l’autre individu, soit ils le trahissent. Les individus sont récompensés selon la matrice des Paiements suivante :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Tableau matrice paiements.PNG]]&lt;br /&gt;
&lt;br /&gt;
L’intérêt de la configuration actuelle de la matrice des Paiements actuelle est que les individus ont un intérêt certain à trahir l’autre mais que la coopération est la meilleur option pour les deux individus. On représente l’intérêt à trahir par rapport à la coopération par la variable B qui dans notre exemple est égale à 1,85. &lt;br /&gt;
&lt;br /&gt;
Afin de simplifier notre modèle nous ne considérerons que deux comportements possibles qui sont :&lt;br /&gt;
&lt;br /&gt;
-Le Croyant qui coopérera systématiquement&lt;br /&gt;
&lt;br /&gt;
-Le Traître qui trahira systématiquement&lt;br /&gt;
&lt;br /&gt;
== Spatialisation du Dilemme du prisonnier ==&lt;br /&gt;
&lt;br /&gt;
Nous spatialisons le dilemme du prisonnier afin d’expliquer en partie des observations dans le vivant où les êtres vivants coopèrent entre eux alors qu’ils ont tout à y gagner en ne le faisant pas. Pour étayer nos propos on propose la citation suivante :« The prisoners’ Dilemma is an interesting metaphor for the fundamental biological problem of how cooperative behaviour may evolve and be maintained »([https://www.researchgate.net/publication/216634494_Evolutionary_Games_and_Spatial_Chaos Nowak, M.A. et May, R.M. 1992. Evolutionary games and spatial chaos]). En spatialisant le dilemme du prisonnier nous pouvons observer l’évolution des pratiques dans des situations variées. Il est à noter que nous pouvons aussi établir des liens entre les domaines de l’économie et de la sociologie notamment.&lt;br /&gt;
&lt;br /&gt;
Les prisonniers sont au voisinage de Moore (8 voisins) de telle sorte à ce que dans l’espace les voisins d’un prisonnier lambda soient disposés de la manière suivante :&lt;br /&gt;
&lt;br /&gt;
1       2       3&lt;br /&gt;
&lt;br /&gt;
4       P       5&lt;br /&gt;
&lt;br /&gt;
6       7       8&lt;br /&gt;
&lt;br /&gt;
L’espace dans lequel ils évoluent est un espace toroïdale (bordures ouvertes) en forme de carré de dimension n*n. On peut aussi le représenter comme une matrice carré avec les bordures qui communiquent entre elles.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
À chaque tour les prisonniers vont jouer au dilemme du prisonnier avec chacun de leurs voisins. Ils obtiendront un score conformément à leurs choix et à la matrice des Paiements. Puis chacun leur tour mettre à jour leur stratégie en fonction du score des voisins.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Afin de pouvoir visualiser l&#039;évolution de notre espace nous avons créé un programme en Java afin de profiter des aspects suivant de Java:&lt;br /&gt;
&lt;br /&gt;
Le premier est la programmation objet, cela nous permet de diviser la complexité de notre programme dans plusieurs objets interagissants entre eux. Nous pouvons aussi créer des abstractions d&#039;objets qui nous permettent d&#039;avoir des objets qui ont des comportements différents les uns des autres mais ayants tous des points communs ce qui permet de les manipuler plus facilement.&lt;br /&gt;
&lt;br /&gt;
Le second est la bibliothèque Abstract Windows Toolkit (ou AWT pour faire plus court), qui nous permet de faire sans trop de problèmes une fenêtre personnalisable qui affiche des composants graphiques. Ces composants étant eux mêmes variés, on utilisera surtout les propriétés du composant Canvas dans ce programme. Grâce à l’héritage permis par la programmation objet nous pouvons créer nos propres composants graphiques pour afficher nos résultats.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Notre programme crée donc une fenêtre qui affiche les prisonniers en fonction de leur stratégie actuelle et de leur dernière stratégie. Le code couleur est le suivant :&lt;br /&gt;
&lt;br /&gt;
-en rouge les Traîtres qui l’ont été pendant 2 tours consécutifs&lt;br /&gt;
&lt;br /&gt;
-en jaune les Croyants qui sont devenus Traîtres&lt;br /&gt;
&lt;br /&gt;
-en vert les Traîtres devenus Croyants&lt;br /&gt;
&lt;br /&gt;
-en bleu les Croyants qui l’ont été pendant 2 tours consécutifs&lt;br /&gt;
&lt;br /&gt;
== Une expérience intéressante ==&lt;br /&gt;
&lt;br /&gt;
On propose dans cette partie de commencer à étudier un cas en particulier. Dans cette première expérience nous fixons B à 1,85 et plaçons un traître au milieu de croyants dans une grille de 301 par 301. Nous pensons que cette configuration donnera des résultats intéressants car B n&#039;est pas assez grand pour permettre une domination complète des Traîtres ou pas assez petit pour permettre une domination complète des Croyants.&lt;br /&gt;
&lt;br /&gt;
Après quelques tours de la simulation nous observons l&#039;image suivante:&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Screen_première_exp.PNG]]&lt;br /&gt;
&lt;br /&gt;
Nous pouvons voir grâce à la bordure verte que le carré de traîtres au centre de l&#039;image est en train de rétrécir alors que dans les coins des îlots de traîtres apparaissent comme nous le montre la grand quantité de jaune.&lt;br /&gt;
&lt;br /&gt;
Nous passons sous silence quelques tours pour arriver à la situation suivante:&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Screen première exp 2.PNG]]&lt;br /&gt;
&lt;br /&gt;
Nous pouvons voir à présent que les comportements dans la simulation varient beaucoup comme témoignent l&#039;abondance de prisonniers affichés en jaune et en vert.&lt;br /&gt;
&lt;br /&gt;
Lors du déroulé de cette simulation nous avons pus récolter C qui est le rapport entre le nombre de croyants dans la matrice sur le nombre de prisonniers au total. Cette variable nous permettra de visualiser l&#039;évolution du nombre de croyants dans la simulation rapidement. Nous allons maintenant montrer son évolution au court du temps dans la simulation.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Screen Graph_première exp.PNG]]&lt;br /&gt;
&lt;br /&gt;
Nous pouvons ainsi observer sur le graphique que C semble tendre vers environ 0.3 montrant de ce fait que la simulation est dominé par les traîtres mais que les croyants résistent tout de même. Les variations de C ne sont pas de ce que l&#039;on observe sur le graphique et la simulation cycliques ce qui veut dire que même si le nombre de croyants semble à peut près stable il n&#039;en reste pas moins fluctuant.&lt;br /&gt;
&lt;br /&gt;
== Automatisation des expériences ==&lt;br /&gt;
&lt;br /&gt;
Nous avons pus observer une simulation particulière mais nous devons maintenant pouvoir faire des observations autres que visuelles car nous n’avons pas le temps de le faire pour toutes les expériences permisses par notre modèle. On n’as alors décidé donc de créer un objet dans le programme pour extraire les données des expériences et nous les résumées. Nous ne montrerons toutefois que les expériences que l’on juge intéressantes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Nous voulons tout d&#039;abord mesurer l&#039;influence de B sur l&#039;évolution d&#039;une répartition aléatoire. Pour cela nous fixerons les paramètres suivants pour chaque simulation. Dans chaque simulation on aura systématiquement 10% de traîtres répartis aléatoirement parmi 90% de croyants. La dimension des matrices sera de 200*200. Nous ferons variez B entre 1.75 et 2.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pour un B appartenant à [1.75;1.8[ On observe la simulation suivante au bout de 400 tours:&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Screen_B_1,75_10%.PNG]]&lt;br /&gt;
&lt;br /&gt;
On observe des réseaux de traîtres interconnectés entre eux mais pouvant être indépendants avec une taille minimale d&#039;un carré de 4 traîtres. On observe aussi des zones ou les prisonniers alternent entre traître et croyant, on les repères en cherchant les zones en jaune ou en vert.&lt;br /&gt;
&lt;br /&gt;
Le graphique de l&#039;évolution de C est le suivant:&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Screen Graph B 1,75 10%.PNG]]&lt;br /&gt;
&lt;br /&gt;
Ce graphique nous permet d&#039;affirmer que la simulation est à peut près stable car on observe toujours des petits chutes du nombre de croyants. C semble tendre par ailleurs vers 0.7.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pour un B appartenant à [1.8;2[ On observe la simulation suivante au bout de 400 tours:&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Screen B 1,9 10%.PNG]]&lt;br /&gt;
&lt;br /&gt;
On observe une situation chaotique avec une majorité de Traîtres et des îlots de Croyants apparaissant et disparaissant au fur et à mesure de la simulation. On remarque aussi beaucoup de jaune et de verts sur les images cela nous montre que les comportements des prisonniers changent beaucoup.&lt;br /&gt;
&lt;br /&gt;
Le graphique de l&#039;évolution de C est le suivant:&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Screen Graph B 1,9 10%.PNG]]&lt;br /&gt;
&lt;br /&gt;
Ce graphique nous montre que la simulation n&#039;est pas stable mais que C se stabilise vers 0.3.&lt;br /&gt;
&lt;br /&gt;
Il est aussi à noter que sur les images B est à 1.9 et que plus B tend vers 1.8, C se stabilise vers 0.4.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pour un B supérieur à 2 On observe la simulation suivante au bout de 400 tours:&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Screen B 2 10%.PNG]]&lt;br /&gt;
&lt;br /&gt;
On observe que les traîtres occupent quasiment tout l&#039;espace et que les croyants sont regroupés en îlots qui s&#039;étendent et se rétrécissent périodiquement.&lt;br /&gt;
&lt;br /&gt;
Le graphique de l&#039;évolution de C est le suivant:&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Screen Graph B 2 10%.PNG]]&lt;br /&gt;
&lt;br /&gt;
Ce graphique nous montre que la simulation est très stable et que C tend vers 0.02.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Améliorations à apporter ==&lt;br /&gt;
&lt;br /&gt;
Nous n’avons pas exploré toutes les possibilités de notre modèle nous discuterons ici des améliorations à apporter à notre modèle.&lt;br /&gt;
&lt;br /&gt;
La première des améliorations que nous pourrions apporter pourrait être l’introduction de comportements avec un historique des actions passées de leurs voisins. Cela nous permettrait d’avoir des stratégies plus complexes à étudier.&lt;br /&gt;
&lt;br /&gt;
La deuxième amélioration que nous pourrions apporter serait une amélioration au niveau du code. On proposerait de faire en sorte d’avoir un objet Stratégie qui se passerait de prisonnier en prisonnier et grâce à la programmation objet on pourrait créer des Stratégies variées avec peu de changements dans la structure du programme.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
&lt;br /&gt;
[http://cormas.cirad.fr/fr/applica/dps.htm Lien vers le site du cormas]&lt;br /&gt;
&lt;br /&gt;
[https://www.researchgate.net/publication/216634494_Evolutionary_Games_and_Spatial_Chaos Lien vers l&#039;article original]&lt;/div&gt;</summary>
		<author><name>Theodet</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11787</id>
		<title>Génération et résolution de labyrinthes II</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11787"/>
		<updated>2019-05-19T21:09:30Z</updated>

		<summary type="html">&lt;p&gt;Theodet : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__FORCETOC__[[Fichier:labyrinthe_photo.png|vignette|300px|Labyrinthe généré avec Kruskal et résolu avec le parcours en profondeur. En route foncé, l&#039;entrée. En vert, la sortie. En bleu, le chemin. En rouge clair, les cellules visitées lors de la résolution.|alt=&amp;quot;Labyrinthe&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
On veut générer des labyrinthes aussi grands et complexes que possible, avec des murs dans une grille carré. Comment faire pour qu&#039;il y ait toujours un chemin de l&#039;entrée à la sortie ? Comment faire pour qu&#039;il n&#039;y ait qu&#039;un chemin ? Et comment trouver la sortie quand on est perdu dans le labyrinthe ?&lt;br /&gt;
&lt;br /&gt;
== Représentation ==&lt;br /&gt;
&lt;br /&gt;
=== Propriétés ===&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe est une grille de cellules reliées, ou non, entre elles.&lt;br /&gt;
&lt;br /&gt;
Deux cellules sont reliées entre elles par une &#039;&#039;&#039;porte&#039;&#039;&#039;, ou séparées par un &#039;&#039;&#039;mur&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Tout labyrinthe a &#039;&#039;&#039;une entrée&#039;&#039;&#039; et &#039;&#039;&#039;une sortie&#039;&#039;&#039;, et quelle que soit l&#039;entrée ou la sortie, le chemin entre ces deux cellules est &#039;&#039;&#039;unique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Modélisation en graphe ===&lt;br /&gt;
&lt;br /&gt;
En théorie des graphes, un graphe est un ensemble de &#039;&#039;&#039;points&#039;&#039;&#039; (ou nœuds ou sommets) reliés ensemble par des &#039;&#039;&#039;lignes&#039;&#039;&#039; (ou liens ou arêtes).&lt;br /&gt;
&lt;br /&gt;
[[Fichier:graphe_cyclique.png|vignette|left|300px|Exemple de graphe connexe cyclique non orienté|alt=Graphe cyclique]]&lt;br /&gt;
&lt;br /&gt;
Un graphe peut être &#039;&#039;&#039;connexe&#039;&#039;&#039; (en un seul morceau) ou &#039;&#039;&#039;non connexe&#039;&#039;&#039; (en plusieurs morceaux).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Un graphe peut aussi être &#039;&#039;&#039;cyclique&#039;&#039;&#039; si les points sont reliés en formant une boucle ou &#039;&#039;&#039;acyclique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Enfin, un graphe peut être &#039;&#039;&#039;orienté&#039;&#039;&#039; (si les arêtes sont à sens unique) ou &#039;&#039;&#039;non orienté&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Arbre.PNG|vignette|left|300px|Exemple d&#039;arbre|alt=Arbre]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Un &#039;&#039;&#039;arbre&#039;&#039;&#039; est un graphe connexe, acyclique et non orienté.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
En plaçant un point sur chaque cellule de notre labyrinthe, et en reliant deux cellules séparées par une porte, on peut dessiner un arbre à partir de n&#039;importe quel labyrinthe.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:labyrinthe_avec_arbre.png|vignette|centre|300px|Exemple de labyrinthe avec son arbre. Pour plus de simplicité, on attribue à chaque nœud une position.|alt=Labyrinthe avec arbre]]&lt;br /&gt;
&lt;br /&gt;
== Génération ==&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe rectangulaire de largeur &amp;lt;math&amp;gt; L &amp;lt;/math&amp;gt; et de hauteur &amp;lt;math&amp;gt; H &amp;lt;/math&amp;gt; contient exactement &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; portes.&lt;br /&gt;
&lt;br /&gt;
Du point de vue du graphe, il y a donc &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; arêtes.&lt;br /&gt;
&lt;br /&gt;
Maintenant, comment répartir toutes ces portes de façon à ce que toutes les cellules soient accessibles et qu&#039;il n&#039;existe qu&#039;un unique chemin entre l&#039;entrée et la sortie ?&lt;br /&gt;
&lt;br /&gt;
De nombreux algorithmes existent, dont le parcours en profondeur et l&#039;algorithme de Kruskal.&lt;br /&gt;
Chaque algorithme est différent et produit des labyrinthes visuellement différents.&lt;br /&gt;
&lt;br /&gt;
En effet, si nous comparons un labyrinthe généré avec l&#039;algorithme du parcours en profondeur à un labyrinthe généré avec l&#039;algorithme de Kruskal, bien qu&#039;ils aient tous les deux une solution unique, ils apparaissent néanmoins différents visuellement.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:recursive_backtracker_comparaison.png|vignette|left|500px|Parcours en profondeur.&amp;lt;br&amp;gt;On remarque des chemins proprement dessinés.|alt=Parcours en profondeur]]&lt;br /&gt;
[[Fichier:kruskal_comparaison.png|vignette|right|500px|Algorithme de Kruskal.&amp;lt;br&amp;gt;On remarque des murs de 1 de longueur çà et là.|alt=Kruskal]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Parcours en profondeur ===&lt;br /&gt;
&lt;br /&gt;
[[Fichier:recursive_backtracker.gif|vignette|left|500px|Illustration du parcours en profondeur|alt=Parcours en profondeur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;algorithme du parcours en profondeur (&amp;quot;recursive backtracker&amp;quot; en anglais), on commence sur une cellule aléatoire dans le labyrinthe.&lt;br /&gt;
&lt;br /&gt;
On se dirige dans une direction aléatoire et on casse le mur en face, tout en marquant la cellule précédente comme visitée.&lt;br /&gt;
&lt;br /&gt;
Lorsque aucune direction n&#039;est disponible, on remonte à la position précédente.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:pile.png|vignette|300px|Représentation d&#039;une pile de positions|alt=Pile]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pour sauvegarder l&#039;historique des positions, on peut utiliser une &#039;&#039;&#039;pile&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Une pile est une liste dans laquelle seul le dernier élément peut être récupéré.&lt;br /&gt;
&lt;br /&gt;
Une pile contient 2 méthodes :&lt;br /&gt;
* push(elem) : ajoute elem à la pile&lt;br /&gt;
* pop() -&amp;gt; elem : retourne le dernier élément de la pile (elem dans notre cas)&lt;br /&gt;
&lt;br /&gt;
Dans mon implémentation de la pile, une erreur est levée si l&#039;on appelle la méthode pop sur une pile vide.&lt;br /&gt;
&lt;br /&gt;
=== Kruskal ===&lt;br /&gt;
&lt;br /&gt;
[[Fichier:kruskal.gif|vignette|left|500px|Illustration de l&#039;algorithme de Kruskal.|alt=Kruskal]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Alors que pour le parcours en profondeur on partait des cellules, l&#039;algorithme de Kruskal s&#039;applique sur des murs.&lt;br /&gt;
&lt;br /&gt;
On attribue à chaque cellule un identifiant unique.&lt;br /&gt;
&lt;br /&gt;
On choisit un mur aléatoire. Si les cellules séparées par ce mur ont des identifiants différents, on leur associe le même identifiant et on casse le mur.&lt;br /&gt;
&lt;br /&gt;
Sinon, on passe à un autre mur.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:union_find.png|vignette|300px|Représentation d&#039;une structure Union-Find avec find(a,b) et find(b,c).|alt=Union-Find]]&lt;br /&gt;
&lt;br /&gt;
Pour mettre en œuvre cet algorithme, on utilise une structure de données appelée &#039;&#039;&#039;Union-Find&#039;&#039;&#039;, qui permet de mettre en relation des éléments partageant un même représentant (ou un même identifiant).&lt;br /&gt;
&lt;br /&gt;
Il existe plusieurs variantes d&#039;Union-Find, dont notamment la compression de chemin, qui permet de n&#039;avoir qu&#039;un ou deux éléments à parcourir pour obtenir le représentant d&#039;un élément.&lt;br /&gt;
&lt;br /&gt;
Union-Find fonctionne comme un arbre. &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; a un représentant &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;, etc..., qui lui même a un représentant &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt;, qui est son propre représentant.&lt;br /&gt;
&lt;br /&gt;
Union-Find est composé de deux méthodes :&lt;br /&gt;
* union(a, b) : associe à &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; et &amp;lt;math&amp;gt;b&amp;lt;/math&amp;gt; le même représentant, par exemple &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; le représentant de &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt;&lt;br /&gt;
* find(a) -&amp;gt; &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; : tant que l&#039;élément n&#039;est pas son propre représentant, on applique find au représentant de l&#039;élément.&amp;lt;br&amp;gt; On commence donc par find(a), puis find(A) (si &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; est le représentant de &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt;), etc... La méthode de la compression de chemin permet d&#039;éviter trop de récursivité en écrivant : représentant de &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; := &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Labyrinthes cycliques ===&lt;br /&gt;
&lt;br /&gt;
Il est possible, en retirant un certain pourcentage de murs, de créer des labyrinthes cycliques à partir des labyrinthes acycliques générés auparavant.&lt;br /&gt;
&lt;br /&gt;
Cependant, certains algorithmes de résolution n&#039;adopteront pas le même comportement.&lt;br /&gt;
&lt;br /&gt;
== Résolution ==&lt;br /&gt;
&lt;br /&gt;
Il existe là encore de nombreux algorithmes de résolution de labyrinthes, plus ou moins efficaces, et surtout ne fonctionnant pas tous dans les mêmes conditions.&lt;br /&gt;
&lt;br /&gt;
=== Parcours en profondeur ===&lt;br /&gt;
&lt;br /&gt;
Cet algorithme est quasiment identique à celui du parcours en profondeur pour la génération.&lt;br /&gt;
&lt;br /&gt;
Il est très efficace et trouvera une solution en minimisant le nombre de cases visitées.&lt;br /&gt;
&lt;br /&gt;
Il s&#039;adapte aux labyrinthes cycliques. En cas de boucle, il ne fera pas la boucle vu que l&#039;intersection a déjà été visitées, il reviendra sur ses pas.&lt;br /&gt;
&lt;br /&gt;
Il s&#039;adapte aux labyrinthes sans solution. En effet, s&#039;il n&#039;y a pas de sortie, il va revenir à sa position de départ sans position précédente (pile vide) et en ayant parcouru toutes les cases.&lt;br /&gt;
&lt;br /&gt;
=== Mur droit ===&lt;br /&gt;
&lt;br /&gt;
Cet algorithme va suivre de la main droite le mur de droite.&lt;br /&gt;
&lt;br /&gt;
Il est relativement inefficace, et va visiter un grand nombre de cases.&lt;br /&gt;
&lt;br /&gt;
Il s&#039;adapte assez mal aux labyrinthes cycliques. En effet, si la sortie n&#039;est pas dans la même boucle que l&#039;entrée, il ne la trouvera jamais.&lt;br /&gt;
&lt;br /&gt;
Il ne s&#039;adapte pas aux labyrinthes sans solution, et fera le tour de la grille à l&#039;infini.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:labyrinthe_exp_exhaust.png|vignette|left|500px|Labyrinthe résolu en utilisant le parcours en profondeur. &amp;lt;br&amp;gt; 660 cellules visitées, 1179 déplacements, chemin de 142 cellules.|alt=Parcours en profondeur]]&lt;br /&gt;
[[Fichier:labyrinthe_right_hand.png|vignette|right|500px|Labyrinthe résolu en utilisant le mur droit. &amp;lt;br&amp;gt; 1068 cellules visitées, 1995 déplacements, chemin de 142 cellules.|alt=Mur droit]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Code source ==&lt;br /&gt;
&lt;br /&gt;
Mon projet total contenant plusieurs milliers de lignes de code réparties dans une dizaine de fichiers, je ne peux évidemment pas l&#039;insérer directement dans cette page.&lt;br /&gt;
&lt;br /&gt;
Le code source est disponible sur Github à [https://github.com/Rominos111/Labyrinthe_VISI201 cette adresse]&lt;br /&gt;
&lt;br /&gt;
Il suffit d&#039;avoir installé Python 3 et tkinter.&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
&lt;br /&gt;
Génération&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#Fusion_al%C3%A9atoire_de_chemins Kruskal (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Maze_generation_algorithm#Randomized_Kruskal&#039;s_algorithm Kruskal (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#Exploration_exhaustive Parcours en profondeur (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Maze_generation_algorithm#Randomized_Depth-First_Search Parcours en profondeur (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Résolution&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#R%C3%A9solution Résolution générale (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Maze_solving_algorithm#Wall_follower Mur droit (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Structures de données&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Union-find Union-Find / Disjoint-Set (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Stack_(abstract_data_type) Pile / Stack (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Queue_(abstract_data_type) File / Queue (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Python&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://docs.python.org/3.6/reference/datamodel.html Classes et types de variables personnalisés (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [http://effbot.org/tkinterbook/canvas.htm Canvas Tkinter (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;/div&gt;</summary>
		<author><name>Theodet</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11781</id>
		<title>Génération et résolution de labyrinthes II</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11781"/>
		<updated>2019-05-19T21:08:02Z</updated>

		<summary type="html">&lt;p&gt;Theodet : /* Kruskal */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__FORCETOC__[[Fichier:labyrinthe_photo.png|vignette|300px|Labyrinthe généré avec Kruskal et résolu avec le parcours en profondeur. En route foncé, l&#039;entrée. En vert, la sortie. En bleu, le chemin. En rouge clair, les cellules visitées lors de la résolution.|alt=&amp;quot;Labyrinthe&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
On veut générer des labyrinthes aussi grands et complexes que possible, avec des murs dans une grille carré. Comment faire pour qu&#039;il y ait toujours un chemin de l&#039;entrée à la sortie ? Comment faire pour qu&#039;il n&#039;y ait qu&#039;un chemin ? Et comment trouver la sortie quand on est perdu dans le labyrinthe ?&lt;br /&gt;
&lt;br /&gt;
== Représentation ==&lt;br /&gt;
&lt;br /&gt;
=== Propriétés ===&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe est une grille de cellules reliées, ou non, entre elles.&lt;br /&gt;
&lt;br /&gt;
Deux cellules sont reliées entre elles par une &#039;&#039;&#039;porte&#039;&#039;&#039;, ou séparées par un &#039;&#039;&#039;mur&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Tout labyrinthe a &#039;&#039;&#039;une entrée&#039;&#039;&#039; et &#039;&#039;&#039;une sortie&#039;&#039;&#039;, et quelle que soit l&#039;entrée ou la sortie, le chemin entre ces deux cellules est &#039;&#039;&#039;unique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Modélisation en graphe ===&lt;br /&gt;
&lt;br /&gt;
En théorie des graphes, un graphe est un ensemble de &#039;&#039;&#039;points&#039;&#039;&#039; (ou nœuds ou sommets) reliés ensemble par des &#039;&#039;&#039;lignes&#039;&#039;&#039; (ou liens ou arêtes).&lt;br /&gt;
&lt;br /&gt;
[[Fichier:graphe_cyclique.png|vignette|left|300px|Exemple de graphe connexe cyclique non orienté|alt=Graphe cyclique]]&lt;br /&gt;
&lt;br /&gt;
Un graphe peut être &#039;&#039;&#039;connexe&#039;&#039;&#039; (en un seul morceau) ou &#039;&#039;&#039;non connexe&#039;&#039;&#039; (en plusieurs morceaux).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Un graphe peut aussi être &#039;&#039;&#039;cyclique&#039;&#039;&#039; si les points sont reliés en formant une boucle ou &#039;&#039;&#039;acyclique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Enfin, un graphe peut être &#039;&#039;&#039;orienté&#039;&#039;&#039; (si les arêtes sont à sens unique) ou &#039;&#039;&#039;non orienté&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Arbre.PNG|vignette|left|300px|Exemple d&#039;arbre|alt=Arbre]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Un &#039;&#039;&#039;arbre&#039;&#039;&#039; est un graphe connexe, acyclique et non orienté.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
En plaçant un point sur chaque cellule de notre labyrinthe, et en reliant deux cellules séparées par une porte, on peut dessiner un arbre à partir de n&#039;importe quel labyrinthe.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:labyrinthe_avec_arbre.png|vignette|centre|300px|Exemple de labyrinthe avec son arbre. Pour plus de simplicité, on attribue à chaque nœud une position.|alt=Labyrinthe avec arbre]]&lt;br /&gt;
&lt;br /&gt;
== Génération ==&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe rectangulaire de largeur &amp;lt;math&amp;gt; L &amp;lt;/math&amp;gt; et de hauteur &amp;lt;math&amp;gt; H &amp;lt;/math&amp;gt; contient exactement &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; portes.&lt;br /&gt;
&lt;br /&gt;
Du point de vue du graphe, il y a donc &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; arêtes.&lt;br /&gt;
&lt;br /&gt;
Maintenant, comment répartir toutes ces portes de façon à ce que toutes les cellules soient accessibles et qu&#039;il n&#039;existe qu&#039;un unique chemin entre l&#039;entrée et la sortie ?&lt;br /&gt;
&lt;br /&gt;
De nombreux algorithmes existent, dont le parcours en profondeur et l&#039;algorithme de Kruskal.&lt;br /&gt;
Chaque algorithme est différent et produit des labyrinthes visuellement différents.&lt;br /&gt;
&lt;br /&gt;
En effet, si nous comparons un labyrinthe généré avec l&#039;algorithme du parcours en profondeur à un labyrinthe généré avec l&#039;algorithme de Kruskal, bien qu&#039;ils aient tous les deux une solution unique, ils apparaissent néanmoins différents visuellement.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:recursive_backtracker_comparaison.png|vignette|left|500px|Parcours en profondeur.&amp;lt;br&amp;gt;On remarque des chemins proprement dessinés.|alt=Parcours en profondeur]]&lt;br /&gt;
[[Fichier:kruskal_comparaison.png|vignette|right|500px|Algorithme de Kruskal.&amp;lt;br&amp;gt;On remarque des murs de 1 de longueur çà et là.|alt=Kruskal]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Parcours en profondeur ===&lt;br /&gt;
&lt;br /&gt;
[[Fichier:recursive_backtracker.gif|vignette|left|500px|Illustration du parcours en profondeur|alt=Parcours en profondeur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;algorithme du parcours en profondeur (&amp;quot;recursive backtracker&amp;quot; en anglais), on commence sur une cellule aléatoire dans le labyrinthe.&lt;br /&gt;
&lt;br /&gt;
On se dirige dans une direction aléatoire et on casse le mur en face, tout en marquant la cellule précédente comme visitée.&lt;br /&gt;
&lt;br /&gt;
Lorsque aucune direction n&#039;est disponible, on remonte à la position précédente.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:pile.png|vignette|300px|Représentation d&#039;une pile de positions|alt=Pile]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pour sauvegarder l&#039;historique des positions, on peut utiliser une &#039;&#039;&#039;pile&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Une pile est une liste dans laquelle seul le dernier élément peut être récupéré.&lt;br /&gt;
&lt;br /&gt;
Une pile contient 2 méthodes :&lt;br /&gt;
* push(elem) : ajoute elem à la pile&lt;br /&gt;
* pop() -&amp;gt; elem : retourne le dernier élément de la pile (elem dans notre cas)&lt;br /&gt;
&lt;br /&gt;
Dans mon implémentation de la pile, une erreur est levée si l&#039;on appelle la méthode pop sur une pile vide.&lt;br /&gt;
&lt;br /&gt;
=== Kruskal ===&lt;br /&gt;
&lt;br /&gt;
[[Fichier:kruskal.gif|vignette|left|500px|Illustration de l&#039;algorithme de Kruskal.|alt=Kruskal]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Alors que pour le parcours en profondeur on partait des cellules, l&#039;algorithme de Kruskal s&#039;applique sur des murs.&lt;br /&gt;
&lt;br /&gt;
On attribue à chaque cellule un identifiant unique.&lt;br /&gt;
&lt;br /&gt;
On choisit un mur aléatoire. Si les cellules séparées par ce mur ont des identifiants différents, on leur associe le même identifiant et on casse le mur.&lt;br /&gt;
&lt;br /&gt;
Sinon, on passe à un autre mur.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:union_find.png|vignette|300px|Représentation d&#039;une structure Union-Find avec find(a,b) et find(b,c).|alt=Union-Find]]&lt;br /&gt;
&lt;br /&gt;
Pour mettre en œuvre cet algorithme, on utilise une structure de données appelée &#039;&#039;&#039;Union-Find&#039;&#039;&#039;, qui permet de mettre en relation des éléments partageant un même représentant (ou un même identifiant).&lt;br /&gt;
&lt;br /&gt;
Il existe plusieurs variantes d&#039;Union-Find, dont notamment la compression de chemin, qui permet de n&#039;avoir qu&#039;un ou deux éléments à parcourir pour obtenir le représentant d&#039;un élément.&lt;br /&gt;
&lt;br /&gt;
Union-Find fonctionne comme un arbre. &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; a un représentant &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;, etc..., qui lui même a un représentant &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt;, qui est son propre représentant.&lt;br /&gt;
&lt;br /&gt;
Union-Find est composé de deux méthodes :&lt;br /&gt;
* union(a, b) : associe à &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; et &amp;lt;math&amp;gt;b&amp;lt;/math&amp;gt; le même représentant, par exemple &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; le représentant de &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt;&lt;br /&gt;
* find(a) -&amp;gt; &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; : tant que l&#039;élément n&#039;est pas son propre représentant, on applique find au représentant de l&#039;élément.&amp;lt;br&amp;gt; On commence donc par find(a), puis find(A) (si &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; est le représentant de &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt;), etc... La méthode de la compression de chemin permet d&#039;éviter trop de récursivité en écrivant : représentant de &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; := &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Labyrinthes cycliques ===&lt;br /&gt;
&lt;br /&gt;
Il est possible, en retirant un certain pourcentage de murs, de créer des labyrinthes cycliques à partir des labyrinthes acycliques générés auparavant.&lt;br /&gt;
&lt;br /&gt;
Cependant, certains algorithmes de résolution n&#039;adopteront pas le même comportement.&lt;br /&gt;
&lt;br /&gt;
== Résolution ==&lt;br /&gt;
&lt;br /&gt;
Il existe là encore de nombreux algorithmes de résolution de labyrinthes, plus ou moins efficaces, et surtout ne fonctionnant pas tous dans les mêmes conditions.&lt;br /&gt;
&lt;br /&gt;
=== Parcours en profondeur ===&lt;br /&gt;
&lt;br /&gt;
Cet algorithme est quasiment identique à celui du parcours en profondeur pour la génération.&lt;br /&gt;
&lt;br /&gt;
Il est très efficace et trouvera une solution en minimisant le nombre de cases visitées.&lt;br /&gt;
&lt;br /&gt;
Il s&#039;adapte aux labyrinthes cycliques. En cas de boucle, il ne fera pas la boucle vu que l&#039;intersection a déjà été visitées, il reviendra sur ses pas.&lt;br /&gt;
&lt;br /&gt;
Il s&#039;adapte aux labyrinthes sans solution. En effet, s&#039;il n&#039;y a pas de sortie, il va revenir à sa position de départ sans position précédente (pile vide) et en ayant parcouru toutes les cases.&lt;br /&gt;
&lt;br /&gt;
=== Mur droit ===&lt;br /&gt;
&lt;br /&gt;
Cet algorithme va suivre de la main droite le mur de droite.&lt;br /&gt;
&lt;br /&gt;
Il est relativement inefficace, et va visiter un grand nombre de cases.&lt;br /&gt;
&lt;br /&gt;
Il s&#039;adapte assez mal aux labyrinthes cycliques. En effet, si la sortie n&#039;est pas dans la même boucle que l&#039;entrée, il ne la trouvera jamais.&lt;br /&gt;
&lt;br /&gt;
Il ne s&#039;adapte pas aux labyrinthes sans solution, et fera le tour de la grille à l&#039;infini.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:labyrinthe_exp_exhaust.png|vignette|left|500px|Labyrinthe résolu en utilisant le parcours en profondeur. &amp;lt;br&amp;gt; 660 cellules visitées, 1179 déplacements, chemin de 142 cellules.|alt=Parcours en profondeur]]&lt;br /&gt;
[[Fichier:labyrinthe_right_hand.png|vignette|right|500px|Labyrinthe résolu en utilisant le mur droit. &amp;lt;br&amp;gt; 1068 cellules visitées, 1995 déplacements, chemin de 142 cellules.|alt=Mur droit]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Affichage ==&lt;br /&gt;
&lt;br /&gt;
tkinter &lt;br /&gt;
&lt;br /&gt;
[https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#Exploration_exhaustive tkinter]&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
Mon projet total contenant plusieurs milliers de lignes de code réparties dans une dizaine de fichiers, je ne peux évidemment pas l&#039;insérer directement dans cette page.&lt;br /&gt;
&lt;br /&gt;
Le code source est disponible sur Github à [https://github.com/Rominos111/Labyrinthe_VISI201 cette adresse]&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
&lt;br /&gt;
Génération&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#Fusion_al%C3%A9atoire_de_chemins Kruskal (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Maze_generation_algorithm#Randomized_Kruskal&#039;s_algorithm Kruskal (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#Exploration_exhaustive Parcours en profondeur (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Maze_generation_algorithm#Randomized_Depth-First_Search Parcours en profondeur (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Résolution&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#R%C3%A9solution Résolution générale (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Maze_solving_algorithm#Wall_follower Mur droit (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Structures de données&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Union-find Union-Find / Disjoint-Set (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Stack_(abstract_data_type) Pile / Stack (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Queue_(abstract_data_type) File / Queue (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Python&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://docs.python.org/3.6/reference/datamodel.html Classes et types de variables personnalisés (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [http://effbot.org/tkinterbook/canvas.htm Canvas Tkinter (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;/div&gt;</summary>
		<author><name>Theodet</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fichier:Union_find.png&amp;diff=11779</id>
		<title>Fichier:Union find.png</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fichier:Union_find.png&amp;diff=11779"/>
		<updated>2019-05-19T20:25:40Z</updated>

		<summary type="html">&lt;p&gt;Theodet : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Theodet</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11778</id>
		<title>Génération et résolution de labyrinthes II</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11778"/>
		<updated>2019-05-19T20:20:52Z</updated>

		<summary type="html">&lt;p&gt;Theodet : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__FORCETOC__[[Fichier:labyrinthe_photo.png|vignette|300px|Labyrinthe généré avec Kruskal et résolu avec le parcours en profondeur. En route foncé, l&#039;entrée. En vert, la sortie. En bleu, le chemin. En rouge clair, les cellules visitées lors de la résolution.|alt=&amp;quot;Labyrinthe&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
On veut générer des labyrinthes aussi grands et complexes que possible, avec des murs dans une grille carré. Comment faire pour qu&#039;il y ait toujours un chemin de l&#039;entrée à la sortie ? Comment faire pour qu&#039;il n&#039;y ait qu&#039;un chemin ? Et comment trouver la sortie quand on est perdu dans le labyrinthe ?&lt;br /&gt;
&lt;br /&gt;
== Représentation ==&lt;br /&gt;
&lt;br /&gt;
=== Propriétés ===&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe est une grille de cellules reliées, ou non, entre elles.&lt;br /&gt;
&lt;br /&gt;
Deux cellules sont reliées entre elles par une &#039;&#039;&#039;porte&#039;&#039;&#039;, ou séparées par un &#039;&#039;&#039;mur&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Tout labyrinthe a &#039;&#039;&#039;une entrée&#039;&#039;&#039; et &#039;&#039;&#039;une sortie&#039;&#039;&#039;, et quelle que soit l&#039;entrée ou la sortie, le chemin entre ces deux cellules est &#039;&#039;&#039;unique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Modélisation en graphe ===&lt;br /&gt;
&lt;br /&gt;
En théorie des graphes, un graphe est un ensemble de &#039;&#039;&#039;points&#039;&#039;&#039; (ou nœuds ou sommets) reliés ensemble par des &#039;&#039;&#039;lignes&#039;&#039;&#039; (ou liens ou arêtes).&lt;br /&gt;
&lt;br /&gt;
[[Fichier:graphe_cyclique.png|vignette|left|300px|Exemple de graphe connexe cyclique non orienté|alt=Graphe cyclique]]&lt;br /&gt;
&lt;br /&gt;
Un graphe peut être &#039;&#039;&#039;connexe&#039;&#039;&#039; (en un seul morceau) ou &#039;&#039;&#039;non connexe&#039;&#039;&#039; (en plusieurs morceaux).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Un graphe peut aussi être &#039;&#039;&#039;cyclique&#039;&#039;&#039; si les points sont reliés en formant une boucle ou &#039;&#039;&#039;acyclique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Enfin, un graphe peut être &#039;&#039;&#039;orienté&#039;&#039;&#039; (si les arêtes sont à sens unique) ou &#039;&#039;&#039;non orienté&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Arbre.PNG|vignette|left|300px|Exemple d&#039;arbre|alt=Arbre]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Un &#039;&#039;&#039;arbre&#039;&#039;&#039; est un graphe connexe, acyclique et non orienté.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
En plaçant un point sur chaque cellule de notre labyrinthe, et en reliant deux cellules séparées par une porte, on peut dessiner un arbre à partir de n&#039;importe quel labyrinthe.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:labyrinthe_avec_arbre.png|vignette|centre|300px|Exemple de labyrinthe avec son arbre. Pour plus de simplicité, on attribue à chaque nœud une position.|alt=Labyrinthe avec arbre]]&lt;br /&gt;
&lt;br /&gt;
== Génération ==&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe rectangulaire de largeur &amp;lt;math&amp;gt; L &amp;lt;/math&amp;gt; et de hauteur &amp;lt;math&amp;gt; H &amp;lt;/math&amp;gt; contient exactement &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; portes.&lt;br /&gt;
&lt;br /&gt;
Du point de vue du graphe, il y a donc &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; arêtes.&lt;br /&gt;
&lt;br /&gt;
Maintenant, comment répartir toutes ces portes de façon à ce que toutes les cellules soient accessibles et qu&#039;il n&#039;existe qu&#039;un unique chemin entre l&#039;entrée et la sortie ?&lt;br /&gt;
&lt;br /&gt;
De nombreux algorithmes existent, dont le parcours en profondeur et l&#039;algorithme de Kruskal.&lt;br /&gt;
Chaque algorithme est différent et produit des labyrinthes visuellement différents.&lt;br /&gt;
&lt;br /&gt;
En effet, si nous comparons un labyrinthe généré avec l&#039;algorithme du parcours en profondeur à un labyrinthe généré avec l&#039;algorithme de Kruskal, bien qu&#039;ils aient tous les deux une solution unique, ils apparaissent néanmoins différents visuellement.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:recursive_backtracker_comparaison.png|vignette|left|500px|Parcours en profondeur.&amp;lt;br&amp;gt;On remarque des chemins proprement dessinés.|alt=Parcours en profondeur]]&lt;br /&gt;
[[Fichier:kruskal_comparaison.png|vignette|right|500px|Algorithme de Kruskal.&amp;lt;br&amp;gt;On remarque des murs de 1 de longueur çà et là.|alt=Kruskal]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Parcours en profondeur ===&lt;br /&gt;
&lt;br /&gt;
[[Fichier:recursive_backtracker.gif|vignette|left|500px|Illustration du parcours en profondeur|alt=Parcours en profondeur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;algorithme du parcours en profondeur (&amp;quot;recursive backtracker&amp;quot; en anglais), on commence sur une cellule aléatoire dans le labyrinthe.&lt;br /&gt;
&lt;br /&gt;
On se dirige dans une direction aléatoire et on casse le mur en face, tout en marquant la cellule précédente comme visitée.&lt;br /&gt;
&lt;br /&gt;
Lorsque aucune direction n&#039;est disponible, on remonte à la position précédente.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:pile.png|vignette|300px|Représentation d&#039;une pile de positions|alt=Pile]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pour sauvegarder l&#039;historique des positions, on peut utiliser une &#039;&#039;&#039;pile&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Une pile est une liste dans laquelle seul le dernier élément peut être récupéré.&lt;br /&gt;
&lt;br /&gt;
Une pile contient 2 méthodes :&lt;br /&gt;
* push(elem) : ajoute elem à la pile&lt;br /&gt;
* pop() -&amp;gt; elem : retourne le dernier élément de la pile (elem dans notre cas)&lt;br /&gt;
&lt;br /&gt;
Dans mon implémentation de la pile, une erreur est levée si l&#039;on appelle la méthode pop sur une pile vide.&lt;br /&gt;
&lt;br /&gt;
=== Kruskal ===&lt;br /&gt;
&lt;br /&gt;
[[Fichier:kruskal.gif|vignette|left|500px|Illustration de l&#039;algorithme de Kruskal|alt=Kruskal]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Alors que pour le parcours en profondeur on partait des cellules, l&#039;algorithme de Kruskal s&#039;applique sur des murs.&lt;br /&gt;
&lt;br /&gt;
On attribue à chaque cellule un identifiant unique.&lt;br /&gt;
&lt;br /&gt;
On choisit un mur aléatoire. Si les cellules séparées par ce mur ont des identifiants différents, on leur associe le même identifiant et on casse le mur.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:union_find.png|vignette|300px|Représentation d&#039;une pile de positions|alt=Pile]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Labyrinthes cycliques ===&lt;br /&gt;
&lt;br /&gt;
Il est possible, en retirant un certain pourcentage de murs, de créer des labyrinthes cycliques à partir des labyrinthes acycliques générés auparavant.&lt;br /&gt;
&lt;br /&gt;
Cependant, certains algorithmes de résolution n&#039;adopteront pas le même comportement.&lt;br /&gt;
&lt;br /&gt;
== Résolution ==&lt;br /&gt;
&lt;br /&gt;
Il existe là encore de nombreux algorithmes de résolution de labyrinthes, plus ou moins efficaces, et surtout ne fonctionnant pas tous dans les mêmes conditions.&lt;br /&gt;
&lt;br /&gt;
=== Parcours en profondeur ===&lt;br /&gt;
&lt;br /&gt;
Cet algorithme est quasiment identique à celui du parcours en profondeur pour la génération.&lt;br /&gt;
&lt;br /&gt;
Il est très efficace et trouvera une solution en minimisant le nombre de cases visitées.&lt;br /&gt;
&lt;br /&gt;
Il s&#039;adapte aux labyrinthes cycliques. En cas de boucle, il ne fera pas la boucle vu que l&#039;intersection a déjà été visitées, il reviendra sur ses pas.&lt;br /&gt;
&lt;br /&gt;
Il s&#039;adapte aux labyrinthes sans solution. En effet, s&#039;il n&#039;y a pas de sortie, il va revenir à sa position de départ sans position précédente (pile vide) et en ayant parcouru toutes les cases.&lt;br /&gt;
&lt;br /&gt;
=== Mur droit ===&lt;br /&gt;
&lt;br /&gt;
Cet algorithme va suivre de la main droite le mur de droite.&lt;br /&gt;
&lt;br /&gt;
Il est relativement inefficace, et va visiter un grand nombre de cases.&lt;br /&gt;
&lt;br /&gt;
Il s&#039;adapte assez mal aux labyrinthes cycliques. En effet, si la sortie n&#039;est pas dans la même boucle que l&#039;entrée, il ne la trouvera jamais.&lt;br /&gt;
&lt;br /&gt;
Il ne s&#039;adapte pas aux labyrinthes sans solution, et fera le tour de la grille à l&#039;infini.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:labyrinthe_exp_exhaust.png|vignette|left|500px|Labyrinthe résolu en utilisant le parcours en profondeur. &amp;lt;br&amp;gt; 660 cellules visitées, 1179 déplacements, chemin de 142 cellules.|alt=Parcours en profondeur]]&lt;br /&gt;
[[Fichier:labyrinthe_right_hand.png|vignette|right|500px|Labyrinthe résolu en utilisant le mur droit. &amp;lt;br&amp;gt; 1068 cellules visitées, 1995 déplacements, chemin de 142 cellules.|alt=Mur droit]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Affichage ==&lt;br /&gt;
&lt;br /&gt;
tkinter &lt;br /&gt;
&lt;br /&gt;
[https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#Exploration_exhaustive tkinter]&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
Mon projet total contenant plusieurs milliers de lignes de code réparties dans une dizaine de fichiers, je ne peux évidemment pas l&#039;insérer directement dans cette page.&lt;br /&gt;
&lt;br /&gt;
Le code source est disponible sur Github à [https://github.com/Rominos111/Labyrinthe_VISI201 cette adresse]&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
&lt;br /&gt;
Génération&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#Fusion_al%C3%A9atoire_de_chemins Kruskal (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Maze_generation_algorithm#Randomized_Kruskal&#039;s_algorithm Kruskal (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#Exploration_exhaustive Parcours en profondeur (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Maze_generation_algorithm#Randomized_Depth-First_Search Parcours en profondeur (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Résolution&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#R%C3%A9solution Résolution générale (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Maze_solving_algorithm#Wall_follower Mur droit (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Structures de données&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Union-find Union-Find / Disjoint-Set (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Stack_(abstract_data_type) Pile / Stack (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Queue_(abstract_data_type) File / Queue (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Python&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://docs.python.org/3.6/reference/datamodel.html Classes et types de variables personnalisés (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [http://effbot.org/tkinterbook/canvas.htm Canvas Tkinter (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;/div&gt;</summary>
		<author><name>Theodet</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Rest_%26_Pub-Sub_:_protocole_hybride_pour_l%27IoT&amp;diff=11777</id>
		<title>Rest &amp; Pub-Sub : protocole hybride pour l&#039;IoT</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Rest_%26_Pub-Sub_:_protocole_hybride_pour_l%27IoT&amp;diff=11777"/>
		<updated>2019-05-19T19:28:49Z</updated>

		<summary type="html">&lt;p&gt;Theodet : /* Introduction */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.&lt;br /&gt;
&lt;br /&gt;
== MQTT ==&lt;br /&gt;
MQTT, Message Queuing Telemetry Transport, est un protocole publish/subscribe se basant sur le protocole TCP/IP.&lt;br /&gt;
Il a été créé par Andy Stanford-Clark et Arlen Nipper.&lt;br /&gt;
&lt;br /&gt;
De façon concrète, MQTT permet à des appareils de publier des informations sur un sujet donné sur un broker (un serveur qui fonctionne comme un coursier) qui va les retransmettre aux appareils abonnés à ce sujet. &lt;br /&gt;
 &lt;br /&gt;
[[Fichier:Fonctionnement broker mqtt.png|600px]]&lt;br /&gt;
&lt;br /&gt;
MQTT gère aussi la qualité de service (d&#039;une qualité 0 à une qualité 2):&lt;br /&gt;
&lt;br /&gt;
Qualité 0: le client qui publie une donnée ne reçoit aucune information par rapport à la confirmation de son arrivé.&lt;br /&gt;
&lt;br /&gt;
Qualité 1: le client qui publie reçoit la confirmation ou non que la donnée publier à été reçu par le broker.&lt;br /&gt;
&lt;br /&gt;
Qualité 2: le client qui publie reçoit la confirmation ou non que la donnée publier à été reçu par le broker ainsi qu&#039;un message lui indiquant que le client qui s&#039;abonne à reçu la donnée.&lt;br /&gt;
===Mosquitto===&lt;br /&gt;
Mosquitto est un broker open-source qui se sert du protocole MQTT. Il permet une fois installé de se familiarisé avec MQTT et le &amp;quot;publish/subscribe&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
nous nous en somme servit ici en publiant en localhost:&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Mosquitto exemple.png]]&lt;br /&gt;
&lt;br /&gt;
sur un premier terminal on s&#039;abonne à un topic &amp;quot;température&amp;quot; et sur un deuxième terminal, on publie ensuite sur ce même topic des nombres (qui s&#039;apparentent à des température). Au fur et à mesure que nous publions ces informations, nous les recevons sur le premier terminal. &lt;br /&gt;
Mosquitto remplit bien ici son rôle de broker.&lt;br /&gt;
&lt;br /&gt;
===Pub/Sub avec Python===&lt;br /&gt;
&lt;br /&gt;
Nous avons ensuite développer un client &#039;&#039;publisher&#039;&#039; et un client &#039;&#039;subscriber&#039;&#039; en python grâce à la librairie paho-mqtt.&lt;br /&gt;
Pour plus de simplicité et éviter des problèmes de timing, nous avons tout regrouper en un seul programme:&lt;br /&gt;
&lt;br /&gt;
    import paho.mqtt.client as mqtt&lt;br /&gt;
    import time&lt;br /&gt;
    &lt;br /&gt;
    broker=&amp;quot;test.mosquitto.org&amp;quot;&lt;br /&gt;
    &lt;br /&gt;
    def envoi_message(client, QoS, message):&lt;br /&gt;
        print(&amp;quot;message reçu :&amp;quot;, str(message.payload.decode(&amp;quot;utf-8&amp;quot;)))&lt;br /&gt;
    &lt;br /&gt;
    client= mqtt.Client(&amp;quot;client_test&amp;quot;)&lt;br /&gt;
    client.on_message=envoi_message&lt;br /&gt;
    &lt;br /&gt;
    client.connect(broker)&lt;br /&gt;
    print(&amp;quot;connection&amp;quot;)&lt;br /&gt;
    client.loop_start()&lt;br /&gt;
    client.subscribe(&amp;quot;Cafetière/temperature_cafe&amp;quot;)&lt;br /&gt;
    print(&amp;quot;Abonnement...&amp;quot;)&lt;br /&gt;
    time.sleep(1)&lt;br /&gt;
    pub= input(&amp;quot;entrez une température (un nombre):&amp;quot;)&lt;br /&gt;
    print(&amp;quot;Publication...&amp;quot;)&lt;br /&gt;
    time.sleep(1)&lt;br /&gt;
    client.publish(&amp;quot;Cafetière/temperature_cafe&amp;quot;,pub +&amp;quot;°C&amp;quot;)&lt;br /&gt;
    time.sleep(1)&lt;br /&gt;
    client.disconnect()&lt;br /&gt;
    print(&amp;quot;deconnection&amp;quot;)&lt;br /&gt;
    client.loop_stop()&lt;br /&gt;
Comme broker, nous nous somme servit ici d&#039;un broker mit en libre service par mosquitto.&lt;br /&gt;
&lt;br /&gt;
==REST==&lt;br /&gt;
REST (Representational State Transfer) aussi appeler restful est une architecture logiciel inventer par Roy Fielding qui se sert des verbes HTTP comme identifiant des opérations et des réponses HTTP comme représentation des ressources.&lt;br /&gt;
&lt;br /&gt;
Une architecture REST est définit par 5 règles/contraintes :&lt;br /&gt;
&lt;br /&gt;
- Client–serveur&lt;br /&gt;
&lt;br /&gt;
- Sans état&lt;br /&gt;
&lt;br /&gt;
- Avec mise en cache&lt;br /&gt;
&lt;br /&gt;
- En couches&lt;br /&gt;
&lt;br /&gt;
- Interface uniforme&lt;br /&gt;
&lt;br /&gt;
===Service pub/sub avec REST===&lt;br /&gt;
On peut réaliser un équivalent de service pub/sub avec REST avec des GET et des POST:&lt;/div&gt;</summary>
		<author><name>Theodet</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11694</id>
		<title>Génération et résolution de labyrinthes II</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11694"/>
		<updated>2019-05-17T13:33:47Z</updated>

		<summary type="html">&lt;p&gt;Theodet : /* Génération */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__FORCETOC__[[Fichier:labyrinthe_photo.png|vignette|300px|Labyrinthe généré avec Kruskal et résolu avec le parcours en profondeur. En route foncé, l&#039;entrée. En vert, la sortie. En bleu, le chemin. En rouge clair, les cellules visitées lors de la résolution.|alt=&amp;quot;Labyrinthe&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
On veut générer des labyrinthes aussi grands et complexes que possible, avec des murs dans une grille carré. Comment faire pour qu&#039;il y ait toujours un chemin de l&#039;entrée à la sortie ? Comment faire pour qu&#039;il n&#039;y ait qu&#039;un chemin ? Et comment trouver la sortie quand on est perdu dans le labyrinthe ?&lt;br /&gt;
&lt;br /&gt;
== Représentation ==&lt;br /&gt;
&lt;br /&gt;
=== Propriétés ===&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe est une grille de cellules reliées, ou non, entre elles.&lt;br /&gt;
&lt;br /&gt;
Deux cellules sont reliées entre elles par une &#039;&#039;&#039;porte&#039;&#039;&#039;, ou séparées par un &#039;&#039;&#039;mur&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Tout labyrinthe a &#039;&#039;&#039;une entrée&#039;&#039;&#039; et &#039;&#039;&#039;une sortie&#039;&#039;&#039;, et quelle que soit l&#039;entrée ou la sortie, le chemin entre ces deux cellules est &#039;&#039;&#039;unique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Modélisation en graphe ===&lt;br /&gt;
&lt;br /&gt;
En théorie des graphes, un graphe est un ensemble de &#039;&#039;&#039;points&#039;&#039;&#039; (ou nœuds ou sommets) reliés ensemble par des &#039;&#039;&#039;lignes&#039;&#039;&#039; (ou liens ou arêtes).&lt;br /&gt;
&lt;br /&gt;
[[Fichier:graphe_cyclique.png|vignette|left|300px|Exemple de graphe connexe cyclique non orienté|alt=Graphe cyclique]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Un graphe peut être &#039;&#039;&#039;connexe&#039;&#039;&#039; (en un seul morceau) ou &#039;&#039;&#039;non connexe&#039;&#039;&#039; (en plusieurs morceaux).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Un graphe peut aussi être &#039;&#039;&#039;cyclique&#039;&#039;&#039; si les points sont reliés en formant une boucle ou &#039;&#039;&#039;acyclique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Enfin, un graphe peut être &#039;&#039;&#039;orienté&#039;&#039;&#039; (si les arêtes sont à sens unique) ou &#039;&#039;&#039;non orienté&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Arbre.PNG|vignette|left|300px|Exemple d&#039;arbre|alt=Arbre]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Un &#039;&#039;&#039;arbre&#039;&#039;&#039; est un graphe connexe, acyclique et non orienté.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
En plaçant un point sur chaque cellule de notre labyrinthe, et en reliant deux cellules séparées par une porte, on peut dessiner un arbre à partir de n&#039;importe quel labyrinthe.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:labyrinthe_avec_arbre.png|vignette|centre|300px|Exemple de labyrinthe avec son arbre. Pour plus de simplicité, on attribue à chaque nœud une position.|alt=Labyrinthe avec arbre]]&lt;br /&gt;
&lt;br /&gt;
== Génération ==&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe rectangulaire de largeur &amp;lt;math&amp;gt; L &amp;lt;/math&amp;gt; et de hauteur &amp;lt;math&amp;gt; H &amp;lt;/math&amp;gt; contient exactement &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; portes.&lt;br /&gt;
&lt;br /&gt;
Du point de vue du graphe, il y a donc &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; arêtes.&lt;br /&gt;
&lt;br /&gt;
Maintenant, comment répartir toutes ces portes de façon à ce que toutes les cellules soient accessibles et qu&#039;il n&#039;existe qu&#039;un unique chemin entre l&#039;entrée et la sortie ?&lt;br /&gt;
&lt;br /&gt;
De nombreux algorithmes existent, dont le parcours en profondeur et l&#039;algorithme de Kruskal.&lt;br /&gt;
Chaque algorithme est différent et produit des labyrinthes visuellement différents.&lt;br /&gt;
&lt;br /&gt;
En effet, si nous comparons un labyrinthe généré avec l&#039;algorithme du parcours en profondeur à un labyrinthe généré avec l&#039;algorithme de Kruskal, bien qu&#039;ils aient tous les deux une solution unique, ils apparaissent néanmoins différents visuellement.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:recursive_backtracker_comparaison.png|vignette|left|500px|Parcours en profondeur.&amp;lt;br&amp;gt;On remarque des chemins proprement dessinés.|alt=Parcours en profondeur]]&lt;br /&gt;
[[Fichier:kruskal_comparaison.png|vignette|right|500px|Algorithme de Kruskal.&amp;lt;br&amp;gt;On remarque des murs de 1 de longueur çà et là.|alt=Kruskal]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Parcours en profondeur ===&lt;br /&gt;
&lt;br /&gt;
[[Fichier:recursive_backtracker.gif|vignette|left|500px|Illustration du parcours en profondeur|alt=Parcours en profondeur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;algorithme du parcours en profondeur (&amp;quot;recursive backtracker&amp;quot; en anglais), on commence sur une cellule aléatoire dans le labyrinthe.&lt;br /&gt;
&lt;br /&gt;
On se dirige dans une direction aléatoire et on casse le mur en face, tout en marquant la cellule précédente comme visitée.&lt;br /&gt;
&lt;br /&gt;
Lorsque aucune direction n&#039;est disponible, on remonte à la position précédente.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:pile.png|vignette|300px|Représentation d&#039;une pile de positions|alt=Pile]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pour sauvegarder l&#039;historique des positions, on peut utiliser une &#039;&#039;&#039;pile&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Une pile est une liste dans laquelle seul le dernier élément peut être récupéré.&lt;br /&gt;
&lt;br /&gt;
Une pile contient 2 méthodes :&lt;br /&gt;
* push(elem) : ajoute elem à la pile&lt;br /&gt;
* pop() -&amp;gt; elem : retourne le dernier élément de la pile (elem dans notre cas)&lt;br /&gt;
&lt;br /&gt;
Dans mon implémentation de la pile, une erreur est levée si l&#039;on appelle la méthode pop sur une pile vide.&lt;br /&gt;
&lt;br /&gt;
=== Kruskal ===&lt;br /&gt;
&lt;br /&gt;
[[Fichier:kruskal.gif|vignette|left|500px|Illustration de l&#039;algorithme de Kruskal|alt=Kruskal]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Alors que pour le parcours en profondeur on partait des cellules, l&#039;algorithme de Kruskal s&#039;applique sur des murs.&lt;br /&gt;
&lt;br /&gt;
On attribue à chaque cellule un identifiant unique.&lt;br /&gt;
&lt;br /&gt;
On choisit un mur aléatoire. Si les cellules séparées par ce mur ont des identifiants différents, on leur associe le même identifiant et on casse le mur.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:union_find.png|vignette|300px|Représentation d&#039;une pile de positions|alt=Pile]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Labyrinthes cycliques ===&lt;br /&gt;
&lt;br /&gt;
Il est possible, en retirant un certain pourcentage de murs, de créer des labyrinthes cycliques à partir des labyrinthes acycliques générés auparavant.&lt;br /&gt;
&lt;br /&gt;
Cependant, certains algorithmes de résolution n&#039;adopteront pas le même comportement.&lt;br /&gt;
&lt;br /&gt;
== Résolution ==&lt;br /&gt;
&lt;br /&gt;
Il existe là encore de nombreux algorithmes de résolution de labyrinthes, plus ou moins efficaces, et surtout ne fonctionnant pas tous dans les mêmes conditions.&lt;br /&gt;
&lt;br /&gt;
=== Parcours en profondeur ===&lt;br /&gt;
&lt;br /&gt;
Cet algorithme est quasiment identique à celui du parcours en profondeur pour la génération.&lt;br /&gt;
&lt;br /&gt;
Il est très efficace et trouvera une solution en minimisant le nombre de cases visitées.&lt;br /&gt;
&lt;br /&gt;
Il s&#039;adapte aux labyrinthes cycliques. En cas de boucle, il ne fera pas la boucle vu que l&#039;intersection a déjà été visitées, il reviendra sur ses pas.&lt;br /&gt;
&lt;br /&gt;
Il s&#039;adapte aux labyrinthes sans solution. En effet, s&#039;il n&#039;y a pas de sortie, il va revenir à sa position de départ sans position précédente (pile vide) et en ayant parcouru toutes les cases.&lt;br /&gt;
&lt;br /&gt;
=== Mur droit ===&lt;br /&gt;
&lt;br /&gt;
Cet algorithme va suivre de la main droite le mur de droite.&lt;br /&gt;
&lt;br /&gt;
Il est relativement inefficace, et va visiter un grand nombre de cases.&lt;br /&gt;
&lt;br /&gt;
Il s&#039;adapte assez mal aux labyrinthes cycliques. En effet, si la sortie n&#039;est pas dans la même boucle que l&#039;entrée, il ne la trouvera jamais.&lt;br /&gt;
&lt;br /&gt;
Il ne s&#039;adapte pas aux labyrinthes sans solution, et fera le tour de la grille à l&#039;infini.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:labyrinthe_exp_exhaust.png|vignette|left|500px|Labyrinthe résolu en utilisant le parcours en profondeur. &amp;lt;br&amp;gt; 660 cellules visitées, 1179 déplacements, chemin de 142 cellules.|alt=Parcours en profondeur]]&lt;br /&gt;
[[Fichier:labyrinthe_right_hand.png|vignette|right|500px|Labyrinthe résolu en utilisant le mur droit. &amp;lt;br&amp;gt; 1068 cellules visitées, 1995 déplacements, chemin de 142 cellules.|alt=Mur droit]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Affichage ==&lt;br /&gt;
&lt;br /&gt;
tkinter &lt;br /&gt;
&lt;br /&gt;
[https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#Exploration_exhaustive tkinter]&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
Mon projet total contenant plusieurs milliers de lignes de code réparties dans une dizaine de fichiers, je ne peux évidemment pas l&#039;insérer directement dans cette page.&lt;br /&gt;
&lt;br /&gt;
Le code source est disponible sur Github à [https://github.com/Rominos111/Labyrinthe_VISI201 cette adresse]&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
&lt;br /&gt;
Génération&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#Fusion_al%C3%A9atoire_de_chemins Kruskal (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Maze_generation_algorithm#Randomized_Kruskal&#039;s_algorithm Kruskal (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#Exploration_exhaustive Parcours en profondeur (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Maze_generation_algorithm#Randomized_Depth-First_Search Parcours en profondeur (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Résolution&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#R%C3%A9solution Résolution générale (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Maze_solving_algorithm#Wall_follower Mur droit (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Structures de données&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Union-find Union-Find / Disjoint-Set (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Stack_(abstract_data_type) Pile / Stack (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Queue_(abstract_data_type) File / Queue (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Python&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://docs.python.org/3.6/reference/datamodel.html Classes et types de variables personnalisés (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [http://effbot.org/tkinterbook/canvas.htm Canvas Tkinter (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;/div&gt;</summary>
		<author><name>Theodet</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fichier:Kruskal.gif&amp;diff=11693</id>
		<title>Fichier:Kruskal.gif</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fichier:Kruskal.gif&amp;diff=11693"/>
		<updated>2019-05-17T13:28:56Z</updated>

		<summary type="html">&lt;p&gt;Theodet : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Theodet</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fichier:Kruskal_comparaison.png&amp;diff=11692</id>
		<title>Fichier:Kruskal comparaison.png</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fichier:Kruskal_comparaison.png&amp;diff=11692"/>
		<updated>2019-05-17T13:25:55Z</updated>

		<summary type="html">&lt;p&gt;Theodet : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Theodet</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fichier:Recursive_backtracker_comparaison.png&amp;diff=11691</id>
		<title>Fichier:Recursive backtracker comparaison.png</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fichier:Recursive_backtracker_comparaison.png&amp;diff=11691"/>
		<updated>2019-05-17T13:25:40Z</updated>

		<summary type="html">&lt;p&gt;Theodet : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Theodet</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11690</id>
		<title>Génération et résolution de labyrinthes II</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11690"/>
		<updated>2019-05-17T13:21:25Z</updated>

		<summary type="html">&lt;p&gt;Theodet : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__FORCETOC__[[Fichier:labyrinthe_photo.png|vignette|300px|Labyrinthe généré avec Kruskal et résolu avec le parcours en profondeur. En route foncé, l&#039;entrée. En vert, la sortie. En bleu, le chemin. En rouge clair, les cellules visitées lors de la résolution.|alt=&amp;quot;Labyrinthe&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
On veut générer des labyrinthes aussi grands et complexes que possible, avec des murs dans une grille carré. Comment faire pour qu&#039;il y ait toujours un chemin de l&#039;entrée à la sortie ? Comment faire pour qu&#039;il n&#039;y ait qu&#039;un chemin ? Et comment trouver la sortie quand on est perdu dans le labyrinthe ?&lt;br /&gt;
&lt;br /&gt;
== Représentation ==&lt;br /&gt;
&lt;br /&gt;
=== Propriétés ===&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe est une grille de cellules reliées, ou non, entre elles.&lt;br /&gt;
&lt;br /&gt;
Deux cellules sont reliées entre elles par une &#039;&#039;&#039;porte&#039;&#039;&#039;, ou séparées par un &#039;&#039;&#039;mur&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Tout labyrinthe a &#039;&#039;&#039;une entrée&#039;&#039;&#039; et &#039;&#039;&#039;une sortie&#039;&#039;&#039;, et quelle que soit l&#039;entrée ou la sortie, le chemin entre ces deux cellules est &#039;&#039;&#039;unique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Modélisation en graphe ===&lt;br /&gt;
&lt;br /&gt;
En théorie des graphes, un graphe est un ensemble de &#039;&#039;&#039;points&#039;&#039;&#039; (ou nœuds ou sommets) reliés ensemble par des &#039;&#039;&#039;lignes&#039;&#039;&#039; (ou liens ou arêtes).&lt;br /&gt;
&lt;br /&gt;
[[Fichier:graphe_cyclique.png|vignette|left|300px|Exemple de graphe connexe cyclique non orienté|alt=Graphe cyclique]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Un graphe peut être &#039;&#039;&#039;connexe&#039;&#039;&#039; (en un seul morceau) ou &#039;&#039;&#039;non connexe&#039;&#039;&#039; (en plusieurs morceaux).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Un graphe peut aussi être &#039;&#039;&#039;cyclique&#039;&#039;&#039; si les points sont reliés en formant une boucle ou &#039;&#039;&#039;acyclique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Enfin, un graphe peut être &#039;&#039;&#039;orienté&#039;&#039;&#039; (si les arêtes sont à sens unique) ou &#039;&#039;&#039;non orienté&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Arbre.PNG|vignette|left|300px|Exemple d&#039;arbre|alt=Arbre]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Un &#039;&#039;&#039;arbre&#039;&#039;&#039; est un graphe connexe, acyclique et non orienté.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
En plaçant un point sur chaque cellule de notre labyrinthe, et en reliant deux cellules séparées par une porte, on peut dessiner un arbre à partir de n&#039;importe quel labyrinthe.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:labyrinthe_avec_arbre.png|vignette|centre|300px|Exemple de labyrinthe avec son arbre. Pour plus de simplicité, on attribue à chaque nœud une position.|alt=Labyrinthe avec arbre]]&lt;br /&gt;
&lt;br /&gt;
== Génération ==&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe rectangulaire de largeur &amp;lt;math&amp;gt; L &amp;lt;/math&amp;gt; et de hauteur &amp;lt;math&amp;gt; H &amp;lt;/math&amp;gt; contient exactement &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; portes.&lt;br /&gt;
&lt;br /&gt;
Du point de vue du graphe, il y a donc &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; arêtes.&lt;br /&gt;
&lt;br /&gt;
Maintenant, comment répartir toutes ces portes de façon à ce que toutes les cellules soient accessibles et qu&#039;il n&#039;existe qu&#039;un unique chemin entre l&#039;entrée et la sortie ?&lt;br /&gt;
&lt;br /&gt;
De nombreux algorithmes existent, dont le parcours en profondeur et l&#039;algorithme de Kruskal.&lt;br /&gt;
Chaque algorithme est différent et produit des labyrinthes visuellement différents.&lt;br /&gt;
&lt;br /&gt;
=== Parcours en profondeur ===&lt;br /&gt;
&lt;br /&gt;
[[Fichier:recursive_backtracker.gif|vignette|left|500px|Illustration du parcours en profondeur|alt=Parcours en profondeur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;algorithme du parcours en profondeur (&amp;quot;recursive backtracker&amp;quot; en anglais), on commence sur une cellule aléatoire dans le labyrinthe.&lt;br /&gt;
&lt;br /&gt;
On se dirige dans une direction aléatoire et on casse le mur en face, tout en marquant la cellule précédente comme visitée.&lt;br /&gt;
&lt;br /&gt;
Lorsque aucune direction n&#039;est disponible, on remonte à la position précédente.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:pile.png|vignette|300px|Représentation d&#039;une pile de positions|alt=Pile]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pour sauvegarder l&#039;historique des positions, on peut utiliser une &#039;&#039;&#039;pile&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Une pile est une liste dans laquelle seul le dernier élément peut être récupéré.&lt;br /&gt;
&lt;br /&gt;
Une pile contient 2 méthodes :&lt;br /&gt;
* push(elem) : ajoute elem à la pile&lt;br /&gt;
* pop() -&amp;gt; elem : retourne le dernier élément de la pile (elem dans notre cas)&lt;br /&gt;
&lt;br /&gt;
Dans mon implémentation de la pile, une erreur est levée si l&#039;on appelle la méthode pop sur une pile vide.&lt;br /&gt;
&lt;br /&gt;
=== Kruskal ===&lt;br /&gt;
&lt;br /&gt;
Alors que pour le parcours en profondeur on partait des cellules, l&#039;algorithme de Kruskal s&#039;applique sur des murs.&lt;br /&gt;
&lt;br /&gt;
On attribue à chaque cellule un identifiant unique.&lt;br /&gt;
&lt;br /&gt;
On choisit&lt;br /&gt;
&lt;br /&gt;
=== Labyrinthes cycliques ===&lt;br /&gt;
&lt;br /&gt;
Il est possible, en retirant un certain pourcentage de murs, de créer des labyrinthes cycliques à partir des labyrinthes acycliques générés auparavant.&lt;br /&gt;
&lt;br /&gt;
Cependant, certains algorithmes de résolution n&#039;adopteront pas le même comportement.&lt;br /&gt;
&lt;br /&gt;
== Résolution ==&lt;br /&gt;
&lt;br /&gt;
Il existe là encore de nombreux algorithmes de résolution de labyrinthes, plus ou moins efficaces, et surtout ne fonctionnant pas tous dans les mêmes conditions.&lt;br /&gt;
&lt;br /&gt;
=== Parcours en profondeur ===&lt;br /&gt;
&lt;br /&gt;
Cet algorithme est quasiment identique à celui du parcours en profondeur pour la génération.&lt;br /&gt;
&lt;br /&gt;
Il est très efficace et trouvera une solution en minimisant le nombre de cases visitées.&lt;br /&gt;
&lt;br /&gt;
Il s&#039;adapte aux labyrinthes cycliques. En cas de boucle, il ne fera pas la boucle vu que l&#039;intersection a déjà été visitées, il reviendra sur ses pas.&lt;br /&gt;
&lt;br /&gt;
Il s&#039;adapte aux labyrinthes sans solution. En effet, s&#039;il n&#039;y a pas de sortie, il va revenir à sa position de départ sans position précédente (pile vide) et en ayant parcouru toutes les cases.&lt;br /&gt;
&lt;br /&gt;
=== Mur droit ===&lt;br /&gt;
&lt;br /&gt;
Cet algorithme va suivre de la main droite le mur de droite.&lt;br /&gt;
&lt;br /&gt;
Il est relativement inefficace, et va visiter un grand nombre de cases.&lt;br /&gt;
&lt;br /&gt;
Il s&#039;adapte assez mal aux labyrinthes cycliques. En effet, si la sortie n&#039;est pas dans la même boucle que l&#039;entrée, il ne la trouvera jamais.&lt;br /&gt;
&lt;br /&gt;
Il ne s&#039;adapte pas aux labyrinthes sans solution, et fera le tour de la grille à l&#039;infini.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:labyrinthe_exp_exhaust.png|vignette|left|500px|Labyrinthe résolu en utilisant le parcours en profondeur. &amp;lt;br&amp;gt; 660 cellules visitées, 1179 déplacements, chemin de 142 cellules.|alt=Parcours en profondeur]]&lt;br /&gt;
[[Fichier:labyrinthe_right_hand.png|vignette|right|500px|Labyrinthe résolu en utilisant le mur droit. &amp;lt;br&amp;gt; 1068 cellules visitées, 1995 déplacements, chemin de 142 cellules.|alt=Mur droit]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Affichage ==&lt;br /&gt;
&lt;br /&gt;
tkinter &lt;br /&gt;
&lt;br /&gt;
[https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#Exploration_exhaustive tkinter]&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
Mon projet total contenant plusieurs milliers de lignes de code réparties dans une dizaine de fichiers, je ne peux évidemment pas l&#039;insérer directement dans cette page.&lt;br /&gt;
&lt;br /&gt;
Le code source est disponible sur Github à [https://github.com/Rominos111/Labyrinthe_VISI201 cette adresse]&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
&lt;br /&gt;
Génération&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#Fusion_al%C3%A9atoire_de_chemins Kruskal (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Maze_generation_algorithm#Randomized_Kruskal&#039;s_algorithm Kruskal (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#Exploration_exhaustive Parcours en profondeur (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Maze_generation_algorithm#Randomized_Depth-First_Search Parcours en profondeur (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Résolution&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#R%C3%A9solution Résolution générale (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Maze_solving_algorithm#Wall_follower Mur droit (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Structures de données&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Union-find Union-Find / Disjoint-Set (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Stack_(abstract_data_type) Pile / Stack (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Queue_(abstract_data_type) File / Queue (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Python&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://docs.python.org/3.6/reference/datamodel.html Classes et types de variables personnalisés (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [http://effbot.org/tkinterbook/canvas.htm Canvas Tkinter (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;/div&gt;</summary>
		<author><name>Theodet</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11689</id>
		<title>Génération et résolution de labyrinthes II</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11689"/>
		<updated>2019-05-17T12:16:00Z</updated>

		<summary type="html">&lt;p&gt;Theodet : /* Labyrinthes cycliques */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__FORCETOC__[[Fichier:labyrinthe_photo.png|vignette|300px|Labyrinthe généré avec Kruskal et résolu avec le parcours en profondeur. En route foncé, l&#039;entrée. En vert, la sortie. En bleu, le chemin. En rouge clair, les cellules visitées lors de la résolution.|alt=&amp;quot;Labyrinthe&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
Lorem ipsum&lt;br /&gt;
&lt;br /&gt;
== Représentation ==&lt;br /&gt;
&lt;br /&gt;
=== Propriétés ===&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe est une grille de cellules reliées, ou non, entre elles.&lt;br /&gt;
&lt;br /&gt;
Deux cellules sont reliées entre elles par une &#039;&#039;&#039;porte&#039;&#039;&#039;, ou séparées par un &#039;&#039;&#039;mur&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Tout labyrinthe a &#039;&#039;&#039;une entrée&#039;&#039;&#039; et &#039;&#039;&#039;une sortie&#039;&#039;&#039;, et quelle que soit l&#039;entrée ou la sortie, le chemin entre ces deux cellules est &#039;&#039;&#039;unique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Modélisation en graphe ===&lt;br /&gt;
&lt;br /&gt;
En théorie des graphes, un graphe est un ensemble de &#039;&#039;&#039;points&#039;&#039;&#039; (ou nœuds ou sommets) reliés ensemble par des &#039;&#039;&#039;lignes&#039;&#039;&#039; (ou liens ou arêtes).&lt;br /&gt;
&lt;br /&gt;
[[Fichier:graphe_cyclique.png|vignette|left|300px|Exemple de graphe connexe cyclique non orienté|alt=Graphe cyclique]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Un graphe peut être &#039;&#039;&#039;connexe&#039;&#039;&#039; (en un seul morceau) ou &#039;&#039;&#039;non connexe&#039;&#039;&#039; (en plusieurs morceaux).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Un graphe peut aussi être &#039;&#039;&#039;cyclique&#039;&#039;&#039; si les points sont reliés en formant une boucle ou &#039;&#039;&#039;acyclique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Enfin, un graphe peut être &#039;&#039;&#039;orienté&#039;&#039;&#039; (si les arêtes sont à sens unique) ou &#039;&#039;&#039;non orienté&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Arbre.PNG|vignette|left|300px|Exemple d&#039;arbre|alt=Arbre]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Un &#039;&#039;&#039;arbre&#039;&#039;&#039; est un graphe connexe, acyclique et non orienté.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
En plaçant un point sur chaque cellule de notre labyrinthe, et en reliant deux cellules séparées par une porte, on peut dessiner un arbre à partir de n&#039;importe quel labyrinthe.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:labyrinthe_avec_arbre.png|vignette|centre|300px|Exemple de labyrinthe avec son arbre. Pour plus de simplicité, on attribue à chaque nœud une position.|alt=Labyrinthe avec arbre]]&lt;br /&gt;
&lt;br /&gt;
== Génération ==&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe rectangulaire de largeur &amp;lt;math&amp;gt; L &amp;lt;/math&amp;gt; et de hauteur &amp;lt;math&amp;gt; H &amp;lt;/math&amp;gt; contient exactement &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; portes.&lt;br /&gt;
&lt;br /&gt;
Du point de vue du graphe, il y a donc &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; arêtes.&lt;br /&gt;
&lt;br /&gt;
Maintenant, comment répartir toutes ces portes de façon à ce que toutes les cellules soient accessibles et qu&#039;il n&#039;existe qu&#039;un unique chemin entre l&#039;entrée et la sortie ?&lt;br /&gt;
&lt;br /&gt;
De nombreux algorithmes existent, dont le parcours en profondeur et l&#039;algorithme de Kruskal.&lt;br /&gt;
Chaque algorithme est différent et produit des labyrinthes visuellement différents.&lt;br /&gt;
&lt;br /&gt;
=== Parcours en profondeur ===&lt;br /&gt;
&lt;br /&gt;
[[Fichier:recursive_backtracker.gif|vignette|left|500px|Illustration du parcours en profondeur|alt=Parcours en profondeur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;algorithme du parcours en profondeur (&amp;quot;recursive backtracker&amp;quot; en anglais), on commence sur une cellule aléatoire dans le labyrinthe.&lt;br /&gt;
&lt;br /&gt;
On se dirige dans une direction aléatoire et on casse le mur en face, tout en marquant la cellule précédente comme visitée.&lt;br /&gt;
&lt;br /&gt;
Lorsque aucune direction n&#039;est disponible, on remonte à la position précédente.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:pile.png|vignette|300px|Représentation d&#039;une pile de positions|alt=Pile]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pour sauvegarder l&#039;historique des positions, on peut utiliser une &#039;&#039;&#039;pile&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Une pile est une liste dans laquelle seul le dernier élément peut être récupéré.&lt;br /&gt;
&lt;br /&gt;
Une pile contient 2 méthodes :&lt;br /&gt;
* push(elem) : ajoute elem à la pile&lt;br /&gt;
* pop() -&amp;gt; elem : retourne le dernier élément de la pile (elem dans notre cas)&lt;br /&gt;
&lt;br /&gt;
Dans mon implémentation de la pile, une erreur est levée si l&#039;on appelle la méthode pop sur une pile vide.&lt;br /&gt;
&lt;br /&gt;
=== Kruskal ===&lt;br /&gt;
&lt;br /&gt;
Alors que pour le parcours en profondeur on partait des cellules, l&#039;algorithme de Kruskal s&#039;applique sur des murs.&lt;br /&gt;
&lt;br /&gt;
On attribue à chaque cellule un identifiant unique.&lt;br /&gt;
&lt;br /&gt;
On choisit&lt;br /&gt;
&lt;br /&gt;
=== Labyrinthes cycliques ===&lt;br /&gt;
&lt;br /&gt;
Il est possible, en retirant un certain pourcentage de murs, de créer des labyrinthes cycliques à partir des labyrinthes acycliques générés auparavant.&lt;br /&gt;
&lt;br /&gt;
Cependant, certains algorithmes de résolution n&#039;adopteront pas le même comportement.&lt;br /&gt;
&lt;br /&gt;
== Résolution ==&lt;br /&gt;
&lt;br /&gt;
Il existe là encore de nombreux algorithmes de résolution de labyrinthes, plus ou moins efficaces, et surtout ne fonctionnant pas tous dans les mêmes conditions.&lt;br /&gt;
&lt;br /&gt;
=== Parcours en profondeur ===&lt;br /&gt;
&lt;br /&gt;
Cet algorithme est quasiment identique à celui du parcours en profondeur pour la génération.&lt;br /&gt;
&lt;br /&gt;
Il est très efficace et trouvera une solution en minimisant le nombre de cases visitées.&lt;br /&gt;
&lt;br /&gt;
Il s&#039;adapte aux labyrinthes cycliques. En cas de boucle, il ne fera pas la boucle vu que l&#039;intersection a déjà été visitées, il reviendra sur ses pas.&lt;br /&gt;
&lt;br /&gt;
Il s&#039;adapte aux labyrinthes sans solution. En effet, s&#039;il n&#039;y a pas de sortie, il va revenir à sa position de départ sans position précédente (pile vide) et en ayant parcouru toutes les cases.&lt;br /&gt;
&lt;br /&gt;
=== Mur droit ===&lt;br /&gt;
&lt;br /&gt;
Cet algorithme va suivre de la main droite le mur de droite.&lt;br /&gt;
&lt;br /&gt;
Il est relativement inefficace, et va visiter un grand nombre de cases.&lt;br /&gt;
&lt;br /&gt;
Il s&#039;adapte assez mal aux labyrinthes cycliques. En effet, si la sortie n&#039;est pas dans la même boucle que l&#039;entrée, il ne la trouvera jamais.&lt;br /&gt;
&lt;br /&gt;
Il ne s&#039;adapte pas aux labyrinthes sans solution, et fera le tour de la grille à l&#039;infini.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:labyrinthe_exp_exhaust.png|vignette|left|500px|Labyrinthe résolu en utilisant le parcours en profondeur. &amp;lt;br&amp;gt; 660 cellules visitées, 1179 déplacements, chemin de 142 cellules.|alt=Parcours en profondeur]]&lt;br /&gt;
[[Fichier:labyrinthe_right_hand.png|vignette|right|500px|Labyrinthe résolu en utilisant le mur droit. &amp;lt;br&amp;gt; 1068 cellules visitées, 1995 déplacements, chemin de 142 cellules.|alt=Mur droit]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Affichage ==&lt;br /&gt;
&lt;br /&gt;
tkinter &lt;br /&gt;
&lt;br /&gt;
[https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#Exploration_exhaustive tkinter]&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
Mon projet total contenant plusieurs milliers de lignes de code réparties dans une dizaine de fichiers, je ne peux évidemment pas l&#039;insérer directement dans cette page.&lt;br /&gt;
&lt;br /&gt;
Le code source est disponible sur Github à [https://github.com/Rominos111/Labyrinthe_VISI201 cette adresse]&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
&lt;br /&gt;
Génération&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#Fusion_al%C3%A9atoire_de_chemins Kruskal (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Maze_generation_algorithm#Randomized_Kruskal&#039;s_algorithm Kruskal (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#Exploration_exhaustive Parcours en profondeur (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Maze_generation_algorithm#Randomized_Depth-First_Search Parcours en profondeur (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Résolution&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#R%C3%A9solution Résolution générale (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Maze_solving_algorithm#Wall_follower Mur droit (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Structures de données&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Union-find Union-Find / Disjoint-Set (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Stack_(abstract_data_type) Pile / Stack (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Queue_(abstract_data_type) File / Queue (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Python&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://docs.python.org/3.6/reference/datamodel.html Classes et types de variables personnalisés (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [http://effbot.org/tkinterbook/canvas.htm Canvas Tkinter (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;/div&gt;</summary>
		<author><name>Theodet</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11688</id>
		<title>Génération et résolution de labyrinthes II</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11688"/>
		<updated>2019-05-17T12:15:20Z</updated>

		<summary type="html">&lt;p&gt;Theodet : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__FORCETOC__[[Fichier:labyrinthe_photo.png|vignette|300px|Labyrinthe généré avec Kruskal et résolu avec le parcours en profondeur. En route foncé, l&#039;entrée. En vert, la sortie. En bleu, le chemin. En rouge clair, les cellules visitées lors de la résolution.|alt=&amp;quot;Labyrinthe&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
Lorem ipsum&lt;br /&gt;
&lt;br /&gt;
== Représentation ==&lt;br /&gt;
&lt;br /&gt;
=== Propriétés ===&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe est une grille de cellules reliées, ou non, entre elles.&lt;br /&gt;
&lt;br /&gt;
Deux cellules sont reliées entre elles par une &#039;&#039;&#039;porte&#039;&#039;&#039;, ou séparées par un &#039;&#039;&#039;mur&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Tout labyrinthe a &#039;&#039;&#039;une entrée&#039;&#039;&#039; et &#039;&#039;&#039;une sortie&#039;&#039;&#039;, et quelle que soit l&#039;entrée ou la sortie, le chemin entre ces deux cellules est &#039;&#039;&#039;unique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Modélisation en graphe ===&lt;br /&gt;
&lt;br /&gt;
En théorie des graphes, un graphe est un ensemble de &#039;&#039;&#039;points&#039;&#039;&#039; (ou nœuds ou sommets) reliés ensemble par des &#039;&#039;&#039;lignes&#039;&#039;&#039; (ou liens ou arêtes).&lt;br /&gt;
&lt;br /&gt;
[[Fichier:graphe_cyclique.png|vignette|left|300px|Exemple de graphe connexe cyclique non orienté|alt=Graphe cyclique]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Un graphe peut être &#039;&#039;&#039;connexe&#039;&#039;&#039; (en un seul morceau) ou &#039;&#039;&#039;non connexe&#039;&#039;&#039; (en plusieurs morceaux).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Un graphe peut aussi être &#039;&#039;&#039;cyclique&#039;&#039;&#039; si les points sont reliés en formant une boucle ou &#039;&#039;&#039;acyclique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Enfin, un graphe peut être &#039;&#039;&#039;orienté&#039;&#039;&#039; (si les arêtes sont à sens unique) ou &#039;&#039;&#039;non orienté&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Arbre.PNG|vignette|left|300px|Exemple d&#039;arbre|alt=Arbre]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Un &#039;&#039;&#039;arbre&#039;&#039;&#039; est un graphe connexe, acyclique et non orienté.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
En plaçant un point sur chaque cellule de notre labyrinthe, et en reliant deux cellules séparées par une porte, on peut dessiner un arbre à partir de n&#039;importe quel labyrinthe.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:labyrinthe_avec_arbre.png|vignette|centre|300px|Exemple de labyrinthe avec son arbre. Pour plus de simplicité, on attribue à chaque nœud une position.|alt=Labyrinthe avec arbre]]&lt;br /&gt;
&lt;br /&gt;
== Génération ==&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe rectangulaire de largeur &amp;lt;math&amp;gt; L &amp;lt;/math&amp;gt; et de hauteur &amp;lt;math&amp;gt; H &amp;lt;/math&amp;gt; contient exactement &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; portes.&lt;br /&gt;
&lt;br /&gt;
Du point de vue du graphe, il y a donc &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; arêtes.&lt;br /&gt;
&lt;br /&gt;
Maintenant, comment répartir toutes ces portes de façon à ce que toutes les cellules soient accessibles et qu&#039;il n&#039;existe qu&#039;un unique chemin entre l&#039;entrée et la sortie ?&lt;br /&gt;
&lt;br /&gt;
De nombreux algorithmes existent, dont le parcours en profondeur et l&#039;algorithme de Kruskal.&lt;br /&gt;
Chaque algorithme est différent et produit des labyrinthes visuellement différents.&lt;br /&gt;
&lt;br /&gt;
=== Parcours en profondeur ===&lt;br /&gt;
&lt;br /&gt;
[[Fichier:recursive_backtracker.gif|vignette|left|500px|Illustration du parcours en profondeur|alt=Parcours en profondeur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;algorithme du parcours en profondeur (&amp;quot;recursive backtracker&amp;quot; en anglais), on commence sur une cellule aléatoire dans le labyrinthe.&lt;br /&gt;
&lt;br /&gt;
On se dirige dans une direction aléatoire et on casse le mur en face, tout en marquant la cellule précédente comme visitée.&lt;br /&gt;
&lt;br /&gt;
Lorsque aucune direction n&#039;est disponible, on remonte à la position précédente.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:pile.png|vignette|300px|Représentation d&#039;une pile de positions|alt=Pile]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pour sauvegarder l&#039;historique des positions, on peut utiliser une &#039;&#039;&#039;pile&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Une pile est une liste dans laquelle seul le dernier élément peut être récupéré.&lt;br /&gt;
&lt;br /&gt;
Une pile contient 2 méthodes :&lt;br /&gt;
* push(elem) : ajoute elem à la pile&lt;br /&gt;
* pop() -&amp;gt; elem : retourne le dernier élément de la pile (elem dans notre cas)&lt;br /&gt;
&lt;br /&gt;
Dans mon implémentation de la pile, une erreur est levée si l&#039;on appelle la méthode pop sur une pile vide.&lt;br /&gt;
&lt;br /&gt;
=== Kruskal ===&lt;br /&gt;
&lt;br /&gt;
Alors que pour le parcours en profondeur on partait des cellules, l&#039;algorithme de Kruskal s&#039;applique sur des murs.&lt;br /&gt;
&lt;br /&gt;
On attribue à chaque cellule un identifiant unique.&lt;br /&gt;
&lt;br /&gt;
On choisit&lt;br /&gt;
&lt;br /&gt;
=== Labyrinthes cycliques ===&lt;br /&gt;
&lt;br /&gt;
Il est possible, en retirant un certain pourcentage de murs, de créer des labyrinthes cycliques à partir des labyrinthes acycliques générés auparavant.&lt;br /&gt;
&lt;br /&gt;
Cependant, certains algorithmes de résolution n&#039;auront pas le même comportement.&lt;br /&gt;
&lt;br /&gt;
== Résolution ==&lt;br /&gt;
&lt;br /&gt;
Il existe là encore de nombreux algorithmes de résolution de labyrinthes, plus ou moins efficaces, et surtout ne fonctionnant pas tous dans les mêmes conditions.&lt;br /&gt;
&lt;br /&gt;
=== Parcours en profondeur ===&lt;br /&gt;
&lt;br /&gt;
Cet algorithme est quasiment identique à celui du parcours en profondeur pour la génération.&lt;br /&gt;
&lt;br /&gt;
Il est très efficace et trouvera une solution en minimisant le nombre de cases visitées.&lt;br /&gt;
&lt;br /&gt;
Il s&#039;adapte aux labyrinthes cycliques. En cas de boucle, il ne fera pas la boucle vu que l&#039;intersection a déjà été visitées, il reviendra sur ses pas.&lt;br /&gt;
&lt;br /&gt;
Il s&#039;adapte aux labyrinthes sans solution. En effet, s&#039;il n&#039;y a pas de sortie, il va revenir à sa position de départ sans position précédente (pile vide) et en ayant parcouru toutes les cases.&lt;br /&gt;
&lt;br /&gt;
=== Mur droit ===&lt;br /&gt;
&lt;br /&gt;
Cet algorithme va suivre de la main droite le mur de droite.&lt;br /&gt;
&lt;br /&gt;
Il est relativement inefficace, et va visiter un grand nombre de cases.&lt;br /&gt;
&lt;br /&gt;
Il s&#039;adapte assez mal aux labyrinthes cycliques. En effet, si la sortie n&#039;est pas dans la même boucle que l&#039;entrée, il ne la trouvera jamais.&lt;br /&gt;
&lt;br /&gt;
Il ne s&#039;adapte pas aux labyrinthes sans solution, et fera le tour de la grille à l&#039;infini.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:labyrinthe_exp_exhaust.png|vignette|left|500px|Labyrinthe résolu en utilisant le parcours en profondeur. &amp;lt;br&amp;gt; 660 cellules visitées, 1179 déplacements, chemin de 142 cellules.|alt=Parcours en profondeur]]&lt;br /&gt;
[[Fichier:labyrinthe_right_hand.png|vignette|right|500px|Labyrinthe résolu en utilisant le mur droit. &amp;lt;br&amp;gt; 1068 cellules visitées, 1995 déplacements, chemin de 142 cellules.|alt=Mur droit]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Affichage ==&lt;br /&gt;
&lt;br /&gt;
tkinter &lt;br /&gt;
&lt;br /&gt;
[https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#Exploration_exhaustive tkinter]&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
Mon projet total contenant plusieurs milliers de lignes de code réparties dans une dizaine de fichiers, je ne peux évidemment pas l&#039;insérer directement dans cette page.&lt;br /&gt;
&lt;br /&gt;
Le code source est disponible sur Github à [https://github.com/Rominos111/Labyrinthe_VISI201 cette adresse]&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
&lt;br /&gt;
Génération&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#Fusion_al%C3%A9atoire_de_chemins Kruskal (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Maze_generation_algorithm#Randomized_Kruskal&#039;s_algorithm Kruskal (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#Exploration_exhaustive Parcours en profondeur (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Maze_generation_algorithm#Randomized_Depth-First_Search Parcours en profondeur (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Résolution&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#R%C3%A9solution Résolution générale (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Maze_solving_algorithm#Wall_follower Mur droit (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Structures de données&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Union-find Union-Find / Disjoint-Set (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Stack_(abstract_data_type) Pile / Stack (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Queue_(abstract_data_type) File / Queue (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Python&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://docs.python.org/3.6/reference/datamodel.html Classes et types de variables personnalisés (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [http://effbot.org/tkinterbook/canvas.htm Canvas Tkinter (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;/div&gt;</summary>
		<author><name>Theodet</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11687</id>
		<title>Génération et résolution de labyrinthes II</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11687"/>
		<updated>2019-05-17T12:14:14Z</updated>

		<summary type="html">&lt;p&gt;Theodet : /* Résolution */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__FORCETOC__[[Fichier:labyrinthe_photo.png|vignette|300px|Labyrinthe généré avec Kruskal et résolu avec le parcours en profondeur. En route foncé, l&#039;entrée. En vert, la sortie. En bleu, le chemin. En rouge clair, les cellules visitées lors de la résolution.|alt=&amp;quot;Labyrinthe&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
Lorem ipsum&lt;br /&gt;
&lt;br /&gt;
== Représentation ==&lt;br /&gt;
&lt;br /&gt;
=== Propriétés ===&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe est une grille de cellules reliées, ou non, entre elles.&lt;br /&gt;
&lt;br /&gt;
Deux cellules sont reliées entre elles par une &#039;&#039;&#039;porte&#039;&#039;&#039;, ou séparées par un &#039;&#039;&#039;mur&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Tout labyrinthe a &#039;&#039;&#039;une entrée&#039;&#039;&#039; et &#039;&#039;&#039;une sortie&#039;&#039;&#039;, et quelle que soit l&#039;entrée ou la sortie, le chemin entre ces deux cellules est &#039;&#039;&#039;unique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Modélisation en graphe ===&lt;br /&gt;
&lt;br /&gt;
En théorie des graphes, un graphe est un ensemble de &#039;&#039;&#039;points&#039;&#039;&#039; (ou nœuds ou sommets) reliés ensemble par des &#039;&#039;&#039;lignes&#039;&#039;&#039; (ou liens ou arêtes).&lt;br /&gt;
&lt;br /&gt;
[[Fichier:graphe_cyclique.png|vignette|left|300px|Exemple de graphe connexe cyclique non orienté|alt=Graphe cyclique]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Un graphe peut être &#039;&#039;&#039;connexe&#039;&#039;&#039; (en un seul morceau) ou &#039;&#039;&#039;non connexe&#039;&#039;&#039; (en plusieurs morceaux).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Un graphe peut aussi être &#039;&#039;&#039;cyclique&#039;&#039;&#039; si les points sont reliés en formant une boucle ou &#039;&#039;&#039;acyclique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Enfin, un graphe peut être &#039;&#039;&#039;orienté&#039;&#039;&#039; (si les arêtes sont à sens unique) ou &#039;&#039;&#039;non orienté&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Arbre.PNG|vignette|left|300px|Exemple d&#039;arbre|alt=Arbre]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Un &#039;&#039;&#039;arbre&#039;&#039;&#039; est un graphe connexe, acyclique et non orienté.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
En plaçant un point sur chaque cellule de notre labyrinthe, et en reliant deux cellules séparées par une porte, on peut dessiner un arbre à partir de n&#039;importe quel labyrinthe.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:labyrinthe_avec_arbre.png|vignette|centre|300px|Exemple de labyrinthe avec son arbre. Pour plus de simplicité, on attribue à chaque nœud une position.|alt=Labyrinthe avec arbre]]&lt;br /&gt;
&lt;br /&gt;
== Génération ==&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe rectangulaire de largeur &amp;lt;math&amp;gt; L &amp;lt;/math&amp;gt; et de hauteur &amp;lt;math&amp;gt; H &amp;lt;/math&amp;gt; contient exactement &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; portes.&lt;br /&gt;
&lt;br /&gt;
Du point de vue du graphe, il y a donc &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; arêtes.&lt;br /&gt;
&lt;br /&gt;
Maintenant, comment répartir toutes ces portes de façon à ce que toutes les cellules soient accessibles et qu&#039;il n&#039;existe qu&#039;un unique chemin entre l&#039;entrée et la sortie ?&lt;br /&gt;
&lt;br /&gt;
De nombreux algorithmes existent, dont le parcours en profondeur et l&#039;algorithme de Kruskal.&lt;br /&gt;
Chaque algorithme est différent et produit des labyrinthes visuellement différents.&lt;br /&gt;
&lt;br /&gt;
=== Parcours en profondeur ===&lt;br /&gt;
&lt;br /&gt;
[[Fichier:recursive_backtracker.gif|vignette|left|500px|Illustration du parcours en profondeur|alt=Parcours en profondeur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;algorithme du parcours en profondeur (&amp;quot;recursive backtracker&amp;quot; en anglais), on commence sur une cellule aléatoire dans le labyrinthe.&lt;br /&gt;
&lt;br /&gt;
On se dirige dans une direction aléatoire et on casse le mur en face, tout en marquant la cellule précédente comme visitée.&lt;br /&gt;
&lt;br /&gt;
Lorsque aucune direction n&#039;est disponible, on remonte à la position précédente.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:pile.png|vignette|300px|Représentation d&#039;une pile de positions|alt=Pile]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pour sauvegarder l&#039;historique des positions, on peut utiliser une &#039;&#039;&#039;pile&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Une pile est une liste dans laquelle seul le dernier élément peut être récupéré.&lt;br /&gt;
&lt;br /&gt;
Une pile contient 2 méthodes :&lt;br /&gt;
* push(elem) : ajoute elem à la pile&lt;br /&gt;
* pop() -&amp;gt; elem : retourne le dernier élément de la pile (elem dans notre cas)&lt;br /&gt;
&lt;br /&gt;
Dans mon implémentation de la pile, une erreur est levée si l&#039;on appelle la méthode pop sur une pile vide.&lt;br /&gt;
&lt;br /&gt;
=== Kruskal ===&lt;br /&gt;
&lt;br /&gt;
Alors que pour le parcours en profondeur on partait des cellules, l&#039;algorithme de Kruskal s&#039;applique sur des murs.&lt;br /&gt;
&lt;br /&gt;
On attribue à chaque cellule un identifiant unique.&lt;br /&gt;
&lt;br /&gt;
On choisit&lt;br /&gt;
&lt;br /&gt;
=== Labyrinthes cycliques ===&lt;br /&gt;
&lt;br /&gt;
Il est possible, en retirant un certain pourcentage de murs, de créer des labyrinthes cycliques à partir des labyrinthes acycliques générés auparavant.&lt;br /&gt;
&lt;br /&gt;
Cependant, certains algorithmes de résolution n&#039;auront pas le même comportement.&lt;br /&gt;
&lt;br /&gt;
== Résolution ==&lt;br /&gt;
&lt;br /&gt;
Il existe là encore de nombreux algorithmes de résolution de labyrinthes, plus ou moins efficaces, et surtout ne fonctionnant pas tous dans les mêmes conditions.&lt;br /&gt;
&lt;br /&gt;
=== Parcours en profondeur ===&lt;br /&gt;
&lt;br /&gt;
Cet algorithme est quasiment identique à celui du parcours en profondeur pour la génération.&lt;br /&gt;
&lt;br /&gt;
Il est très efficace et trouvera une solution en minimisant le nombre de cases visitées.&lt;br /&gt;
&lt;br /&gt;
Il s&#039;adapte aux labyrinthes cycliques. En cas de boucle, il ne fera pas la boucle vu que l&#039;intersection a déjà été visitées, il reviendra sur ses pas.&lt;br /&gt;
&lt;br /&gt;
Il s&#039;adapte aux labyrinthes sans solution. En effet, s&#039;il n&#039;y a pas de sortie, il va revenir à sa position de départ sans position précédente (pile vide) et en ayant parcouru toutes les cases.&lt;br /&gt;
&lt;br /&gt;
=== Mur droit ===&lt;br /&gt;
&lt;br /&gt;
Cet algorithme va suivre de la main droite le mur de droite.&lt;br /&gt;
&lt;br /&gt;
Il est relativement inefficace, et va visiter un grand nombre de cases.&lt;br /&gt;
&lt;br /&gt;
Il s&#039;adapte assez mal aux labyrinthes cycliques. En effet, si la sortie n&#039;est pas dans la même boucle que l&#039;entrée, il ne la trouvera jamais.&lt;br /&gt;
&lt;br /&gt;
Il ne s&#039;adapte pas aux labyrinthes sans solution, et fera le tour de la grille à l&#039;infini.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:labyrinthe_exp_exhaust.png|vignette|left|500px|Labyrinthe résolu en utilisant le parcours en profondeur. &amp;lt;br&amp;gt; 660 cellules visitées, 1179 déplacements, chemin de 142 cellules.|alt=Parcours en profondeur]]&lt;br /&gt;
[[Fichier:labyrinthe_right_hand.png|vignette|right|500px|Labyrinthe résolu en utilisant le mur droit. &amp;lt;br&amp;gt; 1068 cellules visitées, 1995 déplacements, chemin de 142 cellules.|alt=Mur droit]]&lt;br /&gt;
&lt;br /&gt;
== Affichage ==&lt;br /&gt;
&lt;br /&gt;
tkinter &lt;br /&gt;
&lt;br /&gt;
[https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#Exploration_exhaustive tkinter]&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
Mon projet total contenant plusieurs milliers de lignes de code réparties dans une dizaine de fichiers, je ne peux évidemment pas l&#039;insérer directement dans cette page.&lt;br /&gt;
&lt;br /&gt;
Le code source est disponible sur Github à [https://github.com/Rominos111/Labyrinthe_VISI201 cette adresse]&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
&lt;br /&gt;
Génération&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#Fusion_al%C3%A9atoire_de_chemins Kruskal (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Maze_generation_algorithm#Randomized_Kruskal&#039;s_algorithm Kruskal (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#Exploration_exhaustive Parcours en profondeur (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Maze_generation_algorithm#Randomized_Depth-First_Search Parcours en profondeur (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Résolution&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#R%C3%A9solution Résolution générale (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Maze_solving_algorithm#Wall_follower Mur droit (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Structures de données&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Union-find Union-Find / Disjoint-Set (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Stack_(abstract_data_type) Pile / Stack (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Queue_(abstract_data_type) File / Queue (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Python&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://docs.python.org/3.6/reference/datamodel.html Classes et types de variables personnalisés (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [http://effbot.org/tkinterbook/canvas.htm Canvas Tkinter (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;/div&gt;</summary>
		<author><name>Theodet</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fichier:Labyrinthe_right_hand.png&amp;diff=11686</id>
		<title>Fichier:Labyrinthe right hand.png</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fichier:Labyrinthe_right_hand.png&amp;diff=11686"/>
		<updated>2019-05-17T12:11:56Z</updated>

		<summary type="html">&lt;p&gt;Theodet : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Theodet</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fichier:Labyrinthe_exp_exhaust.png&amp;diff=11685</id>
		<title>Fichier:Labyrinthe exp exhaust.png</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fichier:Labyrinthe_exp_exhaust.png&amp;diff=11685"/>
		<updated>2019-05-17T12:11:12Z</updated>

		<summary type="html">&lt;p&gt;Theodet : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Theodet</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11684</id>
		<title>Génération et résolution de labyrinthes II</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11684"/>
		<updated>2019-05-17T11:35:02Z</updated>

		<summary type="html">&lt;p&gt;Theodet : /* Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__FORCETOC__[[Fichier:labyrinthe_photo.png|vignette|300px|Labyrinthe généré avec Kruskal et résolu avec le parcours en profondeur. En route foncé, l&#039;entrée. En vert, la sortie. En bleu, le chemin. En rouge clair, les cellules visitées lors de la résolution.|alt=&amp;quot;Labyrinthe&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
Lorem ipsum&lt;br /&gt;
&lt;br /&gt;
== Représentation ==&lt;br /&gt;
&lt;br /&gt;
=== Propriétés ===&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe est une grille de cellules reliées, ou non, entre elles.&lt;br /&gt;
&lt;br /&gt;
Deux cellules sont reliées entre elles par une &#039;&#039;&#039;porte&#039;&#039;&#039;, ou séparées par un &#039;&#039;&#039;mur&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Tout labyrinthe a &#039;&#039;&#039;une entrée&#039;&#039;&#039; et &#039;&#039;&#039;une sortie&#039;&#039;&#039;, et quelle que soit l&#039;entrée ou la sortie, le chemin entre ces deux cellules est &#039;&#039;&#039;unique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Modélisation en graphe ===&lt;br /&gt;
&lt;br /&gt;
En théorie des graphes, un graphe est un ensemble de &#039;&#039;&#039;points&#039;&#039;&#039; (ou nœuds ou sommets) reliés ensemble par des &#039;&#039;&#039;lignes&#039;&#039;&#039; (ou liens ou arêtes).&lt;br /&gt;
&lt;br /&gt;
[[Fichier:graphe_cyclique.png|vignette|left|300px|Exemple de graphe connexe cyclique non orienté|alt=Graphe cyclique]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Un graphe peut être &#039;&#039;&#039;connexe&#039;&#039;&#039; (en un seul morceau) ou &#039;&#039;&#039;non connexe&#039;&#039;&#039; (en plusieurs morceaux).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Un graphe peut aussi être &#039;&#039;&#039;cyclique&#039;&#039;&#039; si les points sont reliés en formant une boucle ou &#039;&#039;&#039;acyclique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Enfin, un graphe peut être &#039;&#039;&#039;orienté&#039;&#039;&#039; (si les arêtes sont à sens unique) ou &#039;&#039;&#039;non orienté&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Arbre.PNG|vignette|left|300px|Exemple d&#039;arbre|alt=Arbre]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Un &#039;&#039;&#039;arbre&#039;&#039;&#039; est un graphe connexe, acyclique et non orienté.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
En plaçant un point sur chaque cellule de notre labyrinthe, et en reliant deux cellules séparées par une porte, on peut dessiner un arbre à partir de n&#039;importe quel labyrinthe.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:labyrinthe_avec_arbre.png|vignette|centre|300px|Exemple de labyrinthe avec son arbre. Pour plus de simplicité, on attribue à chaque nœud une position.|alt=Labyrinthe avec arbre]]&lt;br /&gt;
&lt;br /&gt;
== Génération ==&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe rectangulaire de largeur &amp;lt;math&amp;gt; L &amp;lt;/math&amp;gt; et de hauteur &amp;lt;math&amp;gt; H &amp;lt;/math&amp;gt; contient exactement &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; portes.&lt;br /&gt;
&lt;br /&gt;
Du point de vue du graphe, il y a donc &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; arêtes.&lt;br /&gt;
&lt;br /&gt;
Maintenant, comment répartir toutes ces portes de façon à ce que toutes les cellules soient accessibles et qu&#039;il n&#039;existe qu&#039;un unique chemin entre l&#039;entrée et la sortie ?&lt;br /&gt;
&lt;br /&gt;
De nombreux algorithmes existent, dont le parcours en profondeur et l&#039;algorithme de Kruskal.&lt;br /&gt;
Chaque algorithme est différent et produit des labyrinthes visuellement différents.&lt;br /&gt;
&lt;br /&gt;
=== Parcours en profondeur ===&lt;br /&gt;
&lt;br /&gt;
[[Fichier:recursive_backtracker.gif|vignette|left|500px|Illustration du parcours en profondeur|alt=Parcours en profondeur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;algorithme du parcours en profondeur (&amp;quot;recursive backtracker&amp;quot; en anglais), on commence sur une cellule aléatoire dans le labyrinthe.&lt;br /&gt;
&lt;br /&gt;
On se dirige dans une direction aléatoire et on casse le mur en face, tout en marquant la cellule précédente comme visitée.&lt;br /&gt;
&lt;br /&gt;
Lorsque aucune direction n&#039;est disponible, on remonte à la position précédente.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:pile.png|vignette|300px|Représentation d&#039;une pile de positions|alt=Pile]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pour sauvegarder l&#039;historique des positions, on peut utiliser une &#039;&#039;&#039;pile&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Une pile est une liste dans laquelle seul le dernier élément peut être récupéré.&lt;br /&gt;
&lt;br /&gt;
Une pile contient 2 méthodes :&lt;br /&gt;
* push(elem) : ajoute elem à la pile&lt;br /&gt;
* pop() -&amp;gt; elem : retourne le dernier élément de la pile (elem dans notre cas)&lt;br /&gt;
&lt;br /&gt;
Dans mon implémentation de la pile, une erreur est levée si l&#039;on appelle la méthode pop sur une pile vide.&lt;br /&gt;
&lt;br /&gt;
=== Kruskal ===&lt;br /&gt;
&lt;br /&gt;
Alors que pour le parcours en profondeur on partait des cellules, l&#039;algorithme de Kruskal s&#039;applique sur des murs.&lt;br /&gt;
&lt;br /&gt;
On attribue à chaque cellule un identifiant unique.&lt;br /&gt;
&lt;br /&gt;
On choisit&lt;br /&gt;
&lt;br /&gt;
=== Labyrinthes cycliques ===&lt;br /&gt;
&lt;br /&gt;
Il est possible, en retirant un certain pourcentage de murs, de créer des labyrinthes cycliques à partir des labyrinthes acycliques générés auparavant.&lt;br /&gt;
&lt;br /&gt;
Cependant, certains algorithmes de résolution n&#039;auront pas le même comportement.&lt;br /&gt;
&lt;br /&gt;
== Résolution ==&lt;br /&gt;
&lt;br /&gt;
?&lt;br /&gt;
&lt;br /&gt;
=== Exploration exhaustive ===&lt;br /&gt;
&lt;br /&gt;
=== Mur droit ===&lt;br /&gt;
&lt;br /&gt;
== Affichage ==&lt;br /&gt;
&lt;br /&gt;
tkinter &lt;br /&gt;
&lt;br /&gt;
[https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#Exploration_exhaustive tkinter]&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
Mon projet total contenant plusieurs milliers de lignes de code réparties dans une dizaine de fichiers, je ne peux évidemment pas l&#039;insérer directement dans cette page.&lt;br /&gt;
&lt;br /&gt;
Le code source est disponible sur Github à [https://github.com/Rominos111/Labyrinthe_VISI201 cette adresse]&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
&lt;br /&gt;
Génération&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#Fusion_al%C3%A9atoire_de_chemins Kruskal (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Maze_generation_algorithm#Randomized_Kruskal&#039;s_algorithm Kruskal (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#Exploration_exhaustive Parcours en profondeur (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Maze_generation_algorithm#Randomized_Depth-First_Search Parcours en profondeur (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Résolution&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#R%C3%A9solution Résolution générale (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Maze_solving_algorithm#Wall_follower Mur droit (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Structures de données&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Union-find Union-Find / Disjoint-Set (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Stack_(abstract_data_type) Pile / Stack (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Queue_(abstract_data_type) File / Queue (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Python&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://docs.python.org/3.6/reference/datamodel.html Classes et types de variables personnalisés (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [http://effbot.org/tkinterbook/canvas.htm Canvas Tkinter (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;/div&gt;</summary>
		<author><name>Theodet</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11683</id>
		<title>Génération et résolution de labyrinthes II</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11683"/>
		<updated>2019-05-17T11:33:28Z</updated>

		<summary type="html">&lt;p&gt;Theodet : /* Sources */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__FORCETOC__[[Fichier:labyrinthe_photo.png|vignette|300px|Labyrinthe généré avec Kruskal et résolu avec le parcours en profondeur. En route foncé, l&#039;entrée. En vert, la sortie. En bleu, le chemin. En rouge clair, les cellules visitées lors de la résolution.|alt=&amp;quot;Labyrinthe&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
Lorem ipsum&lt;br /&gt;
&lt;br /&gt;
== Représentation ==&lt;br /&gt;
&lt;br /&gt;
=== Propriétés ===&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe est une grille de cellules reliées, ou non, entre elles.&lt;br /&gt;
&lt;br /&gt;
Deux cellules sont reliées entre elles par une &#039;&#039;&#039;porte&#039;&#039;&#039;, ou séparées par un &#039;&#039;&#039;mur&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Tout labyrinthe a &#039;&#039;&#039;une entrée&#039;&#039;&#039; et &#039;&#039;&#039;une sortie&#039;&#039;&#039;, et quelle que soit l&#039;entrée ou la sortie, le chemin entre ces deux cellules est &#039;&#039;&#039;unique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Modélisation en graphe ===&lt;br /&gt;
&lt;br /&gt;
En théorie des graphes, un graphe est un ensemble de &#039;&#039;&#039;points&#039;&#039;&#039; (ou nœuds ou sommets) reliés ensemble par des &#039;&#039;&#039;lignes&#039;&#039;&#039; (ou liens ou arêtes).&lt;br /&gt;
&lt;br /&gt;
[[Fichier:graphe_cyclique.png|vignette|left|300px|Exemple de graphe connexe cyclique non orienté|alt=Graphe cyclique]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Un graphe peut être &#039;&#039;&#039;connexe&#039;&#039;&#039; (en un seul morceau) ou &#039;&#039;&#039;non connexe&#039;&#039;&#039; (en plusieurs morceaux).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Un graphe peut aussi être &#039;&#039;&#039;cyclique&#039;&#039;&#039; si les points sont reliés en formant une boucle ou &#039;&#039;&#039;acyclique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Enfin, un graphe peut être &#039;&#039;&#039;orienté&#039;&#039;&#039; (si les arêtes sont à sens unique) ou &#039;&#039;&#039;non orienté&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Arbre.PNG|vignette|left|300px|Exemple d&#039;arbre|alt=Arbre]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Un &#039;&#039;&#039;arbre&#039;&#039;&#039; est un graphe connexe, acyclique et non orienté.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
En plaçant un point sur chaque cellule de notre labyrinthe, et en reliant deux cellules séparées par une porte, on peut dessiner un arbre à partir de n&#039;importe quel labyrinthe.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:labyrinthe_avec_arbre.png|vignette|centre|300px|Exemple de labyrinthe avec son arbre. Pour plus de simplicité, on attribue à chaque nœud une position.|alt=Labyrinthe avec arbre]]&lt;br /&gt;
&lt;br /&gt;
== Génération ==&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe rectangulaire de largeur &amp;lt;math&amp;gt; L &amp;lt;/math&amp;gt; et de hauteur &amp;lt;math&amp;gt; H &amp;lt;/math&amp;gt; contient exactement &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; portes.&lt;br /&gt;
&lt;br /&gt;
Du point de vue du graphe, il y a donc &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; arêtes.&lt;br /&gt;
&lt;br /&gt;
Maintenant, comment répartir toutes ces portes de façon à ce que toutes les cellules soient accessibles et qu&#039;il n&#039;existe qu&#039;un unique chemin entre l&#039;entrée et la sortie ?&lt;br /&gt;
&lt;br /&gt;
De nombreux algorithmes existent, dont le parcours en profondeur et l&#039;algorithme de Kruskal.&lt;br /&gt;
Chaque algorithme est différent et produit des labyrinthes visuellement différents.&lt;br /&gt;
&lt;br /&gt;
=== Parcours en profondeur ===&lt;br /&gt;
&lt;br /&gt;
[[Fichier:recursive_backtracker.gif|vignette|left|500px|Illustration du parcours en profondeur|alt=Parcours en profondeur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;algorithme du parcours en profondeur (&amp;quot;recursive backtracker&amp;quot; en anglais), on commence sur une cellule aléatoire dans le labyrinthe.&lt;br /&gt;
&lt;br /&gt;
On se dirige dans une direction aléatoire et on casse le mur en face, tout en marquant la cellule précédente comme visitée.&lt;br /&gt;
&lt;br /&gt;
Lorsque aucune direction n&#039;est disponible, on remonte à la position précédente.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:pile.png|vignette|300px|Représentation d&#039;une pile de positions|alt=Pile]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pour sauvegarder l&#039;historique des positions, on peut utiliser une &#039;&#039;&#039;pile&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Une pile est une liste dans laquelle seul le dernier élément peut être récupéré.&lt;br /&gt;
&lt;br /&gt;
Une pile contient 2 méthodes :&lt;br /&gt;
* push(elem) : ajoute elem à la pile&lt;br /&gt;
* pop() -&amp;gt; elem : retourne le dernier élément de la pile (elem dans notre cas)&lt;br /&gt;
&lt;br /&gt;
Dans mon implémentation de la pile, une erreur est levée si l&#039;on appelle la méthode pop sur une pile vide.&lt;br /&gt;
&lt;br /&gt;
=== Kruskal ===&lt;br /&gt;
&lt;br /&gt;
Alors que pour le parcours en profondeur on partait des cellules, l&#039;algorithme de Kruskal s&#039;applique sur des murs.&lt;br /&gt;
&lt;br /&gt;
On attribue à chaque cellule un identifiant unique.&lt;br /&gt;
&lt;br /&gt;
On choisit&lt;br /&gt;
&lt;br /&gt;
=== Labyrinthes cycliques ===&lt;br /&gt;
&lt;br /&gt;
Il est possible, en retirant un certain pourcentage de murs, de créer des labyrinthes cycliques à partir des labyrinthes acycliques générés auparavant.&lt;br /&gt;
&lt;br /&gt;
Cependant, certains algorithmes de résolution n&#039;auront pas le même comportement.&lt;br /&gt;
&lt;br /&gt;
== Résolution ==&lt;br /&gt;
&lt;br /&gt;
?&lt;br /&gt;
&lt;br /&gt;
=== Exploration exhaustive ===&lt;br /&gt;
&lt;br /&gt;
=== Mur droit ===&lt;br /&gt;
&lt;br /&gt;
== Affichage ==&lt;br /&gt;
&lt;br /&gt;
tkinter &lt;br /&gt;
&lt;br /&gt;
[https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#Exploration_exhaustive tkinter]&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
Mon projet total contenant plusieurs milliers de lignes réparties dans une dizaine de fichiers, je ne peux évidemment pas l&#039;insérer directement dans cette page.&lt;br /&gt;
&lt;br /&gt;
Le code source est disponible sur Github à [https://github.com/Rominos111/Labyrinthe_VISI201 cette adresse]&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
&lt;br /&gt;
Génération&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#Fusion_al%C3%A9atoire_de_chemins Kruskal (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Maze_generation_algorithm#Randomized_Kruskal&#039;s_algorithm Kruskal (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#Exploration_exhaustive Parcours en profondeur (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Maze_generation_algorithm#Randomized_Depth-First_Search Parcours en profondeur (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Résolution&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#R%C3%A9solution Résolution générale (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Maze_solving_algorithm#Wall_follower Mur droit (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Structures de données&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Union-find Union-Find / Disjoint-Set (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Stack_(abstract_data_type) Pile / Stack (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Queue_(abstract_data_type) File / Queue (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Python&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://docs.python.org/3.6/reference/datamodel.html Classes et types de variables personnalisés (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [http://effbot.org/tkinterbook/canvas.htm Canvas Tkinter (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;/div&gt;</summary>
		<author><name>Theodet</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11682</id>
		<title>Génération et résolution de labyrinthes II</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11682"/>
		<updated>2019-05-17T11:30:01Z</updated>

		<summary type="html">&lt;p&gt;Theodet : /* Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__FORCETOC__[[Fichier:labyrinthe_photo.png|vignette|300px|Labyrinthe généré avec Kruskal et résolu avec le parcours en profondeur. En route foncé, l&#039;entrée. En vert, la sortie. En bleu, le chemin. En rouge clair, les cellules visitées lors de la résolution.|alt=&amp;quot;Labyrinthe&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
Lorem ipsum&lt;br /&gt;
&lt;br /&gt;
== Représentation ==&lt;br /&gt;
&lt;br /&gt;
=== Propriétés ===&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe est une grille de cellules reliées, ou non, entre elles.&lt;br /&gt;
&lt;br /&gt;
Deux cellules sont reliées entre elles par une &#039;&#039;&#039;porte&#039;&#039;&#039;, ou séparées par un &#039;&#039;&#039;mur&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Tout labyrinthe a &#039;&#039;&#039;une entrée&#039;&#039;&#039; et &#039;&#039;&#039;une sortie&#039;&#039;&#039;, et quelle que soit l&#039;entrée ou la sortie, le chemin entre ces deux cellules est &#039;&#039;&#039;unique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Modélisation en graphe ===&lt;br /&gt;
&lt;br /&gt;
En théorie des graphes, un graphe est un ensemble de &#039;&#039;&#039;points&#039;&#039;&#039; (ou nœuds ou sommets) reliés ensemble par des &#039;&#039;&#039;lignes&#039;&#039;&#039; (ou liens ou arêtes).&lt;br /&gt;
&lt;br /&gt;
[[Fichier:graphe_cyclique.png|vignette|left|300px|Exemple de graphe connexe cyclique non orienté|alt=Graphe cyclique]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Un graphe peut être &#039;&#039;&#039;connexe&#039;&#039;&#039; (en un seul morceau) ou &#039;&#039;&#039;non connexe&#039;&#039;&#039; (en plusieurs morceaux).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Un graphe peut aussi être &#039;&#039;&#039;cyclique&#039;&#039;&#039; si les points sont reliés en formant une boucle ou &#039;&#039;&#039;acyclique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Enfin, un graphe peut être &#039;&#039;&#039;orienté&#039;&#039;&#039; (si les arêtes sont à sens unique) ou &#039;&#039;&#039;non orienté&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Arbre.PNG|vignette|left|300px|Exemple d&#039;arbre|alt=Arbre]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Un &#039;&#039;&#039;arbre&#039;&#039;&#039; est un graphe connexe, acyclique et non orienté.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
En plaçant un point sur chaque cellule de notre labyrinthe, et en reliant deux cellules séparées par une porte, on peut dessiner un arbre à partir de n&#039;importe quel labyrinthe.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:labyrinthe_avec_arbre.png|vignette|centre|300px|Exemple de labyrinthe avec son arbre. Pour plus de simplicité, on attribue à chaque nœud une position.|alt=Labyrinthe avec arbre]]&lt;br /&gt;
&lt;br /&gt;
== Génération ==&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe rectangulaire de largeur &amp;lt;math&amp;gt; L &amp;lt;/math&amp;gt; et de hauteur &amp;lt;math&amp;gt; H &amp;lt;/math&amp;gt; contient exactement &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; portes.&lt;br /&gt;
&lt;br /&gt;
Du point de vue du graphe, il y a donc &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; arêtes.&lt;br /&gt;
&lt;br /&gt;
Maintenant, comment répartir toutes ces portes de façon à ce que toutes les cellules soient accessibles et qu&#039;il n&#039;existe qu&#039;un unique chemin entre l&#039;entrée et la sortie ?&lt;br /&gt;
&lt;br /&gt;
De nombreux algorithmes existent, dont le parcours en profondeur et l&#039;algorithme de Kruskal.&lt;br /&gt;
Chaque algorithme est différent et produit des labyrinthes visuellement différents.&lt;br /&gt;
&lt;br /&gt;
=== Parcours en profondeur ===&lt;br /&gt;
&lt;br /&gt;
[[Fichier:recursive_backtracker.gif|vignette|left|500px|Illustration du parcours en profondeur|alt=Parcours en profondeur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;algorithme du parcours en profondeur (&amp;quot;recursive backtracker&amp;quot; en anglais), on commence sur une cellule aléatoire dans le labyrinthe.&lt;br /&gt;
&lt;br /&gt;
On se dirige dans une direction aléatoire et on casse le mur en face, tout en marquant la cellule précédente comme visitée.&lt;br /&gt;
&lt;br /&gt;
Lorsque aucune direction n&#039;est disponible, on remonte à la position précédente.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:pile.png|vignette|300px|Représentation d&#039;une pile de positions|alt=Pile]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pour sauvegarder l&#039;historique des positions, on peut utiliser une &#039;&#039;&#039;pile&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Une pile est une liste dans laquelle seul le dernier élément peut être récupéré.&lt;br /&gt;
&lt;br /&gt;
Une pile contient 2 méthodes :&lt;br /&gt;
* push(elem) : ajoute elem à la pile&lt;br /&gt;
* pop() -&amp;gt; elem : retourne le dernier élément de la pile (elem dans notre cas)&lt;br /&gt;
&lt;br /&gt;
Dans mon implémentation de la pile, une erreur est levée si l&#039;on appelle la méthode pop sur une pile vide.&lt;br /&gt;
&lt;br /&gt;
=== Kruskal ===&lt;br /&gt;
&lt;br /&gt;
Alors que pour le parcours en profondeur on partait des cellules, l&#039;algorithme de Kruskal s&#039;applique sur des murs.&lt;br /&gt;
&lt;br /&gt;
On attribue à chaque cellule un identifiant unique.&lt;br /&gt;
&lt;br /&gt;
On choisit&lt;br /&gt;
&lt;br /&gt;
=== Labyrinthes cycliques ===&lt;br /&gt;
&lt;br /&gt;
Il est possible, en retirant un certain pourcentage de murs, de créer des labyrinthes cycliques à partir des labyrinthes acycliques générés auparavant.&lt;br /&gt;
&lt;br /&gt;
Cependant, certains algorithmes de résolution n&#039;auront pas le même comportement.&lt;br /&gt;
&lt;br /&gt;
== Résolution ==&lt;br /&gt;
&lt;br /&gt;
?&lt;br /&gt;
&lt;br /&gt;
=== Exploration exhaustive ===&lt;br /&gt;
&lt;br /&gt;
=== Mur droit ===&lt;br /&gt;
&lt;br /&gt;
== Affichage ==&lt;br /&gt;
&lt;br /&gt;
tkinter &lt;br /&gt;
&lt;br /&gt;
[https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#Exploration_exhaustive tkinter]&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
Mon projet total contenant plusieurs milliers de lignes réparties dans une dizaine de fichiers, je ne peux évidemment pas l&#039;insérer directement dans cette page.&lt;br /&gt;
&lt;br /&gt;
Le code source est disponible sur Github à [https://github.com/Rominos111/Labyrinthe_VISI201 cette adresse]&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
&lt;br /&gt;
Génération&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#Fusion_al%C3%A9atoire_de_chemins Kruskal (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Maze_generation_algorithm#Randomized_Kruskal&#039;s_algorithm Kruskal (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#Exploration_exhaustive Parcours en profondeur (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Maze_generation_algorithm#Randomized_Depth-First_Search Parcours en profondeur (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Résolution&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#R%C3%A9solution Résolution générale (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Maze_solving_algorithm#Wall_follower Mur droit (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Structures de données&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Union-find Union-Find / Disjoint-Set (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Stack_(abstract_data_type) Pile / Stack (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Queue_(abstract_data_type) File / Queue (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;/div&gt;</summary>
		<author><name>Theodet</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11679</id>
		<title>Génération et résolution de labyrinthes II</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11679"/>
		<updated>2019-05-17T10:18:25Z</updated>

		<summary type="html">&lt;p&gt;Theodet : /* Sources */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__FORCETOC__[[Fichier:labyrinthe_photo.png|vignette|300px|Labyrinthe généré avec Kruskal et résolu avec le parcours en profondeur. En route foncé, l&#039;entrée. En vert, la sortie. En bleu, le chemin. En rouge clair, les cellules visitées lors de la résolution.|alt=&amp;quot;Labyrinthe&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
Lorem ipsum&lt;br /&gt;
&lt;br /&gt;
== Représentation ==&lt;br /&gt;
&lt;br /&gt;
=== Propriétés ===&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe est une grille de cellules reliées, ou non, entre elles.&lt;br /&gt;
&lt;br /&gt;
Deux cellules sont reliées entre elles par une &#039;&#039;&#039;porte&#039;&#039;&#039;, ou séparées par un &#039;&#039;&#039;mur&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Tout labyrinthe a &#039;&#039;&#039;une entrée&#039;&#039;&#039; et &#039;&#039;&#039;une sortie&#039;&#039;&#039;, et quelle que soit l&#039;entrée ou la sortie, le chemin entre ces deux cellules est &#039;&#039;&#039;unique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Modélisation en graphe ===&lt;br /&gt;
&lt;br /&gt;
En théorie des graphes, un graphe est un ensemble de &#039;&#039;&#039;points&#039;&#039;&#039; (ou nœuds ou sommets) reliés ensemble par des &#039;&#039;&#039;lignes&#039;&#039;&#039; (ou liens ou arêtes).&lt;br /&gt;
&lt;br /&gt;
[[Fichier:graphe_cyclique.png|vignette|left|300px|Exemple de graphe connexe cyclique non orienté|alt=Graphe cyclique]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Un graphe peut être &#039;&#039;&#039;connexe&#039;&#039;&#039; (en un seul morceau) ou &#039;&#039;&#039;non connexe&#039;&#039;&#039; (en plusieurs morceaux).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Un graphe peut aussi être &#039;&#039;&#039;cyclique&#039;&#039;&#039; si les points sont reliés en formant une boucle ou &#039;&#039;&#039;acyclique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Enfin, un graphe peut être &#039;&#039;&#039;orienté&#039;&#039;&#039; (si les arêtes sont à sens unique) ou &#039;&#039;&#039;non orienté&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Arbre.PNG|vignette|left|300px|Exemple d&#039;arbre|alt=Arbre]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Un &#039;&#039;&#039;arbre&#039;&#039;&#039; est un graphe connexe, acyclique et non orienté.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
En plaçant un point sur chaque cellule de notre labyrinthe, et en reliant deux cellules séparées par une porte, on peut dessiner un arbre à partir de n&#039;importe quel labyrinthe.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:labyrinthe_avec_arbre.png|vignette|centre|300px|Exemple de labyrinthe avec son arbre. Pour plus de simplicité, on attribue à chaque nœud une position.|alt=Labyrinthe avec arbre]]&lt;br /&gt;
&lt;br /&gt;
== Génération ==&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe rectangulaire de largeur &amp;lt;math&amp;gt; L &amp;lt;/math&amp;gt; et de hauteur &amp;lt;math&amp;gt; H &amp;lt;/math&amp;gt; contient exactement &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; portes.&lt;br /&gt;
&lt;br /&gt;
Du point de vue du graphe, il y a donc &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; arêtes.&lt;br /&gt;
&lt;br /&gt;
Maintenant, comment répartir toutes ces portes de façon à ce que toutes les cellules soient accessibles et qu&#039;il n&#039;existe qu&#039;un unique chemin entre l&#039;entrée et la sortie ?&lt;br /&gt;
&lt;br /&gt;
De nombreux algorithmes existent, dont le parcours en profondeur et l&#039;algorithme de Kruskal.&lt;br /&gt;
Chaque algorithme est différent et produit des labyrinthes visuellement différents.&lt;br /&gt;
&lt;br /&gt;
=== Parcours en profondeur ===&lt;br /&gt;
&lt;br /&gt;
[[Fichier:recursive_backtracker.gif|vignette|left|500px|Illustration du parcours en profondeur|alt=Parcours en profondeur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;algorithme du parcours en profondeur (&amp;quot;recursive backtracker&amp;quot; en anglais), on commence sur une cellule aléatoire dans le labyrinthe.&lt;br /&gt;
&lt;br /&gt;
On se dirige dans une direction aléatoire et on casse le mur en face, tout en marquant la cellule précédente comme visitée.&lt;br /&gt;
&lt;br /&gt;
Lorsque aucune direction n&#039;est disponible, on remonte à la position précédente.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:pile.png|vignette|300px|Représentation d&#039;une pile de positions|alt=Pile]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pour sauvegarder l&#039;historique des positions, on peut utiliser une &#039;&#039;&#039;pile&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Une pile est une liste dans laquelle seul le dernier élément peut être récupéré.&lt;br /&gt;
&lt;br /&gt;
Une pile contient 2 méthodes :&lt;br /&gt;
* push(elem) : ajoute elem à la pile&lt;br /&gt;
* pop() -&amp;gt; elem : retourne le dernier élément de la pile (elem dans notre cas)&lt;br /&gt;
&lt;br /&gt;
Dans mon implémentation de la pile, une erreur est levée si l&#039;on appelle la méthode pop sur une pile vide.&lt;br /&gt;
&lt;br /&gt;
=== Kruskal ===&lt;br /&gt;
&lt;br /&gt;
Alors que pour le parcours en profondeur on partait des cellules, l&#039;algorithme de Kruskal s&#039;applique sur des murs.&lt;br /&gt;
&lt;br /&gt;
On attribue à chaque cellule un identifiant unique.&lt;br /&gt;
&lt;br /&gt;
On choisit&lt;br /&gt;
&lt;br /&gt;
=== Labyrinthes cycliques ===&lt;br /&gt;
&lt;br /&gt;
Il est possible, en retirant un certain pourcentage de murs, de créer des labyrinthes cycliques à partir des labyrinthes acycliques générés auparavant.&lt;br /&gt;
&lt;br /&gt;
Cependant, certains algorithmes de résolution n&#039;auront pas le même comportement.&lt;br /&gt;
&lt;br /&gt;
== Résolution ==&lt;br /&gt;
&lt;br /&gt;
?&lt;br /&gt;
&lt;br /&gt;
=== Exploration exhaustive ===&lt;br /&gt;
&lt;br /&gt;
=== Mur droit ===&lt;br /&gt;
&lt;br /&gt;
== Affichage ==&lt;br /&gt;
&lt;br /&gt;
tkinter &lt;br /&gt;
&lt;br /&gt;
[https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#Exploration_exhaustive tkinter]&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
N&#039;ayant pas utilisé de bibliothèques autres que tkinter, mon projet total contient plusieurs milliers de lignes réparties dans une dizaine de fichiers.&lt;br /&gt;
&lt;br /&gt;
Je ne peux donc évidemment pas l&#039;insérer directement dans cette page.&lt;br /&gt;
&lt;br /&gt;
Le code source est disponible sur Github à [https://github.com/Rominos111/Labyrinthe_VISI201 cette adresse]&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
&lt;br /&gt;
Génération&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#Fusion_al%C3%A9atoire_de_chemins Kruskal (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Maze_generation_algorithm#Randomized_Kruskal&#039;s_algorithm Kruskal (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#Exploration_exhaustive Parcours en profondeur (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Maze_generation_algorithm#Randomized_Depth-First_Search Parcours en profondeur (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Résolution&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#R%C3%A9solution Résolution générale (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Maze_solving_algorithm#Wall_follower Mur droit (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Structures de données&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://fr.wikipedia.org/wiki/Union-find Union-Find / Disjoint-Set (fr)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Stack_(abstract_data_type) Pile / Stack (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; [https://en.wikipedia.org/wiki/Queue_(abstract_data_type) File / Queue (en)] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;/div&gt;</summary>
		<author><name>Theodet</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11678</id>
		<title>Génération et résolution de labyrinthes II</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11678"/>
		<updated>2019-05-17T10:04:43Z</updated>

		<summary type="html">&lt;p&gt;Theodet : /* Sources */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__FORCETOC__[[Fichier:labyrinthe_photo.png|vignette|300px|Labyrinthe généré avec Kruskal et résolu avec le parcours en profondeur. En route foncé, l&#039;entrée. En vert, la sortie. En bleu, le chemin. En rouge clair, les cellules visitées lors de la résolution.|alt=&amp;quot;Labyrinthe&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
Lorem ipsum&lt;br /&gt;
&lt;br /&gt;
== Représentation ==&lt;br /&gt;
&lt;br /&gt;
=== Propriétés ===&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe est une grille de cellules reliées, ou non, entre elles.&lt;br /&gt;
&lt;br /&gt;
Deux cellules sont reliées entre elles par une &#039;&#039;&#039;porte&#039;&#039;&#039;, ou séparées par un &#039;&#039;&#039;mur&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Tout labyrinthe a &#039;&#039;&#039;une entrée&#039;&#039;&#039; et &#039;&#039;&#039;une sortie&#039;&#039;&#039;, et quelle que soit l&#039;entrée ou la sortie, le chemin entre ces deux cellules est &#039;&#039;&#039;unique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Modélisation en graphe ===&lt;br /&gt;
&lt;br /&gt;
En théorie des graphes, un graphe est un ensemble de &#039;&#039;&#039;points&#039;&#039;&#039; (ou nœuds ou sommets) reliés ensemble par des &#039;&#039;&#039;lignes&#039;&#039;&#039; (ou liens ou arêtes).&lt;br /&gt;
&lt;br /&gt;
[[Fichier:graphe_cyclique.png|vignette|left|300px|Exemple de graphe connexe cyclique non orienté|alt=Graphe cyclique]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Un graphe peut être &#039;&#039;&#039;connexe&#039;&#039;&#039; (en un seul morceau) ou &#039;&#039;&#039;non connexe&#039;&#039;&#039; (en plusieurs morceaux).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Un graphe peut aussi être &#039;&#039;&#039;cyclique&#039;&#039;&#039; si les points sont reliés en formant une boucle ou &#039;&#039;&#039;acyclique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Enfin, un graphe peut être &#039;&#039;&#039;orienté&#039;&#039;&#039; (si les arêtes sont à sens unique) ou &#039;&#039;&#039;non orienté&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Arbre.PNG|vignette|left|300px|Exemple d&#039;arbre|alt=Arbre]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Un &#039;&#039;&#039;arbre&#039;&#039;&#039; est un graphe connexe, acyclique et non orienté.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
En plaçant un point sur chaque cellule de notre labyrinthe, et en reliant deux cellules séparées par une porte, on peut dessiner un arbre à partir de n&#039;importe quel labyrinthe.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:labyrinthe_avec_arbre.png|vignette|centre|300px|Exemple de labyrinthe avec son arbre. Pour plus de simplicité, on attribue à chaque nœud une position.|alt=Labyrinthe avec arbre]]&lt;br /&gt;
&lt;br /&gt;
== Génération ==&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe rectangulaire de largeur &amp;lt;math&amp;gt; L &amp;lt;/math&amp;gt; et de hauteur &amp;lt;math&amp;gt; H &amp;lt;/math&amp;gt; contient exactement &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; portes.&lt;br /&gt;
&lt;br /&gt;
Du point de vue du graphe, il y a donc &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; arêtes.&lt;br /&gt;
&lt;br /&gt;
Maintenant, comment répartir toutes ces portes de façon à ce que toutes les cellules soient accessibles et qu&#039;il n&#039;existe qu&#039;un unique chemin entre l&#039;entrée et la sortie ?&lt;br /&gt;
&lt;br /&gt;
De nombreux algorithmes existent, dont le parcours en profondeur et l&#039;algorithme de Kruskal.&lt;br /&gt;
Chaque algorithme est différent et produit des labyrinthes visuellement différents.&lt;br /&gt;
&lt;br /&gt;
=== Parcours en profondeur ===&lt;br /&gt;
&lt;br /&gt;
[[Fichier:recursive_backtracker.gif|vignette|left|500px|Illustration du parcours en profondeur|alt=Parcours en profondeur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;algorithme du parcours en profondeur (&amp;quot;recursive backtracker&amp;quot; en anglais), on commence sur une cellule aléatoire dans le labyrinthe.&lt;br /&gt;
&lt;br /&gt;
On se dirige dans une direction aléatoire et on casse le mur en face, tout en marquant la cellule précédente comme visitée.&lt;br /&gt;
&lt;br /&gt;
Lorsque aucune direction n&#039;est disponible, on remonte à la position précédente.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:pile.png|vignette|300px|Représentation d&#039;une pile de positions|alt=Pile]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pour sauvegarder l&#039;historique des positions, on peut utiliser une &#039;&#039;&#039;pile&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Une pile est une liste dans laquelle seul le dernier élément peut être récupéré.&lt;br /&gt;
&lt;br /&gt;
Une pile contient 2 méthodes :&lt;br /&gt;
* push(elem) : ajoute elem à la pile&lt;br /&gt;
* pop() -&amp;gt; elem : retourne le dernier élément de la pile (elem dans notre cas)&lt;br /&gt;
&lt;br /&gt;
Dans mon implémentation de la pile, une erreur est levée si l&#039;on appelle la méthode pop sur une pile vide.&lt;br /&gt;
&lt;br /&gt;
=== Kruskal ===&lt;br /&gt;
&lt;br /&gt;
Alors que pour le parcours en profondeur on partait des cellules, l&#039;algorithme de Kruskal s&#039;applique sur des murs.&lt;br /&gt;
&lt;br /&gt;
On attribue à chaque cellule un identifiant unique.&lt;br /&gt;
&lt;br /&gt;
On choisit&lt;br /&gt;
&lt;br /&gt;
=== Labyrinthes cycliques ===&lt;br /&gt;
&lt;br /&gt;
Il est possible, en retirant un certain pourcentage de murs, de créer des labyrinthes cycliques à partir des labyrinthes acycliques générés auparavant.&lt;br /&gt;
&lt;br /&gt;
Cependant, certains algorithmes de résolution n&#039;auront pas le même comportement.&lt;br /&gt;
&lt;br /&gt;
== Résolution ==&lt;br /&gt;
&lt;br /&gt;
?&lt;br /&gt;
&lt;br /&gt;
=== Exploration exhaustive ===&lt;br /&gt;
&lt;br /&gt;
=== Mur droit ===&lt;br /&gt;
&lt;br /&gt;
== Affichage ==&lt;br /&gt;
&lt;br /&gt;
tkinter &lt;br /&gt;
&lt;br /&gt;
[https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#Exploration_exhaustive tkinter]&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
N&#039;ayant pas utilisé de bibliothèques autres que tkinter, mon projet total contient plusieurs milliers de lignes réparties dans une dizaine de fichiers.&lt;br /&gt;
&lt;br /&gt;
Je ne peux donc évidemment pas l&#039;insérer directement dans cette page.&lt;br /&gt;
&lt;br /&gt;
Le code source est disponible sur Github à [https://github.com/Rominos111/Labyrinthe_VISI201 cette adresse]&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
&lt;br /&gt;
[http://www.lama.univ-savoie.fr/mediawiki/index.php/INFO805_:_Introduction_%C3%A0_l%27Informatique_Graphique Diapo INFO805]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;display:screen&amp;quot; onmouseover=&amp;quot;&amp;gt; eee &amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;pdf-icon-box&amp;quot; style=&amp;quot;position:relative;&amp;quot; onmouseover=&amp;quot;this.getElementsByClassName(&#039;name&#039;)[0].style.backgroundColor = &#039;yellow&#039;&amp;quot;; onmouseout=&amp;quot;this.getElementsByClassName(&#039;name&#039;)[0].style.backgroundColor = &#039;green&#039;&amp;quot;; &amp;gt;&lt;br /&gt;
&amp;lt;span class=&amp;quot;pdf-style&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span class=&amp;quot;name&amp;quot; style=&amp;quot;display:inline-block;background-color:orange;&amp;quot;&amp;gt; T E S T &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>Theodet</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11677</id>
		<title>Génération et résolution de labyrinthes II</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11677"/>
		<updated>2019-05-17T10:02:43Z</updated>

		<summary type="html">&lt;p&gt;Theodet : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__FORCETOC__[[Fichier:labyrinthe_photo.png|vignette|300px|Labyrinthe généré avec Kruskal et résolu avec le parcours en profondeur. En route foncé, l&#039;entrée. En vert, la sortie. En bleu, le chemin. En rouge clair, les cellules visitées lors de la résolution.|alt=&amp;quot;Labyrinthe&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
Lorem ipsum&lt;br /&gt;
&lt;br /&gt;
== Représentation ==&lt;br /&gt;
&lt;br /&gt;
=== Propriétés ===&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe est une grille de cellules reliées, ou non, entre elles.&lt;br /&gt;
&lt;br /&gt;
Deux cellules sont reliées entre elles par une &#039;&#039;&#039;porte&#039;&#039;&#039;, ou séparées par un &#039;&#039;&#039;mur&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Tout labyrinthe a &#039;&#039;&#039;une entrée&#039;&#039;&#039; et &#039;&#039;&#039;une sortie&#039;&#039;&#039;, et quelle que soit l&#039;entrée ou la sortie, le chemin entre ces deux cellules est &#039;&#039;&#039;unique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Modélisation en graphe ===&lt;br /&gt;
&lt;br /&gt;
En théorie des graphes, un graphe est un ensemble de &#039;&#039;&#039;points&#039;&#039;&#039; (ou nœuds ou sommets) reliés ensemble par des &#039;&#039;&#039;lignes&#039;&#039;&#039; (ou liens ou arêtes).&lt;br /&gt;
&lt;br /&gt;
[[Fichier:graphe_cyclique.png|vignette|left|300px|Exemple de graphe connexe cyclique non orienté|alt=Graphe cyclique]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Un graphe peut être &#039;&#039;&#039;connexe&#039;&#039;&#039; (en un seul morceau) ou &#039;&#039;&#039;non connexe&#039;&#039;&#039; (en plusieurs morceaux).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Un graphe peut aussi être &#039;&#039;&#039;cyclique&#039;&#039;&#039; si les points sont reliés en formant une boucle ou &#039;&#039;&#039;acyclique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Enfin, un graphe peut être &#039;&#039;&#039;orienté&#039;&#039;&#039; (si les arêtes sont à sens unique) ou &#039;&#039;&#039;non orienté&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Arbre.PNG|vignette|left|300px|Exemple d&#039;arbre|alt=Arbre]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Un &#039;&#039;&#039;arbre&#039;&#039;&#039; est un graphe connexe, acyclique et non orienté.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
En plaçant un point sur chaque cellule de notre labyrinthe, et en reliant deux cellules séparées par une porte, on peut dessiner un arbre à partir de n&#039;importe quel labyrinthe.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:labyrinthe_avec_arbre.png|vignette|centre|300px|Exemple de labyrinthe avec son arbre. Pour plus de simplicité, on attribue à chaque nœud une position.|alt=Labyrinthe avec arbre]]&lt;br /&gt;
&lt;br /&gt;
== Génération ==&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe rectangulaire de largeur &amp;lt;math&amp;gt; L &amp;lt;/math&amp;gt; et de hauteur &amp;lt;math&amp;gt; H &amp;lt;/math&amp;gt; contient exactement &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; portes.&lt;br /&gt;
&lt;br /&gt;
Du point de vue du graphe, il y a donc &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; arêtes.&lt;br /&gt;
&lt;br /&gt;
Maintenant, comment répartir toutes ces portes de façon à ce que toutes les cellules soient accessibles et qu&#039;il n&#039;existe qu&#039;un unique chemin entre l&#039;entrée et la sortie ?&lt;br /&gt;
&lt;br /&gt;
De nombreux algorithmes existent, dont le parcours en profondeur et l&#039;algorithme de Kruskal.&lt;br /&gt;
Chaque algorithme est différent et produit des labyrinthes visuellement différents.&lt;br /&gt;
&lt;br /&gt;
=== Parcours en profondeur ===&lt;br /&gt;
&lt;br /&gt;
[[Fichier:recursive_backtracker.gif|vignette|left|500px|Illustration du parcours en profondeur|alt=Parcours en profondeur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;algorithme du parcours en profondeur (&amp;quot;recursive backtracker&amp;quot; en anglais), on commence sur une cellule aléatoire dans le labyrinthe.&lt;br /&gt;
&lt;br /&gt;
On se dirige dans une direction aléatoire et on casse le mur en face, tout en marquant la cellule précédente comme visitée.&lt;br /&gt;
&lt;br /&gt;
Lorsque aucune direction n&#039;est disponible, on remonte à la position précédente.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:pile.png|vignette|300px|Représentation d&#039;une pile de positions|alt=Pile]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pour sauvegarder l&#039;historique des positions, on peut utiliser une &#039;&#039;&#039;pile&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Une pile est une liste dans laquelle seul le dernier élément peut être récupéré.&lt;br /&gt;
&lt;br /&gt;
Une pile contient 2 méthodes :&lt;br /&gt;
* push(elem) : ajoute elem à la pile&lt;br /&gt;
* pop() -&amp;gt; elem : retourne le dernier élément de la pile (elem dans notre cas)&lt;br /&gt;
&lt;br /&gt;
Dans mon implémentation de la pile, une erreur est levée si l&#039;on appelle la méthode pop sur une pile vide.&lt;br /&gt;
&lt;br /&gt;
=== Kruskal ===&lt;br /&gt;
&lt;br /&gt;
Alors que pour le parcours en profondeur on partait des cellules, l&#039;algorithme de Kruskal s&#039;applique sur des murs.&lt;br /&gt;
&lt;br /&gt;
On attribue à chaque cellule un identifiant unique.&lt;br /&gt;
&lt;br /&gt;
On choisit&lt;br /&gt;
&lt;br /&gt;
=== Labyrinthes cycliques ===&lt;br /&gt;
&lt;br /&gt;
Il est possible, en retirant un certain pourcentage de murs, de créer des labyrinthes cycliques à partir des labyrinthes acycliques générés auparavant.&lt;br /&gt;
&lt;br /&gt;
Cependant, certains algorithmes de résolution n&#039;auront pas le même comportement.&lt;br /&gt;
&lt;br /&gt;
== Résolution ==&lt;br /&gt;
&lt;br /&gt;
?&lt;br /&gt;
&lt;br /&gt;
=== Exploration exhaustive ===&lt;br /&gt;
&lt;br /&gt;
=== Mur droit ===&lt;br /&gt;
&lt;br /&gt;
== Affichage ==&lt;br /&gt;
&lt;br /&gt;
tkinter &lt;br /&gt;
&lt;br /&gt;
[https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#Exploration_exhaustive tkinter]&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
N&#039;ayant pas utilisé de bibliothèques autres que tkinter, mon projet total contient plusieurs milliers de lignes réparties dans une dizaine de fichiers.&lt;br /&gt;
&lt;br /&gt;
Je ne peux donc évidemment pas l&#039;insérer directement dans cette page.&lt;br /&gt;
&lt;br /&gt;
Le code source est disponible sur Github à [https://github.com/Rominos111/Labyrinthe_VISI201 cette adresse]&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
&lt;br /&gt;
[http://www.lama.univ-savoie.fr/mediawiki/index.php/INFO805_:_Introduction_%C3%A0_l%27Informatique_Graphique Diapo INFO805]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;&amp;quot;&amp;gt; eee &amp;lt;/span&amp;gt;&lt;/div&gt;</summary>
		<author><name>Theodet</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11675</id>
		<title>Génération et résolution de labyrinthes II</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11675"/>
		<updated>2019-05-17T09:44:28Z</updated>

		<summary type="html">&lt;p&gt;Theodet : /* Génération */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__FORCETOC__[[Fichier:labyrinthe_photo.png|vignette|300px|Labyrinthe généré avec Kruskal et résolu avec le parcours en profondeur. En route foncé, l&#039;entrée. En vert, la sortie. En bleu, le chemin. En rouge clair, les cellules visitées lors de la résolution.|alt=&amp;quot;Labyrinthe&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
Lorem ipsum&lt;br /&gt;
&lt;br /&gt;
== Représentation ==&lt;br /&gt;
&lt;br /&gt;
=== Propriétés ===&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe est une grille de cellules reliées, ou non, entre elles.&lt;br /&gt;
&lt;br /&gt;
Deux cellules sont reliées entre elles par une &#039;&#039;&#039;porte&#039;&#039;&#039;, ou séparées par un &#039;&#039;&#039;mur&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Tout labyrinthe a &#039;&#039;&#039;une entrée&#039;&#039;&#039; et &#039;&#039;&#039;une sortie&#039;&#039;&#039;, et quelle que soit l&#039;entrée ou la sortie, le chemin entre ces deux cellules est &#039;&#039;&#039;unique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Modélisation en graphe ===&lt;br /&gt;
&lt;br /&gt;
En théorie des graphes, un graphe est un ensemble de &#039;&#039;&#039;points&#039;&#039;&#039; (ou nœuds ou sommets) reliés ensemble par des &#039;&#039;&#039;lignes&#039;&#039;&#039; (ou liens ou arêtes).&lt;br /&gt;
&lt;br /&gt;
[[Fichier:graphe_cyclique.png|vignette|left|300px|Exemple de graphe connexe cyclique non orienté|alt=Graphe cyclique]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Un graphe peut être &#039;&#039;&#039;connexe&#039;&#039;&#039; (en un seul morceau) ou &#039;&#039;&#039;non connexe&#039;&#039;&#039; (en plusieurs morceaux).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Un graphe peut aussi être &#039;&#039;&#039;cyclique&#039;&#039;&#039; si les points sont reliés en formant une boucle ou &#039;&#039;&#039;acyclique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Enfin, un graphe peut être &#039;&#039;&#039;orienté&#039;&#039;&#039; (si les arêtes sont à sens unique) ou &#039;&#039;&#039;non orienté&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Arbre.PNG|vignette|left|300px|Exemple d&#039;arbre|alt=Arbre]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Un &#039;&#039;&#039;arbre&#039;&#039;&#039; est un graphe connexe, acyclique et non orienté.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
En plaçant un point sur chaque cellule de notre labyrinthe, et en reliant deux cellules séparées par une porte, on peut dessiner un arbre à partir de n&#039;importe quel labyrinthe.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:labyrinthe_avec_arbre.png|vignette|centre|300px|Exemple de labyrinthe avec son arbre. Pour plus de simplicité, on attribue à chaque nœud une position.|alt=Labyrinthe avec arbre]]&lt;br /&gt;
&lt;br /&gt;
== Génération ==&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe rectangulaire de largeur &amp;lt;math&amp;gt; L &amp;lt;/math&amp;gt; et de hauteur &amp;lt;math&amp;gt; H &amp;lt;/math&amp;gt; contient exactement &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; portes.&lt;br /&gt;
&lt;br /&gt;
Du point de vue du graphe, il y a donc &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; arêtes.&lt;br /&gt;
&lt;br /&gt;
Maintenant, comment répartir toutes ces portes de façon à ce que toutes les cellules soient accessibles et qu&#039;il n&#039;existe qu&#039;un unique chemin entre l&#039;entrée et la sortie ?&lt;br /&gt;
&lt;br /&gt;
De nombreux algorithmes existent, dont le parcours en profondeur et l&#039;algorithme de Kruskal.&lt;br /&gt;
Chaque algorithme est différent et produit des labyrinthes visuellement différents.&lt;br /&gt;
&lt;br /&gt;
=== Parcours en profondeur ===&lt;br /&gt;
&lt;br /&gt;
[[Fichier:recursive_backtracker.gif|vignette|left|500px|Illustration du parcours en profondeur|alt=Parcours en profondeur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;algorithme du parcours en profondeur (&amp;quot;recursive backtracker&amp;quot; en anglais), on commence sur une cellule aléatoire dans le labyrinthe.&lt;br /&gt;
&lt;br /&gt;
On se dirige dans une direction aléatoire et on casse le mur en face, tout en marquant la cellule précédente comme visitée.&lt;br /&gt;
&lt;br /&gt;
Lorsque aucune direction n&#039;est disponible, on remonte à la position précédente.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:pile.png|vignette|300px|Représentation d&#039;une pile de positions|alt=Pile]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pour sauvegarder l&#039;historique des positions, on peut utiliser une &#039;&#039;&#039;pile&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Une pile est une liste dans laquelle seul le dernier élément peut être récupéré.&lt;br /&gt;
&lt;br /&gt;
Une pile contient 2 méthodes :&lt;br /&gt;
* push(elem) : ajoute elem à la pile&lt;br /&gt;
* pop() -&amp;gt; elem : retourne le dernier élément de la pile (elem dans notre cas)&lt;br /&gt;
&lt;br /&gt;
Dans mon implémentation de la pile, une erreur est levée si l&#039;on appelle la méthode pop sur une pile vide.&lt;br /&gt;
&lt;br /&gt;
=== Kruskal ===&lt;br /&gt;
&lt;br /&gt;
Alors que pour le parcours en profondeur on partait des cellules, l&#039;algorithme de Kruskal s&#039;applique sur des murs.&lt;br /&gt;
&lt;br /&gt;
On attribue à chaque cellule un identifiant unique.&lt;br /&gt;
&lt;br /&gt;
On choisit&lt;br /&gt;
&lt;br /&gt;
=== Labyrinthes cycliques ===&lt;br /&gt;
&lt;br /&gt;
Il est possible, en retirant un certain pourcentage de murs, de créer des labyrinthes cycliques à partir des labyrinthes acycliques générés auparavant.&lt;br /&gt;
&lt;br /&gt;
Cependant, certains algorithmes de résolution n&#039;auront pas le même comportement.&lt;br /&gt;
&lt;br /&gt;
== Résolution ==&lt;br /&gt;
&lt;br /&gt;
?&lt;br /&gt;
&lt;br /&gt;
=== Exploration exhaustive ===&lt;br /&gt;
&lt;br /&gt;
=== Mur droit ===&lt;br /&gt;
&lt;br /&gt;
== Structures de données ==&lt;br /&gt;
&lt;br /&gt;
=== Union-Find ===&lt;br /&gt;
&lt;br /&gt;
Dijoint Set&lt;br /&gt;
&lt;br /&gt;
=== Pile ===&lt;br /&gt;
&lt;br /&gt;
Stack&lt;br /&gt;
&lt;br /&gt;
=== File ===&lt;br /&gt;
&lt;br /&gt;
Queue&lt;br /&gt;
&lt;br /&gt;
== Affichage ==&lt;br /&gt;
&lt;br /&gt;
tkinter &lt;br /&gt;
&lt;br /&gt;
[https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#Exploration_exhaustive tkinter]&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
N&#039;ayant pas utilisé de bibliothèques autres que tkinter, mon projet total contient plusieurs milliers de lignes réparties dans une dizaine de fichiers.&lt;br /&gt;
&lt;br /&gt;
Je ne peux donc évidemment pas l&#039;insérer directement dans cette page.&lt;br /&gt;
&lt;br /&gt;
Le code source est disponible sur Github à [https://github.com/Rominos111/Labyrinthe_VISI201 cette adresse]&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
&lt;br /&gt;
== Annexes ==&lt;/div&gt;</summary>
		<author><name>Theodet</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11674</id>
		<title>Génération et résolution de labyrinthes II</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11674"/>
		<updated>2019-05-17T09:40:56Z</updated>

		<summary type="html">&lt;p&gt;Theodet : /* Parcours en profondeur */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__FORCETOC__[[Fichier:labyrinthe_photo.png|vignette|300px|Labyrinthe généré avec Kruskal et résolu avec le parcours en profondeur. En route foncé, l&#039;entrée. En vert, la sortie. En bleu, le chemin. En rouge clair, les cellules visitées lors de la résolution.|alt=&amp;quot;Labyrinthe&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
Lorem ipsum&lt;br /&gt;
&lt;br /&gt;
== Représentation ==&lt;br /&gt;
&lt;br /&gt;
=== Propriétés ===&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe est une grille de cellules reliées, ou non, entre elles.&lt;br /&gt;
&lt;br /&gt;
Deux cellules sont reliées entre elles par une &#039;&#039;&#039;porte&#039;&#039;&#039;, ou séparées par un &#039;&#039;&#039;mur&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Tout labyrinthe a &#039;&#039;&#039;une entrée&#039;&#039;&#039; et &#039;&#039;&#039;une sortie&#039;&#039;&#039;, et quelle que soit l&#039;entrée ou la sortie, le chemin entre ces deux cellules est &#039;&#039;&#039;unique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Modélisation en graphe ===&lt;br /&gt;
&lt;br /&gt;
En théorie des graphes, un graphe est un ensemble de &#039;&#039;&#039;points&#039;&#039;&#039; (ou nœuds ou sommets) reliés ensemble par des &#039;&#039;&#039;lignes&#039;&#039;&#039; (ou liens ou arêtes).&lt;br /&gt;
&lt;br /&gt;
[[Fichier:graphe_cyclique.png|vignette|left|300px|Exemple de graphe connexe cyclique non orienté|alt=Graphe cyclique]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Un graphe peut être &#039;&#039;&#039;connexe&#039;&#039;&#039; (en un seul morceau) ou &#039;&#039;&#039;non connexe&#039;&#039;&#039; (en plusieurs morceaux).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Un graphe peut aussi être &#039;&#039;&#039;cyclique&#039;&#039;&#039; si les points sont reliés en formant une boucle ou &#039;&#039;&#039;acyclique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Enfin, un graphe peut être &#039;&#039;&#039;orienté&#039;&#039;&#039; (si les arêtes sont à sens unique) ou &#039;&#039;&#039;non orienté&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Arbre.PNG|vignette|left|300px|Exemple d&#039;arbre|alt=Arbre]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Un &#039;&#039;&#039;arbre&#039;&#039;&#039; est un graphe connexe, acyclique et non orienté.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
En plaçant un point sur chaque cellule de notre labyrinthe, et en reliant deux cellules séparées par une porte, on peut dessiner un arbre à partir de n&#039;importe quel labyrinthe.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:labyrinthe_avec_arbre.png|vignette|centre|300px|Exemple de labyrinthe avec son arbre. Pour plus de simplicité, on attribue à chaque nœud une position.|alt=Labyrinthe avec arbre]]&lt;br /&gt;
&lt;br /&gt;
== Génération ==&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe rectangulaire de largeur &amp;lt;math&amp;gt; L &amp;lt;/math&amp;gt; et de hauteur &amp;lt;math&amp;gt; H &amp;lt;/math&amp;gt; contient exactement &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; portes.&lt;br /&gt;
&lt;br /&gt;
Du point de vue du graphe, il y a donc &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; arêtes.&lt;br /&gt;
&lt;br /&gt;
Maintenant, comment répartir toutes ces portes de façon à ce que toutes les cellules soient accessibles et qu&#039;il n&#039;existe qu&#039;un unique chemin entre l&#039;entrée et la sortie ?&lt;br /&gt;
&lt;br /&gt;
De nombreux algorithmes existent, dont le parcours en profondeur et l&#039;algorithme de Kruskal.&lt;br /&gt;
Chaque algorithme est différent et produit des labyrinthes visuellement différents.&lt;br /&gt;
&lt;br /&gt;
=== Parcours en profondeur ===&lt;br /&gt;
&lt;br /&gt;
[[Fichier:recursive_backtracker.gif|vignette|right|500px|Illustration du parcours en profondeur|alt=Parcours en profondeur]]&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;algorithme du parcours en profondeur (&amp;quot;recursive backtracker&amp;quot; en anglais), on commence sur une cellule aléatoire dans le labyrinthe.&lt;br /&gt;
&lt;br /&gt;
On se dirige dans une direction aléatoire et on casse le mur en face, tout en marquant la cellule précédente comme visitée.&lt;br /&gt;
&lt;br /&gt;
Lorsque aucune direction n&#039;est disponible, on remonte à la position précédente.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:pile.png|vignette|right|300px|Représentation d&#039;une pile de positions|alt=Pile]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pour sauvegarder l&#039;historique des positions, on peut utiliser une &#039;&#039;&#039;pile&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Une pile est une liste dans laquelle seul le dernier élément peut être récupéré.&lt;br /&gt;
&lt;br /&gt;
Une pile contient 2 méthodes :&lt;br /&gt;
* push(elem) : ajoute elem à la pile&lt;br /&gt;
* pop() -&amp;gt; elem : retourne le dernier élément de la pile (elem dans notre cas)&lt;br /&gt;
&lt;br /&gt;
Dans mon implémentation de la pile, une erreur est levée si l&#039;on appelle la méthode pop sur une pile vide.&lt;br /&gt;
&lt;br /&gt;
=== Kruskal ===&lt;br /&gt;
&lt;br /&gt;
Alors que pour le parcours en profondeur on partait des cellules, l&#039;algorithme de Kruskal s&#039;applique sur des murs.&lt;br /&gt;
&lt;br /&gt;
On attribue à chaque cellule un identifiant unique.&lt;br /&gt;
&lt;br /&gt;
On choisit&lt;br /&gt;
&lt;br /&gt;
=== Labyrinthes cycliques ===&lt;br /&gt;
&lt;br /&gt;
Il est possible, en retirant un certain pourcentage de murs, de créer des labyrinthes cycliques à partir des labyrinthes acycliques générés auparavant.&lt;br /&gt;
&lt;br /&gt;
Cependant, certains algorithmes de résolution n&#039;auront pas le même comportement.&lt;br /&gt;
&lt;br /&gt;
== Résolution ==&lt;br /&gt;
&lt;br /&gt;
?&lt;br /&gt;
&lt;br /&gt;
=== Exploration exhaustive ===&lt;br /&gt;
&lt;br /&gt;
=== Mur droit ===&lt;br /&gt;
&lt;br /&gt;
== Structures de données ==&lt;br /&gt;
&lt;br /&gt;
=== Union-Find ===&lt;br /&gt;
&lt;br /&gt;
Dijoint Set&lt;br /&gt;
&lt;br /&gt;
=== Pile ===&lt;br /&gt;
&lt;br /&gt;
Stack&lt;br /&gt;
&lt;br /&gt;
=== File ===&lt;br /&gt;
&lt;br /&gt;
Queue&lt;br /&gt;
&lt;br /&gt;
== Affichage ==&lt;br /&gt;
&lt;br /&gt;
tkinter &lt;br /&gt;
&lt;br /&gt;
[https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#Exploration_exhaustive tkinter]&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
N&#039;ayant pas utilisé de bibliothèques autres que tkinter, mon projet total contient plusieurs milliers de lignes réparties dans une dizaine de fichiers.&lt;br /&gt;
&lt;br /&gt;
Je ne peux donc évidemment pas l&#039;insérer directement dans cette page.&lt;br /&gt;
&lt;br /&gt;
Le code source est disponible sur Github à [https://github.com/Rominos111/Labyrinthe_VISI201 cette adresse]&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
&lt;br /&gt;
== Annexes ==&lt;/div&gt;</summary>
		<author><name>Theodet</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11673</id>
		<title>Génération et résolution de labyrinthes II</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11673"/>
		<updated>2019-05-17T09:39:38Z</updated>

		<summary type="html">&lt;p&gt;Theodet : /* Modélisation en graphe */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__FORCETOC__[[Fichier:labyrinthe_photo.png|vignette|300px|Labyrinthe généré avec Kruskal et résolu avec le parcours en profondeur. En route foncé, l&#039;entrée. En vert, la sortie. En bleu, le chemin. En rouge clair, les cellules visitées lors de la résolution.|alt=&amp;quot;Labyrinthe&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
Lorem ipsum&lt;br /&gt;
&lt;br /&gt;
== Représentation ==&lt;br /&gt;
&lt;br /&gt;
=== Propriétés ===&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe est une grille de cellules reliées, ou non, entre elles.&lt;br /&gt;
&lt;br /&gt;
Deux cellules sont reliées entre elles par une &#039;&#039;&#039;porte&#039;&#039;&#039;, ou séparées par un &#039;&#039;&#039;mur&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Tout labyrinthe a &#039;&#039;&#039;une entrée&#039;&#039;&#039; et &#039;&#039;&#039;une sortie&#039;&#039;&#039;, et quelle que soit l&#039;entrée ou la sortie, le chemin entre ces deux cellules est &#039;&#039;&#039;unique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Modélisation en graphe ===&lt;br /&gt;
&lt;br /&gt;
En théorie des graphes, un graphe est un ensemble de &#039;&#039;&#039;points&#039;&#039;&#039; (ou nœuds ou sommets) reliés ensemble par des &#039;&#039;&#039;lignes&#039;&#039;&#039; (ou liens ou arêtes).&lt;br /&gt;
&lt;br /&gt;
[[Fichier:graphe_cyclique.png|vignette|left|300px|Exemple de graphe connexe cyclique non orienté|alt=Graphe cyclique]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Un graphe peut être &#039;&#039;&#039;connexe&#039;&#039;&#039; (en un seul morceau) ou &#039;&#039;&#039;non connexe&#039;&#039;&#039; (en plusieurs morceaux).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Un graphe peut aussi être &#039;&#039;&#039;cyclique&#039;&#039;&#039; si les points sont reliés en formant une boucle ou &#039;&#039;&#039;acyclique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Enfin, un graphe peut être &#039;&#039;&#039;orienté&#039;&#039;&#039; (si les arêtes sont à sens unique) ou &#039;&#039;&#039;non orienté&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Arbre.PNG|vignette|left|300px|Exemple d&#039;arbre|alt=Arbre]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Un &#039;&#039;&#039;arbre&#039;&#039;&#039; est un graphe connexe, acyclique et non orienté.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
En plaçant un point sur chaque cellule de notre labyrinthe, et en reliant deux cellules séparées par une porte, on peut dessiner un arbre à partir de n&#039;importe quel labyrinthe.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:labyrinthe_avec_arbre.png|vignette|centre|300px|Exemple de labyrinthe avec son arbre. Pour plus de simplicité, on attribue à chaque nœud une position.|alt=Labyrinthe avec arbre]]&lt;br /&gt;
&lt;br /&gt;
== Génération ==&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe rectangulaire de largeur &amp;lt;math&amp;gt; L &amp;lt;/math&amp;gt; et de hauteur &amp;lt;math&amp;gt; H &amp;lt;/math&amp;gt; contient exactement &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; portes.&lt;br /&gt;
&lt;br /&gt;
Du point de vue du graphe, il y a donc &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; arêtes.&lt;br /&gt;
&lt;br /&gt;
Maintenant, comment répartir toutes ces portes de façon à ce que toutes les cellules soient accessibles et qu&#039;il n&#039;existe qu&#039;un unique chemin entre l&#039;entrée et la sortie ?&lt;br /&gt;
&lt;br /&gt;
De nombreux algorithmes existent, dont le parcours en profondeur et l&#039;algorithme de Kruskal.&lt;br /&gt;
Chaque algorithme est différent et produit des labyrinthes visuellement différents.&lt;br /&gt;
&lt;br /&gt;
=== Parcours en profondeur ===&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;algorithme du parcours en profondeur (&amp;quot;recursive backtracker&amp;quot; en anglais), on commence sur une cellule aléatoire dans le labyrinthe.&lt;br /&gt;
&lt;br /&gt;
On se dirige dans une direction aléatoire et on casse le mur en face, tout en marquant la cellule précédente comme visitée.&lt;br /&gt;
&lt;br /&gt;
Lorsque aucune direction n&#039;est disponible, on remonte à la position précédente.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:recursive_backtracker.gif|vignette|centre|500px|Illustration du parcours en profondeur|alt=Parcours en profondeur]]&lt;br /&gt;
&lt;br /&gt;
Pour sauvegarder l&#039;historique des positions, on peut utiliser une &#039;&#039;&#039;pile&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Une pile est une liste dans laquelle seul le dernier élément peut être récupéré.&lt;br /&gt;
&lt;br /&gt;
Une pile contient 2 méthodes :&lt;br /&gt;
* push(elem) : ajoute elem à la pile&lt;br /&gt;
* pop() -&amp;gt; elem : retourne le dernier élément de la pile (elem dans notre cas)&lt;br /&gt;
&lt;br /&gt;
Dans mon implémentation de la pile, une erreur est levée si l&#039;on appelle la méthode pop sur une pile vide.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:pile.png|vignette|centre|300px|Représentation d&#039;une pile de positions|alt=Pile]]&lt;br /&gt;
&lt;br /&gt;
=== Kruskal ===&lt;br /&gt;
&lt;br /&gt;
Alors que pour le parcours en profondeur on partait des cellules, l&#039;algorithme de Kruskal s&#039;applique sur des murs.&lt;br /&gt;
&lt;br /&gt;
On attribue à chaque cellule un identifiant unique.&lt;br /&gt;
&lt;br /&gt;
On choisit&lt;br /&gt;
&lt;br /&gt;
=== Labyrinthes cycliques ===&lt;br /&gt;
&lt;br /&gt;
Il est possible, en retirant un certain pourcentage de murs, de créer des labyrinthes cycliques à partir des labyrinthes acycliques générés auparavant.&lt;br /&gt;
&lt;br /&gt;
Cependant, certains algorithmes de résolution n&#039;auront pas le même comportement.&lt;br /&gt;
&lt;br /&gt;
== Résolution ==&lt;br /&gt;
&lt;br /&gt;
?&lt;br /&gt;
&lt;br /&gt;
=== Exploration exhaustive ===&lt;br /&gt;
&lt;br /&gt;
=== Mur droit ===&lt;br /&gt;
&lt;br /&gt;
== Structures de données ==&lt;br /&gt;
&lt;br /&gt;
=== Union-Find ===&lt;br /&gt;
&lt;br /&gt;
Dijoint Set&lt;br /&gt;
&lt;br /&gt;
=== Pile ===&lt;br /&gt;
&lt;br /&gt;
Stack&lt;br /&gt;
&lt;br /&gt;
=== File ===&lt;br /&gt;
&lt;br /&gt;
Queue&lt;br /&gt;
&lt;br /&gt;
== Affichage ==&lt;br /&gt;
&lt;br /&gt;
tkinter &lt;br /&gt;
&lt;br /&gt;
[https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#Exploration_exhaustive tkinter]&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
N&#039;ayant pas utilisé de bibliothèques autres que tkinter, mon projet total contient plusieurs milliers de lignes réparties dans une dizaine de fichiers.&lt;br /&gt;
&lt;br /&gt;
Je ne peux donc évidemment pas l&#039;insérer directement dans cette page.&lt;br /&gt;
&lt;br /&gt;
Le code source est disponible sur Github à [https://github.com/Rominos111/Labyrinthe_VISI201 cette adresse]&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
&lt;br /&gt;
== Annexes ==&lt;/div&gt;</summary>
		<author><name>Theodet</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11672</id>
		<title>Génération et résolution de labyrinthes II</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11672"/>
		<updated>2019-05-17T09:36:27Z</updated>

		<summary type="html">&lt;p&gt;Theodet : /* Modélisation en graphe */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__FORCETOC__[[Fichier:labyrinthe_photo.png|vignette|300px|Labyrinthe généré avec Kruskal et résolu avec le parcours en profondeur. En route foncé, l&#039;entrée. En vert, la sortie. En bleu, le chemin. En rouge clair, les cellules visitées lors de la résolution.|alt=&amp;quot;Labyrinthe&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
Lorem ipsum&lt;br /&gt;
&lt;br /&gt;
== Représentation ==&lt;br /&gt;
&lt;br /&gt;
=== Propriétés ===&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe est une grille de cellules reliées, ou non, entre elles.&lt;br /&gt;
&lt;br /&gt;
Deux cellules sont reliées entre elles par une &#039;&#039;&#039;porte&#039;&#039;&#039;, ou séparées par un &#039;&#039;&#039;mur&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Tout labyrinthe a &#039;&#039;&#039;une entrée&#039;&#039;&#039; et &#039;&#039;&#039;une sortie&#039;&#039;&#039;, et quelle que soit l&#039;entrée ou la sortie, le chemin entre ces deux cellules est &#039;&#039;&#039;unique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Modélisation en graphe ===&lt;br /&gt;
&lt;br /&gt;
En théorie des graphes, un graphe est un ensemble de &#039;&#039;&#039;points&#039;&#039;&#039; (ou nœuds ou sommets) reliés ensemble par des &#039;&#039;&#039;lignes&#039;&#039;&#039; (ou liens ou arêtes).&lt;br /&gt;
&lt;br /&gt;
Un graphe peut être &#039;&#039;&#039;connexe&#039;&#039;&#039; (en un seul morceau) ou &#039;&#039;&#039;non connexe&#039;&#039;&#039; (en plusieurs morceaux).&lt;br /&gt;
&lt;br /&gt;
Un graphe peut aussi être &#039;&#039;&#039;cyclique&#039;&#039;&#039; si les points sont reliés en formant une boucle ou &#039;&#039;&#039;acyclique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Enfin, un graphe peut être &#039;&#039;&#039;orienté&#039;&#039;&#039; (si les arêtes sont à sens unique) ou &#039;&#039;&#039;non orienté&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:graphe_cyclique.png|vignette|centre|300px|Exemple de graphe connexe cyclique non orienté|alt=Graphe cyclique]]&lt;br /&gt;
&lt;br /&gt;
Un &#039;&#039;&#039;arbre&#039;&#039;&#039; est un graphe connexe, acyclique et non orienté.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Arbre.PNG|vignette|centre|300px|Exemple d&#039;arbre|alt=Arbre]]&lt;br /&gt;
&lt;br /&gt;
En plaçant un point sur chaque cellule de notre labyrinthe, et en reliant deux cellules séparées par une porte, on peut dessiner un arbre comme ceci :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:labyrinthe_avec_arbre.png|vignette|centre|300px|Exemple de labyrinthe avec son arbre. Pour plus de simplicité, on attribue à chaque nœud une position.|alt=Labyrinthe avec arbre]]&lt;br /&gt;
&lt;br /&gt;
== Génération ==&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe rectangulaire de largeur &amp;lt;math&amp;gt; L &amp;lt;/math&amp;gt; et de hauteur &amp;lt;math&amp;gt; H &amp;lt;/math&amp;gt; contient exactement &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; portes.&lt;br /&gt;
&lt;br /&gt;
Du point de vue du graphe, il y a donc &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; arêtes.&lt;br /&gt;
&lt;br /&gt;
Maintenant, comment répartir toutes ces portes de façon à ce que toutes les cellules soient accessibles et qu&#039;il n&#039;existe qu&#039;un unique chemin entre l&#039;entrée et la sortie ?&lt;br /&gt;
&lt;br /&gt;
De nombreux algorithmes existent, dont le parcours en profondeur et l&#039;algorithme de Kruskal.&lt;br /&gt;
Chaque algorithme est différent et produit des labyrinthes visuellement différents.&lt;br /&gt;
&lt;br /&gt;
=== Parcours en profondeur ===&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;algorithme du parcours en profondeur (&amp;quot;recursive backtracker&amp;quot; en anglais), on commence sur une cellule aléatoire dans le labyrinthe.&lt;br /&gt;
&lt;br /&gt;
On se dirige dans une direction aléatoire et on casse le mur en face, tout en marquant la cellule précédente comme visitée.&lt;br /&gt;
&lt;br /&gt;
Lorsque aucune direction n&#039;est disponible, on remonte à la position précédente.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:recursive_backtracker.gif|vignette|centre|500px|Illustration du parcours en profondeur|alt=Parcours en profondeur]]&lt;br /&gt;
&lt;br /&gt;
Pour sauvegarder l&#039;historique des positions, on peut utiliser une &#039;&#039;&#039;pile&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Une pile est une liste dans laquelle seul le dernier élément peut être récupéré.&lt;br /&gt;
&lt;br /&gt;
Une pile contient 2 méthodes :&lt;br /&gt;
* push(elem) : ajoute elem à la pile&lt;br /&gt;
* pop() -&amp;gt; elem : retourne le dernier élément de la pile (elem dans notre cas)&lt;br /&gt;
&lt;br /&gt;
Dans mon implémentation de la pile, une erreur est levée si l&#039;on appelle la méthode pop sur une pile vide.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:pile.png|vignette|centre|300px|Représentation d&#039;une pile de positions|alt=Pile]]&lt;br /&gt;
&lt;br /&gt;
=== Kruskal ===&lt;br /&gt;
&lt;br /&gt;
Alors que pour le parcours en profondeur on partait des cellules, l&#039;algorithme de Kruskal s&#039;applique sur des murs.&lt;br /&gt;
&lt;br /&gt;
On attribue à chaque cellule un identifiant unique.&lt;br /&gt;
&lt;br /&gt;
On choisit&lt;br /&gt;
&lt;br /&gt;
=== Labyrinthes cycliques ===&lt;br /&gt;
&lt;br /&gt;
Il est possible, en retirant un certain pourcentage de murs, de créer des labyrinthes cycliques à partir des labyrinthes acycliques générés auparavant.&lt;br /&gt;
&lt;br /&gt;
Cependant, certains algorithmes de résolution n&#039;auront pas le même comportement.&lt;br /&gt;
&lt;br /&gt;
== Résolution ==&lt;br /&gt;
&lt;br /&gt;
?&lt;br /&gt;
&lt;br /&gt;
=== Exploration exhaustive ===&lt;br /&gt;
&lt;br /&gt;
=== Mur droit ===&lt;br /&gt;
&lt;br /&gt;
== Structures de données ==&lt;br /&gt;
&lt;br /&gt;
=== Union-Find ===&lt;br /&gt;
&lt;br /&gt;
Dijoint Set&lt;br /&gt;
&lt;br /&gt;
=== Pile ===&lt;br /&gt;
&lt;br /&gt;
Stack&lt;br /&gt;
&lt;br /&gt;
=== File ===&lt;br /&gt;
&lt;br /&gt;
Queue&lt;br /&gt;
&lt;br /&gt;
== Affichage ==&lt;br /&gt;
&lt;br /&gt;
tkinter &lt;br /&gt;
&lt;br /&gt;
[https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#Exploration_exhaustive tkinter]&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
N&#039;ayant pas utilisé de bibliothèques autres que tkinter, mon projet total contient plusieurs milliers de lignes réparties dans une dizaine de fichiers.&lt;br /&gt;
&lt;br /&gt;
Je ne peux donc évidemment pas l&#039;insérer directement dans cette page.&lt;br /&gt;
&lt;br /&gt;
Le code source est disponible sur Github à [https://github.com/Rominos111/Labyrinthe_VISI201 cette adresse]&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
&lt;br /&gt;
== Annexes ==&lt;/div&gt;</summary>
		<author><name>Theodet</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11671</id>
		<title>Génération et résolution de labyrinthes II</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11671"/>
		<updated>2019-05-17T09:35:46Z</updated>

		<summary type="html">&lt;p&gt;Theodet : /* Parcours en profondeur */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__FORCETOC__[[Fichier:labyrinthe_photo.png|vignette|300px|Labyrinthe généré avec Kruskal et résolu avec le parcours en profondeur. En route foncé, l&#039;entrée. En vert, la sortie. En bleu, le chemin. En rouge clair, les cellules visitées lors de la résolution.|alt=&amp;quot;Labyrinthe&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
Lorem ipsum&lt;br /&gt;
&lt;br /&gt;
== Représentation ==&lt;br /&gt;
&lt;br /&gt;
=== Propriétés ===&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe est une grille de cellules reliées, ou non, entre elles.&lt;br /&gt;
&lt;br /&gt;
Deux cellules sont reliées entre elles par une &#039;&#039;&#039;porte&#039;&#039;&#039;, ou séparées par un &#039;&#039;&#039;mur&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Tout labyrinthe a &#039;&#039;&#039;une entrée&#039;&#039;&#039; et &#039;&#039;&#039;une sortie&#039;&#039;&#039;, et quelle que soit l&#039;entrée ou la sortie, le chemin entre ces deux cellules est &#039;&#039;&#039;unique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Modélisation en graphe ===&lt;br /&gt;
&lt;br /&gt;
En théorie des graphes, un graphe est un ensemble de &#039;&#039;&#039;points&#039;&#039;&#039; (ou nœuds ou sommets) reliés ensemble par des &#039;&#039;&#039;lignes&#039;&#039;&#039; (ou liens ou arêtes).&lt;br /&gt;
&lt;br /&gt;
Un graphe peut être &#039;&#039;&#039;connexe&#039;&#039;&#039; (en un seul morceau) ou &#039;&#039;&#039;non connexe&#039;&#039;&#039; (en plusieurs morceaux).&lt;br /&gt;
&lt;br /&gt;
Un graphe peut aussi être &#039;&#039;&#039;cyclique&#039;&#039;&#039; si les points sont reliés en formant une boucle ou &#039;&#039;&#039;acyclique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Enfin, un graphe peut être &#039;&#039;&#039;orienté&#039;&#039;&#039; (si les arêtes sont à sens unique) ou &#039;&#039;&#039;non orienté&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:graphe_cyclique.png|vignette|centre|500px|Exemple de graphe connexe cyclique non orienté|alt=Graphe cyclique]]&lt;br /&gt;
&lt;br /&gt;
Un &#039;&#039;&#039;arbre&#039;&#039;&#039; est un graphe connexe, acyclique et non orienté.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Arbre.PNG|vignette|centre|500px|Exemple d&#039;arbre|alt=Arbre]]&lt;br /&gt;
&lt;br /&gt;
En plaçant un point sur chaque cellule de notre labyrinthe, et en reliant deux cellules séparées par une porte, on peut dessiner un arbre comme ceci :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:labyrinthe_avec_arbre.png|vignette|centre|500px|Exemple de labyrinthe avec son arbre. Pour plus de simplicité, on attribue à chaque nœud une position.|alt=Labyrinthe avec arbre]]&lt;br /&gt;
&lt;br /&gt;
== Génération ==&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe rectangulaire de largeur &amp;lt;math&amp;gt; L &amp;lt;/math&amp;gt; et de hauteur &amp;lt;math&amp;gt; H &amp;lt;/math&amp;gt; contient exactement &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; portes.&lt;br /&gt;
&lt;br /&gt;
Du point de vue du graphe, il y a donc &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; arêtes.&lt;br /&gt;
&lt;br /&gt;
Maintenant, comment répartir toutes ces portes de façon à ce que toutes les cellules soient accessibles et qu&#039;il n&#039;existe qu&#039;un unique chemin entre l&#039;entrée et la sortie ?&lt;br /&gt;
&lt;br /&gt;
De nombreux algorithmes existent, dont le parcours en profondeur et l&#039;algorithme de Kruskal.&lt;br /&gt;
Chaque algorithme est différent et produit des labyrinthes visuellement différents.&lt;br /&gt;
&lt;br /&gt;
=== Parcours en profondeur ===&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;algorithme du parcours en profondeur (&amp;quot;recursive backtracker&amp;quot; en anglais), on commence sur une cellule aléatoire dans le labyrinthe.&lt;br /&gt;
&lt;br /&gt;
On se dirige dans une direction aléatoire et on casse le mur en face, tout en marquant la cellule précédente comme visitée.&lt;br /&gt;
&lt;br /&gt;
Lorsque aucune direction n&#039;est disponible, on remonte à la position précédente.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:recursive_backtracker.gif|vignette|centre|500px|Illustration du parcours en profondeur|alt=Parcours en profondeur]]&lt;br /&gt;
&lt;br /&gt;
Pour sauvegarder l&#039;historique des positions, on peut utiliser une &#039;&#039;&#039;pile&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Une pile est une liste dans laquelle seul le dernier élément peut être récupéré.&lt;br /&gt;
&lt;br /&gt;
Une pile contient 2 méthodes :&lt;br /&gt;
* push(elem) : ajoute elem à la pile&lt;br /&gt;
* pop() -&amp;gt; elem : retourne le dernier élément de la pile (elem dans notre cas)&lt;br /&gt;
&lt;br /&gt;
Dans mon implémentation de la pile, une erreur est levée si l&#039;on appelle la méthode pop sur une pile vide.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:pile.png|vignette|centre|300px|Représentation d&#039;une pile de positions|alt=Pile]]&lt;br /&gt;
&lt;br /&gt;
=== Kruskal ===&lt;br /&gt;
&lt;br /&gt;
Alors que pour le parcours en profondeur on partait des cellules, l&#039;algorithme de Kruskal s&#039;applique sur des murs.&lt;br /&gt;
&lt;br /&gt;
On attribue à chaque cellule un identifiant unique.&lt;br /&gt;
&lt;br /&gt;
On choisit&lt;br /&gt;
&lt;br /&gt;
=== Labyrinthes cycliques ===&lt;br /&gt;
&lt;br /&gt;
Il est possible, en retirant un certain pourcentage de murs, de créer des labyrinthes cycliques à partir des labyrinthes acycliques générés auparavant.&lt;br /&gt;
&lt;br /&gt;
Cependant, certains algorithmes de résolution n&#039;auront pas le même comportement.&lt;br /&gt;
&lt;br /&gt;
== Résolution ==&lt;br /&gt;
&lt;br /&gt;
?&lt;br /&gt;
&lt;br /&gt;
=== Exploration exhaustive ===&lt;br /&gt;
&lt;br /&gt;
=== Mur droit ===&lt;br /&gt;
&lt;br /&gt;
== Structures de données ==&lt;br /&gt;
&lt;br /&gt;
=== Union-Find ===&lt;br /&gt;
&lt;br /&gt;
Dijoint Set&lt;br /&gt;
&lt;br /&gt;
=== Pile ===&lt;br /&gt;
&lt;br /&gt;
Stack&lt;br /&gt;
&lt;br /&gt;
=== File ===&lt;br /&gt;
&lt;br /&gt;
Queue&lt;br /&gt;
&lt;br /&gt;
== Affichage ==&lt;br /&gt;
&lt;br /&gt;
tkinter &lt;br /&gt;
&lt;br /&gt;
[https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#Exploration_exhaustive tkinter]&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
N&#039;ayant pas utilisé de bibliothèques autres que tkinter, mon projet total contient plusieurs milliers de lignes réparties dans une dizaine de fichiers.&lt;br /&gt;
&lt;br /&gt;
Je ne peux donc évidemment pas l&#039;insérer directement dans cette page.&lt;br /&gt;
&lt;br /&gt;
Le code source est disponible sur Github à [https://github.com/Rominos111/Labyrinthe_VISI201 cette adresse]&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
&lt;br /&gt;
== Annexes ==&lt;/div&gt;</summary>
		<author><name>Theodet</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11670</id>
		<title>Génération et résolution de labyrinthes II</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11670"/>
		<updated>2019-05-17T09:34:55Z</updated>

		<summary type="html">&lt;p&gt;Theodet : /* Kruskal */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__FORCETOC__[[Fichier:labyrinthe_photo.png|vignette|300px|Labyrinthe généré avec Kruskal et résolu avec le parcours en profondeur. En route foncé, l&#039;entrée. En vert, la sortie. En bleu, le chemin. En rouge clair, les cellules visitées lors de la résolution.|alt=&amp;quot;Labyrinthe&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
Lorem ipsum&lt;br /&gt;
&lt;br /&gt;
== Représentation ==&lt;br /&gt;
&lt;br /&gt;
=== Propriétés ===&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe est une grille de cellules reliées, ou non, entre elles.&lt;br /&gt;
&lt;br /&gt;
Deux cellules sont reliées entre elles par une &#039;&#039;&#039;porte&#039;&#039;&#039;, ou séparées par un &#039;&#039;&#039;mur&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Tout labyrinthe a &#039;&#039;&#039;une entrée&#039;&#039;&#039; et &#039;&#039;&#039;une sortie&#039;&#039;&#039;, et quelle que soit l&#039;entrée ou la sortie, le chemin entre ces deux cellules est &#039;&#039;&#039;unique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Modélisation en graphe ===&lt;br /&gt;
&lt;br /&gt;
En théorie des graphes, un graphe est un ensemble de &#039;&#039;&#039;points&#039;&#039;&#039; (ou nœuds ou sommets) reliés ensemble par des &#039;&#039;&#039;lignes&#039;&#039;&#039; (ou liens ou arêtes).&lt;br /&gt;
&lt;br /&gt;
Un graphe peut être &#039;&#039;&#039;connexe&#039;&#039;&#039; (en un seul morceau) ou &#039;&#039;&#039;non connexe&#039;&#039;&#039; (en plusieurs morceaux).&lt;br /&gt;
&lt;br /&gt;
Un graphe peut aussi être &#039;&#039;&#039;cyclique&#039;&#039;&#039; si les points sont reliés en formant une boucle ou &#039;&#039;&#039;acyclique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Enfin, un graphe peut être &#039;&#039;&#039;orienté&#039;&#039;&#039; (si les arêtes sont à sens unique) ou &#039;&#039;&#039;non orienté&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:graphe_cyclique.png|vignette|centre|500px|Exemple de graphe connexe cyclique non orienté|alt=Graphe cyclique]]&lt;br /&gt;
&lt;br /&gt;
Un &#039;&#039;&#039;arbre&#039;&#039;&#039; est un graphe connexe, acyclique et non orienté.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Arbre.PNG|vignette|centre|500px|Exemple d&#039;arbre|alt=Arbre]]&lt;br /&gt;
&lt;br /&gt;
En plaçant un point sur chaque cellule de notre labyrinthe, et en reliant deux cellules séparées par une porte, on peut dessiner un arbre comme ceci :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:labyrinthe_avec_arbre.png|vignette|centre|500px|Exemple de labyrinthe avec son arbre. Pour plus de simplicité, on attribue à chaque nœud une position.|alt=Labyrinthe avec arbre]]&lt;br /&gt;
&lt;br /&gt;
== Génération ==&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe rectangulaire de largeur &amp;lt;math&amp;gt; L &amp;lt;/math&amp;gt; et de hauteur &amp;lt;math&amp;gt; H &amp;lt;/math&amp;gt; contient exactement &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; portes.&lt;br /&gt;
&lt;br /&gt;
Du point de vue du graphe, il y a donc &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; arêtes.&lt;br /&gt;
&lt;br /&gt;
Maintenant, comment répartir toutes ces portes de façon à ce que toutes les cellules soient accessibles et qu&#039;il n&#039;existe qu&#039;un unique chemin entre l&#039;entrée et la sortie ?&lt;br /&gt;
&lt;br /&gt;
De nombreux algorithmes existent, dont le parcours en profondeur et l&#039;algorithme de Kruskal.&lt;br /&gt;
Chaque algorithme est différent et produit des labyrinthes visuellement différents.&lt;br /&gt;
&lt;br /&gt;
=== Parcours en profondeur ===&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;algorithme du parcours en profondeur (&amp;quot;recursive backtracker&amp;quot; en anglais), on commence sur une cellule aléatoire dans le labyrinthe.&lt;br /&gt;
&lt;br /&gt;
On se dirige dans une direction aléatoire et on casse le mur en face, tout en marquant la cellule précédente comme visitée.&lt;br /&gt;
&lt;br /&gt;
Lorsque aucune direction n&#039;est disponible, on remonte à la position précédente.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:recursive_backtracker.gif|vignette|centre|500px|Illustration du parcours en profondeur|alt=Parcours en profondeur.]]&lt;br /&gt;
&lt;br /&gt;
Pour sauvegarder l&#039;historique des positions, on peut utiliser une &#039;&#039;&#039;pile&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Une pile est une liste dans laquelle seul le dernier élément peut être récupéré.&lt;br /&gt;
&lt;br /&gt;
Une pile contient 2 méthodes :&lt;br /&gt;
* push(elem) : ajoute elem à la pile&lt;br /&gt;
* pop() -&amp;gt; elem : retourne le dernier élément de la pile (elem dans notre cas)&lt;br /&gt;
&lt;br /&gt;
Dans mon implémentation de la pile, une erreur est levée si l&#039;on appelle la méthode pop sur une pile vide.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;eee&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Kruskal ===&lt;br /&gt;
&lt;br /&gt;
Alors que pour le parcours en profondeur on partait des cellules, l&#039;algorithme de Kruskal s&#039;applique sur des murs.&lt;br /&gt;
&lt;br /&gt;
On attribue à chaque cellule un identifiant unique.&lt;br /&gt;
&lt;br /&gt;
On choisit&lt;br /&gt;
&lt;br /&gt;
=== Labyrinthes cycliques ===&lt;br /&gt;
&lt;br /&gt;
Il est possible, en retirant un certain pourcentage de murs, de créer des labyrinthes cycliques à partir des labyrinthes acycliques générés auparavant.&lt;br /&gt;
&lt;br /&gt;
Cependant, certains algorithmes de résolution n&#039;auront pas le même comportement.&lt;br /&gt;
&lt;br /&gt;
== Résolution ==&lt;br /&gt;
&lt;br /&gt;
?&lt;br /&gt;
&lt;br /&gt;
=== Exploration exhaustive ===&lt;br /&gt;
&lt;br /&gt;
=== Mur droit ===&lt;br /&gt;
&lt;br /&gt;
== Structures de données ==&lt;br /&gt;
&lt;br /&gt;
=== Union-Find ===&lt;br /&gt;
&lt;br /&gt;
Dijoint Set&lt;br /&gt;
&lt;br /&gt;
=== Pile ===&lt;br /&gt;
&lt;br /&gt;
Stack&lt;br /&gt;
&lt;br /&gt;
=== File ===&lt;br /&gt;
&lt;br /&gt;
Queue&lt;br /&gt;
&lt;br /&gt;
== Affichage ==&lt;br /&gt;
&lt;br /&gt;
tkinter &lt;br /&gt;
&lt;br /&gt;
[https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#Exploration_exhaustive tkinter]&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
N&#039;ayant pas utilisé de bibliothèques autres que tkinter, mon projet total contient plusieurs milliers de lignes réparties dans une dizaine de fichiers.&lt;br /&gt;
&lt;br /&gt;
Je ne peux donc évidemment pas l&#039;insérer directement dans cette page.&lt;br /&gt;
&lt;br /&gt;
Le code source est disponible sur Github à [https://github.com/Rominos111/Labyrinthe_VISI201 cette adresse]&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
&lt;br /&gt;
== Annexes ==&lt;/div&gt;</summary>
		<author><name>Theodet</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fichier:Pile.png&amp;diff=11669</id>
		<title>Fichier:Pile.png</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fichier:Pile.png&amp;diff=11669"/>
		<updated>2019-05-17T09:34:52Z</updated>

		<summary type="html">&lt;p&gt;Theodet : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Theodet</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11668</id>
		<title>Génération et résolution de labyrinthes II</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11668"/>
		<updated>2019-05-17T09:31:18Z</updated>

		<summary type="html">&lt;p&gt;Theodet : /* Prim */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__FORCETOC__[[Fichier:labyrinthe_photo.png|vignette|300px|Labyrinthe généré avec Kruskal et résolu avec le parcours en profondeur. En route foncé, l&#039;entrée. En vert, la sortie. En bleu, le chemin. En rouge clair, les cellules visitées lors de la résolution.|alt=&amp;quot;Labyrinthe&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
Lorem ipsum&lt;br /&gt;
&lt;br /&gt;
== Représentation ==&lt;br /&gt;
&lt;br /&gt;
=== Propriétés ===&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe est une grille de cellules reliées, ou non, entre elles.&lt;br /&gt;
&lt;br /&gt;
Deux cellules sont reliées entre elles par une &#039;&#039;&#039;porte&#039;&#039;&#039;, ou séparées par un &#039;&#039;&#039;mur&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Tout labyrinthe a &#039;&#039;&#039;une entrée&#039;&#039;&#039; et &#039;&#039;&#039;une sortie&#039;&#039;&#039;, et quelle que soit l&#039;entrée ou la sortie, le chemin entre ces deux cellules est &#039;&#039;&#039;unique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Modélisation en graphe ===&lt;br /&gt;
&lt;br /&gt;
En théorie des graphes, un graphe est un ensemble de &#039;&#039;&#039;points&#039;&#039;&#039; (ou nœuds ou sommets) reliés ensemble par des &#039;&#039;&#039;lignes&#039;&#039;&#039; (ou liens ou arêtes).&lt;br /&gt;
&lt;br /&gt;
Un graphe peut être &#039;&#039;&#039;connexe&#039;&#039;&#039; (en un seul morceau) ou &#039;&#039;&#039;non connexe&#039;&#039;&#039; (en plusieurs morceaux).&lt;br /&gt;
&lt;br /&gt;
Un graphe peut aussi être &#039;&#039;&#039;cyclique&#039;&#039;&#039; si les points sont reliés en formant une boucle ou &#039;&#039;&#039;acyclique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Enfin, un graphe peut être &#039;&#039;&#039;orienté&#039;&#039;&#039; (si les arêtes sont à sens unique) ou &#039;&#039;&#039;non orienté&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:graphe_cyclique.png|vignette|centre|500px|Exemple de graphe connexe cyclique non orienté|alt=Graphe cyclique]]&lt;br /&gt;
&lt;br /&gt;
Un &#039;&#039;&#039;arbre&#039;&#039;&#039; est un graphe connexe, acyclique et non orienté.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Arbre.PNG|vignette|centre|500px|Exemple d&#039;arbre|alt=Arbre]]&lt;br /&gt;
&lt;br /&gt;
En plaçant un point sur chaque cellule de notre labyrinthe, et en reliant deux cellules séparées par une porte, on peut dessiner un arbre comme ceci :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:labyrinthe_avec_arbre.png|vignette|centre|500px|Exemple de labyrinthe avec son arbre. Pour plus de simplicité, on attribue à chaque nœud une position.|alt=Labyrinthe avec arbre]]&lt;br /&gt;
&lt;br /&gt;
== Génération ==&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe rectangulaire de largeur &amp;lt;math&amp;gt; L &amp;lt;/math&amp;gt; et de hauteur &amp;lt;math&amp;gt; H &amp;lt;/math&amp;gt; contient exactement &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; portes.&lt;br /&gt;
&lt;br /&gt;
Du point de vue du graphe, il y a donc &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; arêtes.&lt;br /&gt;
&lt;br /&gt;
Maintenant, comment répartir toutes ces portes de façon à ce que toutes les cellules soient accessibles et qu&#039;il n&#039;existe qu&#039;un unique chemin entre l&#039;entrée et la sortie ?&lt;br /&gt;
&lt;br /&gt;
De nombreux algorithmes existent, dont le parcours en profondeur et l&#039;algorithme de Kruskal.&lt;br /&gt;
Chaque algorithme est différent et produit des labyrinthes visuellement différents.&lt;br /&gt;
&lt;br /&gt;
=== Parcours en profondeur ===&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;algorithme du parcours en profondeur (&amp;quot;recursive backtracker&amp;quot; en anglais), on commence sur une cellule aléatoire dans le labyrinthe.&lt;br /&gt;
&lt;br /&gt;
On se dirige dans une direction aléatoire et on casse le mur en face, tout en marquant la cellule précédente comme visitée.&lt;br /&gt;
&lt;br /&gt;
Lorsque aucune direction n&#039;est disponible, on remonte à la position précédente.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:recursive_backtracker.gif|vignette|centre|500px|Illustration du parcours en profondeur|alt=Parcours en profondeur.]]&lt;br /&gt;
&lt;br /&gt;
Pour sauvegarder l&#039;historique des positions, on peut utiliser une &#039;&#039;&#039;pile&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Une pile est une liste dans laquelle seul le dernier élément peut être récupéré.&lt;br /&gt;
&lt;br /&gt;
Une pile contient 2 méthodes :&lt;br /&gt;
* push(elem) : ajoute elem à la pile&lt;br /&gt;
* pop() -&amp;gt; elem : retourne le dernier élément de la pile (elem dans notre cas)&lt;br /&gt;
&lt;br /&gt;
Dans mon implémentation de la pile, une erreur est levée si l&#039;on appelle la méthode pop sur une pile vide.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;eee&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Kruskal ===&lt;br /&gt;
&lt;br /&gt;
Kruskal&lt;br /&gt;
&lt;br /&gt;
=== Labyrinthes cycliques ===&lt;br /&gt;
&lt;br /&gt;
Il est possible, en retirant un certain pourcentage de murs, de créer des labyrinthes cycliques à partir des labyrinthes acycliques générés auparavant.&lt;br /&gt;
&lt;br /&gt;
Cependant, certains algorithmes de résolution n&#039;auront pas le même comportement.&lt;br /&gt;
&lt;br /&gt;
== Résolution ==&lt;br /&gt;
&lt;br /&gt;
?&lt;br /&gt;
&lt;br /&gt;
=== Exploration exhaustive ===&lt;br /&gt;
&lt;br /&gt;
=== Mur droit ===&lt;br /&gt;
&lt;br /&gt;
== Structures de données ==&lt;br /&gt;
&lt;br /&gt;
=== Union-Find ===&lt;br /&gt;
&lt;br /&gt;
Dijoint Set&lt;br /&gt;
&lt;br /&gt;
=== Pile ===&lt;br /&gt;
&lt;br /&gt;
Stack&lt;br /&gt;
&lt;br /&gt;
=== File ===&lt;br /&gt;
&lt;br /&gt;
Queue&lt;br /&gt;
&lt;br /&gt;
== Affichage ==&lt;br /&gt;
&lt;br /&gt;
tkinter &lt;br /&gt;
&lt;br /&gt;
[https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#Exploration_exhaustive tkinter]&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
N&#039;ayant pas utilisé de bibliothèques autres que tkinter, mon projet total contient plusieurs milliers de lignes réparties dans une dizaine de fichiers.&lt;br /&gt;
&lt;br /&gt;
Je ne peux donc évidemment pas l&#039;insérer directement dans cette page.&lt;br /&gt;
&lt;br /&gt;
Le code source est disponible sur Github à [https://github.com/Rominos111/Labyrinthe_VISI201 cette adresse]&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
&lt;br /&gt;
== Annexes ==&lt;/div&gt;</summary>
		<author><name>Theodet</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11667</id>
		<title>Génération et résolution de labyrinthes II</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11667"/>
		<updated>2019-05-17T09:29:36Z</updated>

		<summary type="html">&lt;p&gt;Theodet : /* Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__FORCETOC__[[Fichier:labyrinthe_photo.png|vignette|300px|Labyrinthe généré avec Kruskal et résolu avec le parcours en profondeur. En route foncé, l&#039;entrée. En vert, la sortie. En bleu, le chemin. En rouge clair, les cellules visitées lors de la résolution.|alt=&amp;quot;Labyrinthe&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
Lorem ipsum&lt;br /&gt;
&lt;br /&gt;
== Représentation ==&lt;br /&gt;
&lt;br /&gt;
=== Propriétés ===&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe est une grille de cellules reliées, ou non, entre elles.&lt;br /&gt;
&lt;br /&gt;
Deux cellules sont reliées entre elles par une &#039;&#039;&#039;porte&#039;&#039;&#039;, ou séparées par un &#039;&#039;&#039;mur&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Tout labyrinthe a &#039;&#039;&#039;une entrée&#039;&#039;&#039; et &#039;&#039;&#039;une sortie&#039;&#039;&#039;, et quelle que soit l&#039;entrée ou la sortie, le chemin entre ces deux cellules est &#039;&#039;&#039;unique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Modélisation en graphe ===&lt;br /&gt;
&lt;br /&gt;
En théorie des graphes, un graphe est un ensemble de &#039;&#039;&#039;points&#039;&#039;&#039; (ou nœuds ou sommets) reliés ensemble par des &#039;&#039;&#039;lignes&#039;&#039;&#039; (ou liens ou arêtes).&lt;br /&gt;
&lt;br /&gt;
Un graphe peut être &#039;&#039;&#039;connexe&#039;&#039;&#039; (en un seul morceau) ou &#039;&#039;&#039;non connexe&#039;&#039;&#039; (en plusieurs morceaux).&lt;br /&gt;
&lt;br /&gt;
Un graphe peut aussi être &#039;&#039;&#039;cyclique&#039;&#039;&#039; si les points sont reliés en formant une boucle ou &#039;&#039;&#039;acyclique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Enfin, un graphe peut être &#039;&#039;&#039;orienté&#039;&#039;&#039; (si les arêtes sont à sens unique) ou &#039;&#039;&#039;non orienté&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:graphe_cyclique.png|vignette|centre|500px|Exemple de graphe connexe cyclique non orienté|alt=Graphe cyclique]]&lt;br /&gt;
&lt;br /&gt;
Un &#039;&#039;&#039;arbre&#039;&#039;&#039; est un graphe connexe, acyclique et non orienté.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Arbre.PNG|vignette|centre|500px|Exemple d&#039;arbre|alt=Arbre]]&lt;br /&gt;
&lt;br /&gt;
En plaçant un point sur chaque cellule de notre labyrinthe, et en reliant deux cellules séparées par une porte, on peut dessiner un arbre comme ceci :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:labyrinthe_avec_arbre.png|vignette|centre|500px|Exemple de labyrinthe avec son arbre. Pour plus de simplicité, on attribue à chaque nœud une position.|alt=Labyrinthe avec arbre]]&lt;br /&gt;
&lt;br /&gt;
== Génération ==&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe rectangulaire de largeur &amp;lt;math&amp;gt; L &amp;lt;/math&amp;gt; et de hauteur &amp;lt;math&amp;gt; H &amp;lt;/math&amp;gt; contient exactement &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; portes.&lt;br /&gt;
&lt;br /&gt;
Du point de vue du graphe, il y a donc &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; arêtes.&lt;br /&gt;
&lt;br /&gt;
Maintenant, comment répartir toutes ces portes de façon à ce que toutes les cellules soient accessibles et qu&#039;il n&#039;existe qu&#039;un unique chemin entre l&#039;entrée et la sortie ?&lt;br /&gt;
&lt;br /&gt;
De nombreux algorithmes existent, dont le parcours en profondeur et l&#039;algorithme de Kruskal.&lt;br /&gt;
Chaque algorithme est différent et produit des labyrinthes visuellement différents.&lt;br /&gt;
&lt;br /&gt;
=== Parcours en profondeur ===&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;algorithme du parcours en profondeur (&amp;quot;recursive backtracker&amp;quot; en anglais), on commence sur une cellule aléatoire dans le labyrinthe.&lt;br /&gt;
&lt;br /&gt;
On se dirige dans une direction aléatoire et on casse le mur en face, tout en marquant la cellule précédente comme visitée.&lt;br /&gt;
&lt;br /&gt;
Lorsque aucune direction n&#039;est disponible, on remonte à la position précédente.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:recursive_backtracker.gif|vignette|centre|500px|Illustration du parcours en profondeur|alt=Parcours en profondeur.]]&lt;br /&gt;
&lt;br /&gt;
Pour sauvegarder l&#039;historique des positions, on peut utiliser une &#039;&#039;&#039;pile&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Une pile est une liste dans laquelle seul le dernier élément peut être récupéré.&lt;br /&gt;
&lt;br /&gt;
Une pile contient 2 méthodes :&lt;br /&gt;
* push(elem) : ajoute elem à la pile&lt;br /&gt;
* pop() -&amp;gt; elem : retourne le dernier élément de la pile (elem dans notre cas)&lt;br /&gt;
&lt;br /&gt;
Dans mon implémentation de la pile, une erreur est levée si l&#039;on appelle la méthode pop sur une pile vide.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;eee&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Kruskal ===&lt;br /&gt;
&lt;br /&gt;
Kruskal&lt;br /&gt;
&lt;br /&gt;
=== Prim ===&lt;br /&gt;
&lt;br /&gt;
== Résolution ==&lt;br /&gt;
&lt;br /&gt;
?&lt;br /&gt;
&lt;br /&gt;
=== Exploration exhaustive ===&lt;br /&gt;
&lt;br /&gt;
=== Mur droit ===&lt;br /&gt;
&lt;br /&gt;
== Structures de données ==&lt;br /&gt;
&lt;br /&gt;
=== Union-Find ===&lt;br /&gt;
&lt;br /&gt;
Dijoint Set&lt;br /&gt;
&lt;br /&gt;
=== Pile ===&lt;br /&gt;
&lt;br /&gt;
Stack&lt;br /&gt;
&lt;br /&gt;
=== File ===&lt;br /&gt;
&lt;br /&gt;
Queue&lt;br /&gt;
&lt;br /&gt;
== Affichage ==&lt;br /&gt;
&lt;br /&gt;
tkinter &lt;br /&gt;
&lt;br /&gt;
[https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#Exploration_exhaustive tkinter]&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
N&#039;ayant pas utilisé de bibliothèques autres que tkinter, mon projet total contient plusieurs milliers de lignes réparties dans une dizaine de fichiers.&lt;br /&gt;
&lt;br /&gt;
Je ne peux donc évidemment pas l&#039;insérer directement dans cette page.&lt;br /&gt;
&lt;br /&gt;
Le code source est disponible sur Github à [https://github.com/Rominos111/Labyrinthe_VISI201 cette adresse]&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
&lt;br /&gt;
== Annexes ==&lt;/div&gt;</summary>
		<author><name>Theodet</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11666</id>
		<title>Génération et résolution de labyrinthes II</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11666"/>
		<updated>2019-05-17T09:29:28Z</updated>

		<summary type="html">&lt;p&gt;Theodet : /* Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__FORCETOC__[[Fichier:labyrinthe_photo.png|vignette|300px|Labyrinthe généré avec Kruskal et résolu avec le parcours en profondeur. En route foncé, l&#039;entrée. En vert, la sortie. En bleu, le chemin. En rouge clair, les cellules visitées lors de la résolution.|alt=&amp;quot;Labyrinthe&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
Lorem ipsum&lt;br /&gt;
&lt;br /&gt;
== Représentation ==&lt;br /&gt;
&lt;br /&gt;
=== Propriétés ===&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe est une grille de cellules reliées, ou non, entre elles.&lt;br /&gt;
&lt;br /&gt;
Deux cellules sont reliées entre elles par une &#039;&#039;&#039;porte&#039;&#039;&#039;, ou séparées par un &#039;&#039;&#039;mur&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Tout labyrinthe a &#039;&#039;&#039;une entrée&#039;&#039;&#039; et &#039;&#039;&#039;une sortie&#039;&#039;&#039;, et quelle que soit l&#039;entrée ou la sortie, le chemin entre ces deux cellules est &#039;&#039;&#039;unique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Modélisation en graphe ===&lt;br /&gt;
&lt;br /&gt;
En théorie des graphes, un graphe est un ensemble de &#039;&#039;&#039;points&#039;&#039;&#039; (ou nœuds ou sommets) reliés ensemble par des &#039;&#039;&#039;lignes&#039;&#039;&#039; (ou liens ou arêtes).&lt;br /&gt;
&lt;br /&gt;
Un graphe peut être &#039;&#039;&#039;connexe&#039;&#039;&#039; (en un seul morceau) ou &#039;&#039;&#039;non connexe&#039;&#039;&#039; (en plusieurs morceaux).&lt;br /&gt;
&lt;br /&gt;
Un graphe peut aussi être &#039;&#039;&#039;cyclique&#039;&#039;&#039; si les points sont reliés en formant une boucle ou &#039;&#039;&#039;acyclique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Enfin, un graphe peut être &#039;&#039;&#039;orienté&#039;&#039;&#039; (si les arêtes sont à sens unique) ou &#039;&#039;&#039;non orienté&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:graphe_cyclique.png|vignette|centre|500px|Exemple de graphe connexe cyclique non orienté|alt=Graphe cyclique]]&lt;br /&gt;
&lt;br /&gt;
Un &#039;&#039;&#039;arbre&#039;&#039;&#039; est un graphe connexe, acyclique et non orienté.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Arbre.PNG|vignette|centre|500px|Exemple d&#039;arbre|alt=Arbre]]&lt;br /&gt;
&lt;br /&gt;
En plaçant un point sur chaque cellule de notre labyrinthe, et en reliant deux cellules séparées par une porte, on peut dessiner un arbre comme ceci :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:labyrinthe_avec_arbre.png|vignette|centre|500px|Exemple de labyrinthe avec son arbre. Pour plus de simplicité, on attribue à chaque nœud une position.|alt=Labyrinthe avec arbre]]&lt;br /&gt;
&lt;br /&gt;
== Génération ==&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe rectangulaire de largeur &amp;lt;math&amp;gt; L &amp;lt;/math&amp;gt; et de hauteur &amp;lt;math&amp;gt; H &amp;lt;/math&amp;gt; contient exactement &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; portes.&lt;br /&gt;
&lt;br /&gt;
Du point de vue du graphe, il y a donc &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; arêtes.&lt;br /&gt;
&lt;br /&gt;
Maintenant, comment répartir toutes ces portes de façon à ce que toutes les cellules soient accessibles et qu&#039;il n&#039;existe qu&#039;un unique chemin entre l&#039;entrée et la sortie ?&lt;br /&gt;
&lt;br /&gt;
De nombreux algorithmes existent, dont le parcours en profondeur et l&#039;algorithme de Kruskal.&lt;br /&gt;
Chaque algorithme est différent et produit des labyrinthes visuellement différents.&lt;br /&gt;
&lt;br /&gt;
=== Parcours en profondeur ===&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;algorithme du parcours en profondeur (&amp;quot;recursive backtracker&amp;quot; en anglais), on commence sur une cellule aléatoire dans le labyrinthe.&lt;br /&gt;
&lt;br /&gt;
On se dirige dans une direction aléatoire et on casse le mur en face, tout en marquant la cellule précédente comme visitée.&lt;br /&gt;
&lt;br /&gt;
Lorsque aucune direction n&#039;est disponible, on remonte à la position précédente.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:recursive_backtracker.gif|vignette|centre|500px|Illustration du parcours en profondeur|alt=Parcours en profondeur.]]&lt;br /&gt;
&lt;br /&gt;
Pour sauvegarder l&#039;historique des positions, on peut utiliser une &#039;&#039;&#039;pile&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Une pile est une liste dans laquelle seul le dernier élément peut être récupéré.&lt;br /&gt;
&lt;br /&gt;
Une pile contient 2 méthodes :&lt;br /&gt;
* push(elem) : ajoute elem à la pile&lt;br /&gt;
* pop() -&amp;gt; elem : retourne le dernier élément de la pile (elem dans notre cas)&lt;br /&gt;
&lt;br /&gt;
Dans mon implémentation de la pile, une erreur est levée si l&#039;on appelle la méthode pop sur une pile vide.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;eee&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Kruskal ===&lt;br /&gt;
&lt;br /&gt;
Kruskal&lt;br /&gt;
&lt;br /&gt;
=== Prim ===&lt;br /&gt;
&lt;br /&gt;
== Résolution ==&lt;br /&gt;
&lt;br /&gt;
?&lt;br /&gt;
&lt;br /&gt;
=== Exploration exhaustive ===&lt;br /&gt;
&lt;br /&gt;
=== Mur droit ===&lt;br /&gt;
&lt;br /&gt;
== Structures de données ==&lt;br /&gt;
&lt;br /&gt;
=== Union-Find ===&lt;br /&gt;
&lt;br /&gt;
Dijoint Set&lt;br /&gt;
&lt;br /&gt;
=== Pile ===&lt;br /&gt;
&lt;br /&gt;
Stack&lt;br /&gt;
&lt;br /&gt;
=== File ===&lt;br /&gt;
&lt;br /&gt;
Queue&lt;br /&gt;
&lt;br /&gt;
== Affichage ==&lt;br /&gt;
&lt;br /&gt;
tkinter &lt;br /&gt;
&lt;br /&gt;
[https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#Exploration_exhaustive tkinter]&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
N&#039;ayant pas utilisé de bibliothèques autres que tkinter, mon projet total contient plusieurs milliers de lignes réparties dans une dizaine de fichiers.&lt;br /&gt;
&lt;br /&gt;
Je ne peux donc évidemment pas l&#039;insérer directement dans cette page.&lt;br /&gt;
&lt;br /&gt;
Le code source est disponible sur Github à [https://github.com/Rominos111/Labyrinthe_VISI201 cette adresse.]&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
&lt;br /&gt;
== Annexes ==&lt;/div&gt;</summary>
		<author><name>Theodet</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11665</id>
		<title>Génération et résolution de labyrinthes II</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11665"/>
		<updated>2019-05-17T09:29:16Z</updated>

		<summary type="html">&lt;p&gt;Theodet : /* Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__FORCETOC__[[Fichier:labyrinthe_photo.png|vignette|300px|Labyrinthe généré avec Kruskal et résolu avec le parcours en profondeur. En route foncé, l&#039;entrée. En vert, la sortie. En bleu, le chemin. En rouge clair, les cellules visitées lors de la résolution.|alt=&amp;quot;Labyrinthe&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
Lorem ipsum&lt;br /&gt;
&lt;br /&gt;
== Représentation ==&lt;br /&gt;
&lt;br /&gt;
=== Propriétés ===&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe est une grille de cellules reliées, ou non, entre elles.&lt;br /&gt;
&lt;br /&gt;
Deux cellules sont reliées entre elles par une &#039;&#039;&#039;porte&#039;&#039;&#039;, ou séparées par un &#039;&#039;&#039;mur&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Tout labyrinthe a &#039;&#039;&#039;une entrée&#039;&#039;&#039; et &#039;&#039;&#039;une sortie&#039;&#039;&#039;, et quelle que soit l&#039;entrée ou la sortie, le chemin entre ces deux cellules est &#039;&#039;&#039;unique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Modélisation en graphe ===&lt;br /&gt;
&lt;br /&gt;
En théorie des graphes, un graphe est un ensemble de &#039;&#039;&#039;points&#039;&#039;&#039; (ou nœuds ou sommets) reliés ensemble par des &#039;&#039;&#039;lignes&#039;&#039;&#039; (ou liens ou arêtes).&lt;br /&gt;
&lt;br /&gt;
Un graphe peut être &#039;&#039;&#039;connexe&#039;&#039;&#039; (en un seul morceau) ou &#039;&#039;&#039;non connexe&#039;&#039;&#039; (en plusieurs morceaux).&lt;br /&gt;
&lt;br /&gt;
Un graphe peut aussi être &#039;&#039;&#039;cyclique&#039;&#039;&#039; si les points sont reliés en formant une boucle ou &#039;&#039;&#039;acyclique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Enfin, un graphe peut être &#039;&#039;&#039;orienté&#039;&#039;&#039; (si les arêtes sont à sens unique) ou &#039;&#039;&#039;non orienté&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:graphe_cyclique.png|vignette|centre|500px|Exemple de graphe connexe cyclique non orienté|alt=Graphe cyclique]]&lt;br /&gt;
&lt;br /&gt;
Un &#039;&#039;&#039;arbre&#039;&#039;&#039; est un graphe connexe, acyclique et non orienté.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Arbre.PNG|vignette|centre|500px|Exemple d&#039;arbre|alt=Arbre]]&lt;br /&gt;
&lt;br /&gt;
En plaçant un point sur chaque cellule de notre labyrinthe, et en reliant deux cellules séparées par une porte, on peut dessiner un arbre comme ceci :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:labyrinthe_avec_arbre.png|vignette|centre|500px|Exemple de labyrinthe avec son arbre. Pour plus de simplicité, on attribue à chaque nœud une position.|alt=Labyrinthe avec arbre]]&lt;br /&gt;
&lt;br /&gt;
== Génération ==&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe rectangulaire de largeur &amp;lt;math&amp;gt; L &amp;lt;/math&amp;gt; et de hauteur &amp;lt;math&amp;gt; H &amp;lt;/math&amp;gt; contient exactement &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; portes.&lt;br /&gt;
&lt;br /&gt;
Du point de vue du graphe, il y a donc &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; arêtes.&lt;br /&gt;
&lt;br /&gt;
Maintenant, comment répartir toutes ces portes de façon à ce que toutes les cellules soient accessibles et qu&#039;il n&#039;existe qu&#039;un unique chemin entre l&#039;entrée et la sortie ?&lt;br /&gt;
&lt;br /&gt;
De nombreux algorithmes existent, dont le parcours en profondeur et l&#039;algorithme de Kruskal.&lt;br /&gt;
Chaque algorithme est différent et produit des labyrinthes visuellement différents.&lt;br /&gt;
&lt;br /&gt;
=== Parcours en profondeur ===&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;algorithme du parcours en profondeur (&amp;quot;recursive backtracker&amp;quot; en anglais), on commence sur une cellule aléatoire dans le labyrinthe.&lt;br /&gt;
&lt;br /&gt;
On se dirige dans une direction aléatoire et on casse le mur en face, tout en marquant la cellule précédente comme visitée.&lt;br /&gt;
&lt;br /&gt;
Lorsque aucune direction n&#039;est disponible, on remonte à la position précédente.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:recursive_backtracker.gif|vignette|centre|500px|Illustration du parcours en profondeur|alt=Parcours en profondeur.]]&lt;br /&gt;
&lt;br /&gt;
Pour sauvegarder l&#039;historique des positions, on peut utiliser une &#039;&#039;&#039;pile&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Une pile est une liste dans laquelle seul le dernier élément peut être récupéré.&lt;br /&gt;
&lt;br /&gt;
Une pile contient 2 méthodes :&lt;br /&gt;
* push(elem) : ajoute elem à la pile&lt;br /&gt;
* pop() -&amp;gt; elem : retourne le dernier élément de la pile (elem dans notre cas)&lt;br /&gt;
&lt;br /&gt;
Dans mon implémentation de la pile, une erreur est levée si l&#039;on appelle la méthode pop sur une pile vide.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;eee&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Kruskal ===&lt;br /&gt;
&lt;br /&gt;
Kruskal&lt;br /&gt;
&lt;br /&gt;
=== Prim ===&lt;br /&gt;
&lt;br /&gt;
== Résolution ==&lt;br /&gt;
&lt;br /&gt;
?&lt;br /&gt;
&lt;br /&gt;
=== Exploration exhaustive ===&lt;br /&gt;
&lt;br /&gt;
=== Mur droit ===&lt;br /&gt;
&lt;br /&gt;
== Structures de données ==&lt;br /&gt;
&lt;br /&gt;
=== Union-Find ===&lt;br /&gt;
&lt;br /&gt;
Dijoint Set&lt;br /&gt;
&lt;br /&gt;
=== Pile ===&lt;br /&gt;
&lt;br /&gt;
Stack&lt;br /&gt;
&lt;br /&gt;
=== File ===&lt;br /&gt;
&lt;br /&gt;
Queue&lt;br /&gt;
&lt;br /&gt;
== Affichage ==&lt;br /&gt;
&lt;br /&gt;
tkinter &lt;br /&gt;
&lt;br /&gt;
[https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#Exploration_exhaustive tkinter]&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
N&#039;ayant pas utilisé de bibliothèques autres que tkinter, mon projet total contient plusieurs milliers de lignes réparties dans une dizaine de fichiers.&lt;br /&gt;
&lt;br /&gt;
Je ne peux donc évidemment pas l&#039;insérer directement dans cette page.&lt;br /&gt;
&lt;br /&gt;
Le code source est disponible sur Github à [https://github.com/Rominos111/Labyrinthe_VISI201 cette adresse].&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
&lt;br /&gt;
== Annexes ==&lt;/div&gt;</summary>
		<author><name>Theodet</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11664</id>
		<title>Génération et résolution de labyrinthes II</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11664"/>
		<updated>2019-05-17T09:28:04Z</updated>

		<summary type="html">&lt;p&gt;Theodet : /* Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__FORCETOC__[[Fichier:labyrinthe_photo.png|vignette|300px|Labyrinthe généré avec Kruskal et résolu avec le parcours en profondeur. En route foncé, l&#039;entrée. En vert, la sortie. En bleu, le chemin. En rouge clair, les cellules visitées lors de la résolution.|alt=&amp;quot;Labyrinthe&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
Lorem ipsum&lt;br /&gt;
&lt;br /&gt;
== Représentation ==&lt;br /&gt;
&lt;br /&gt;
=== Propriétés ===&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe est une grille de cellules reliées, ou non, entre elles.&lt;br /&gt;
&lt;br /&gt;
Deux cellules sont reliées entre elles par une &#039;&#039;&#039;porte&#039;&#039;&#039;, ou séparées par un &#039;&#039;&#039;mur&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Tout labyrinthe a &#039;&#039;&#039;une entrée&#039;&#039;&#039; et &#039;&#039;&#039;une sortie&#039;&#039;&#039;, et quelle que soit l&#039;entrée ou la sortie, le chemin entre ces deux cellules est &#039;&#039;&#039;unique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Modélisation en graphe ===&lt;br /&gt;
&lt;br /&gt;
En théorie des graphes, un graphe est un ensemble de &#039;&#039;&#039;points&#039;&#039;&#039; (ou nœuds ou sommets) reliés ensemble par des &#039;&#039;&#039;lignes&#039;&#039;&#039; (ou liens ou arêtes).&lt;br /&gt;
&lt;br /&gt;
Un graphe peut être &#039;&#039;&#039;connexe&#039;&#039;&#039; (en un seul morceau) ou &#039;&#039;&#039;non connexe&#039;&#039;&#039; (en plusieurs morceaux).&lt;br /&gt;
&lt;br /&gt;
Un graphe peut aussi être &#039;&#039;&#039;cyclique&#039;&#039;&#039; si les points sont reliés en formant une boucle ou &#039;&#039;&#039;acyclique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Enfin, un graphe peut être &#039;&#039;&#039;orienté&#039;&#039;&#039; (si les arêtes sont à sens unique) ou &#039;&#039;&#039;non orienté&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:graphe_cyclique.png|vignette|centre|500px|Exemple de graphe connexe cyclique non orienté|alt=Graphe cyclique]]&lt;br /&gt;
&lt;br /&gt;
Un &#039;&#039;&#039;arbre&#039;&#039;&#039; est un graphe connexe, acyclique et non orienté.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Arbre.PNG|vignette|centre|500px|Exemple d&#039;arbre|alt=Arbre]]&lt;br /&gt;
&lt;br /&gt;
En plaçant un point sur chaque cellule de notre labyrinthe, et en reliant deux cellules séparées par une porte, on peut dessiner un arbre comme ceci :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:labyrinthe_avec_arbre.png|vignette|centre|500px|Exemple de labyrinthe avec son arbre. Pour plus de simplicité, on attribue à chaque nœud une position.|alt=Labyrinthe avec arbre]]&lt;br /&gt;
&lt;br /&gt;
== Génération ==&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe rectangulaire de largeur &amp;lt;math&amp;gt; L &amp;lt;/math&amp;gt; et de hauteur &amp;lt;math&amp;gt; H &amp;lt;/math&amp;gt; contient exactement &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; portes.&lt;br /&gt;
&lt;br /&gt;
Du point de vue du graphe, il y a donc &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; arêtes.&lt;br /&gt;
&lt;br /&gt;
Maintenant, comment répartir toutes ces portes de façon à ce que toutes les cellules soient accessibles et qu&#039;il n&#039;existe qu&#039;un unique chemin entre l&#039;entrée et la sortie ?&lt;br /&gt;
&lt;br /&gt;
De nombreux algorithmes existent, dont le parcours en profondeur et l&#039;algorithme de Kruskal.&lt;br /&gt;
Chaque algorithme est différent et produit des labyrinthes visuellement différents.&lt;br /&gt;
&lt;br /&gt;
=== Parcours en profondeur ===&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;algorithme du parcours en profondeur (&amp;quot;recursive backtracker&amp;quot; en anglais), on commence sur une cellule aléatoire dans le labyrinthe.&lt;br /&gt;
&lt;br /&gt;
On se dirige dans une direction aléatoire et on casse le mur en face, tout en marquant la cellule précédente comme visitée.&lt;br /&gt;
&lt;br /&gt;
Lorsque aucune direction n&#039;est disponible, on remonte à la position précédente.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:recursive_backtracker.gif|vignette|centre|500px|Illustration du parcours en profondeur|alt=Parcours en profondeur.]]&lt;br /&gt;
&lt;br /&gt;
Pour sauvegarder l&#039;historique des positions, on peut utiliser une &#039;&#039;&#039;pile&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Une pile est une liste dans laquelle seul le dernier élément peut être récupéré.&lt;br /&gt;
&lt;br /&gt;
Une pile contient 2 méthodes :&lt;br /&gt;
* push(elem) : ajoute elem à la pile&lt;br /&gt;
* pop() -&amp;gt; elem : retourne le dernier élément de la pile (elem dans notre cas)&lt;br /&gt;
&lt;br /&gt;
Dans mon implémentation de la pile, une erreur est levée si l&#039;on appelle la méthode pop sur une pile vide.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;eee&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Kruskal ===&lt;br /&gt;
&lt;br /&gt;
Kruskal&lt;br /&gt;
&lt;br /&gt;
=== Prim ===&lt;br /&gt;
&lt;br /&gt;
== Résolution ==&lt;br /&gt;
&lt;br /&gt;
?&lt;br /&gt;
&lt;br /&gt;
=== Exploration exhaustive ===&lt;br /&gt;
&lt;br /&gt;
=== Mur droit ===&lt;br /&gt;
&lt;br /&gt;
== Structures de données ==&lt;br /&gt;
&lt;br /&gt;
=== Union-Find ===&lt;br /&gt;
&lt;br /&gt;
Dijoint Set&lt;br /&gt;
&lt;br /&gt;
=== Pile ===&lt;br /&gt;
&lt;br /&gt;
Stack&lt;br /&gt;
&lt;br /&gt;
=== File ===&lt;br /&gt;
&lt;br /&gt;
Queue&lt;br /&gt;
&lt;br /&gt;
== Affichage ==&lt;br /&gt;
&lt;br /&gt;
tkinter &lt;br /&gt;
&lt;br /&gt;
[https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#Exploration_exhaustive tkinter]&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
N&#039;ayant pas utilisé de bibliothèques autres que tkinter, mon projet total contient plusieurs milliers de lignes réparties dans une dizaine de fichiers.&lt;br /&gt;
&lt;br /&gt;
Je ne peux donc évidemment pas l&#039;insérer directement dans cette page.&lt;br /&gt;
&lt;br /&gt;
Le code source est disponible à cette adresse. https://github.com/Rominos111/Labyrinthe_VISI201&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
&lt;br /&gt;
== Annexes ==&lt;/div&gt;</summary>
		<author><name>Theodet</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11663</id>
		<title>Génération et résolution de labyrinthes II</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11663"/>
		<updated>2019-05-17T09:25:30Z</updated>

		<summary type="html">&lt;p&gt;Theodet : /* Parcours en profondeur */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__FORCETOC__[[Fichier:labyrinthe_photo.png|vignette|300px|Labyrinthe généré avec Kruskal et résolu avec le parcours en profondeur. En route foncé, l&#039;entrée. En vert, la sortie. En bleu, le chemin. En rouge clair, les cellules visitées lors de la résolution.|alt=&amp;quot;Labyrinthe&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
Lorem ipsum&lt;br /&gt;
&lt;br /&gt;
== Représentation ==&lt;br /&gt;
&lt;br /&gt;
=== Propriétés ===&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe est une grille de cellules reliées, ou non, entre elles.&lt;br /&gt;
&lt;br /&gt;
Deux cellules sont reliées entre elles par une &#039;&#039;&#039;porte&#039;&#039;&#039;, ou séparées par un &#039;&#039;&#039;mur&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Tout labyrinthe a &#039;&#039;&#039;une entrée&#039;&#039;&#039; et &#039;&#039;&#039;une sortie&#039;&#039;&#039;, et quelle que soit l&#039;entrée ou la sortie, le chemin entre ces deux cellules est &#039;&#039;&#039;unique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Modélisation en graphe ===&lt;br /&gt;
&lt;br /&gt;
En théorie des graphes, un graphe est un ensemble de &#039;&#039;&#039;points&#039;&#039;&#039; (ou nœuds ou sommets) reliés ensemble par des &#039;&#039;&#039;lignes&#039;&#039;&#039; (ou liens ou arêtes).&lt;br /&gt;
&lt;br /&gt;
Un graphe peut être &#039;&#039;&#039;connexe&#039;&#039;&#039; (en un seul morceau) ou &#039;&#039;&#039;non connexe&#039;&#039;&#039; (en plusieurs morceaux).&lt;br /&gt;
&lt;br /&gt;
Un graphe peut aussi être &#039;&#039;&#039;cyclique&#039;&#039;&#039; si les points sont reliés en formant une boucle ou &#039;&#039;&#039;acyclique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Enfin, un graphe peut être &#039;&#039;&#039;orienté&#039;&#039;&#039; (si les arêtes sont à sens unique) ou &#039;&#039;&#039;non orienté&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:graphe_cyclique.png|vignette|centre|500px|Exemple de graphe connexe cyclique non orienté|alt=Graphe cyclique]]&lt;br /&gt;
&lt;br /&gt;
Un &#039;&#039;&#039;arbre&#039;&#039;&#039; est un graphe connexe, acyclique et non orienté.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Arbre.PNG|vignette|centre|500px|Exemple d&#039;arbre|alt=Arbre]]&lt;br /&gt;
&lt;br /&gt;
En plaçant un point sur chaque cellule de notre labyrinthe, et en reliant deux cellules séparées par une porte, on peut dessiner un arbre comme ceci :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:labyrinthe_avec_arbre.png|vignette|centre|500px|Exemple de labyrinthe avec son arbre. Pour plus de simplicité, on attribue à chaque nœud une position.|alt=Labyrinthe avec arbre]]&lt;br /&gt;
&lt;br /&gt;
== Génération ==&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe rectangulaire de largeur &amp;lt;math&amp;gt; L &amp;lt;/math&amp;gt; et de hauteur &amp;lt;math&amp;gt; H &amp;lt;/math&amp;gt; contient exactement &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; portes.&lt;br /&gt;
&lt;br /&gt;
Du point de vue du graphe, il y a donc &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; arêtes.&lt;br /&gt;
&lt;br /&gt;
Maintenant, comment répartir toutes ces portes de façon à ce que toutes les cellules soient accessibles et qu&#039;il n&#039;existe qu&#039;un unique chemin entre l&#039;entrée et la sortie ?&lt;br /&gt;
&lt;br /&gt;
De nombreux algorithmes existent, dont le parcours en profondeur et l&#039;algorithme de Kruskal.&lt;br /&gt;
Chaque algorithme est différent et produit des labyrinthes visuellement différents.&lt;br /&gt;
&lt;br /&gt;
=== Parcours en profondeur ===&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;algorithme du parcours en profondeur (&amp;quot;recursive backtracker&amp;quot; en anglais), on commence sur une cellule aléatoire dans le labyrinthe.&lt;br /&gt;
&lt;br /&gt;
On se dirige dans une direction aléatoire et on casse le mur en face, tout en marquant la cellule précédente comme visitée.&lt;br /&gt;
&lt;br /&gt;
Lorsque aucune direction n&#039;est disponible, on remonte à la position précédente.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:recursive_backtracker.gif|vignette|centre|500px|Illustration du parcours en profondeur|alt=Parcours en profondeur.]]&lt;br /&gt;
&lt;br /&gt;
Pour sauvegarder l&#039;historique des positions, on peut utiliser une &#039;&#039;&#039;pile&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Une pile est une liste dans laquelle seul le dernier élément peut être récupéré.&lt;br /&gt;
&lt;br /&gt;
Une pile contient 2 méthodes :&lt;br /&gt;
* push(elem) : ajoute elem à la pile&lt;br /&gt;
* pop() -&amp;gt; elem : retourne le dernier élément de la pile (elem dans notre cas)&lt;br /&gt;
&lt;br /&gt;
Dans mon implémentation de la pile, une erreur est levée si l&#039;on appelle la méthode pop sur une pile vide.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;eee&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Kruskal ===&lt;br /&gt;
&lt;br /&gt;
Kruskal&lt;br /&gt;
&lt;br /&gt;
=== Prim ===&lt;br /&gt;
&lt;br /&gt;
== Résolution ==&lt;br /&gt;
&lt;br /&gt;
?&lt;br /&gt;
&lt;br /&gt;
=== Exploration exhaustive ===&lt;br /&gt;
&lt;br /&gt;
=== Mur droit ===&lt;br /&gt;
&lt;br /&gt;
== Structures de données ==&lt;br /&gt;
&lt;br /&gt;
=== Union-Find ===&lt;br /&gt;
&lt;br /&gt;
Dijoint Set&lt;br /&gt;
&lt;br /&gt;
=== Pile ===&lt;br /&gt;
&lt;br /&gt;
Stack&lt;br /&gt;
&lt;br /&gt;
=== File ===&lt;br /&gt;
&lt;br /&gt;
Queue&lt;br /&gt;
&lt;br /&gt;
== Affichage ==&lt;br /&gt;
&lt;br /&gt;
tkinter &lt;br /&gt;
&lt;br /&gt;
[https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#Exploration_exhaustive tkinter]&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
Le code source est disponible à l&#039;adresse Github suivante : https://github.com/Rominos111/Labyrinthe_VISI201&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
&lt;br /&gt;
== Annexes ==&lt;/div&gt;</summary>
		<author><name>Theodet</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11662</id>
		<title>Génération et résolution de labyrinthes II</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11662"/>
		<updated>2019-05-17T09:24:26Z</updated>

		<summary type="html">&lt;p&gt;Theodet : /* Prim */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__FORCETOC__[[Fichier:labyrinthe_photo.png|vignette|300px|Labyrinthe généré avec Kruskal et résolu avec le parcours en profondeur. En route foncé, l&#039;entrée. En vert, la sortie. En bleu, le chemin. En rouge clair, les cellules visitées lors de la résolution.|alt=&amp;quot;Labyrinthe&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
Lorem ipsum&lt;br /&gt;
&lt;br /&gt;
== Représentation ==&lt;br /&gt;
&lt;br /&gt;
=== Propriétés ===&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe est une grille de cellules reliées, ou non, entre elles.&lt;br /&gt;
&lt;br /&gt;
Deux cellules sont reliées entre elles par une &#039;&#039;&#039;porte&#039;&#039;&#039;, ou séparées par un &#039;&#039;&#039;mur&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Tout labyrinthe a &#039;&#039;&#039;une entrée&#039;&#039;&#039; et &#039;&#039;&#039;une sortie&#039;&#039;&#039;, et quelle que soit l&#039;entrée ou la sortie, le chemin entre ces deux cellules est &#039;&#039;&#039;unique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Modélisation en graphe ===&lt;br /&gt;
&lt;br /&gt;
En théorie des graphes, un graphe est un ensemble de &#039;&#039;&#039;points&#039;&#039;&#039; (ou nœuds ou sommets) reliés ensemble par des &#039;&#039;&#039;lignes&#039;&#039;&#039; (ou liens ou arêtes).&lt;br /&gt;
&lt;br /&gt;
Un graphe peut être &#039;&#039;&#039;connexe&#039;&#039;&#039; (en un seul morceau) ou &#039;&#039;&#039;non connexe&#039;&#039;&#039; (en plusieurs morceaux).&lt;br /&gt;
&lt;br /&gt;
Un graphe peut aussi être &#039;&#039;&#039;cyclique&#039;&#039;&#039; si les points sont reliés en formant une boucle ou &#039;&#039;&#039;acyclique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Enfin, un graphe peut être &#039;&#039;&#039;orienté&#039;&#039;&#039; (si les arêtes sont à sens unique) ou &#039;&#039;&#039;non orienté&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:graphe_cyclique.png|vignette|centre|500px|Exemple de graphe connexe cyclique non orienté|alt=Graphe cyclique]]&lt;br /&gt;
&lt;br /&gt;
Un &#039;&#039;&#039;arbre&#039;&#039;&#039; est un graphe connexe, acyclique et non orienté.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Arbre.PNG|vignette|centre|500px|Exemple d&#039;arbre|alt=Arbre]]&lt;br /&gt;
&lt;br /&gt;
En plaçant un point sur chaque cellule de notre labyrinthe, et en reliant deux cellules séparées par une porte, on peut dessiner un arbre comme ceci :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:labyrinthe_avec_arbre.png|vignette|centre|500px|Exemple de labyrinthe avec son arbre. Pour plus de simplicité, on attribue à chaque nœud une position.|alt=Labyrinthe avec arbre]]&lt;br /&gt;
&lt;br /&gt;
== Génération ==&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe rectangulaire de largeur &amp;lt;math&amp;gt; L &amp;lt;/math&amp;gt; et de hauteur &amp;lt;math&amp;gt; H &amp;lt;/math&amp;gt; contient exactement &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; portes.&lt;br /&gt;
&lt;br /&gt;
Du point de vue du graphe, il y a donc &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; arêtes.&lt;br /&gt;
&lt;br /&gt;
Maintenant, comment répartir toutes ces portes de façon à ce que toutes les cellules soient accessibles et qu&#039;il n&#039;existe qu&#039;un unique chemin entre l&#039;entrée et la sortie ?&lt;br /&gt;
&lt;br /&gt;
De nombreux algorithmes existent, dont le parcours en profondeur et l&#039;algorithme de Kruskal.&lt;br /&gt;
Chaque algorithme est différent et produit des labyrinthes visuellement différents.&lt;br /&gt;
&lt;br /&gt;
=== Parcours en profondeur ===&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;algorithme du parcours en profondeur (&amp;quot;recursive backtracker&amp;quot; en anglais), on commence sur une cellule aléatoire dans le labyrinthe.&lt;br /&gt;
&lt;br /&gt;
On se dirige dans une direction aléatoire et on casse le mur en face, tout en marquant la cellule précédente comme visitée.&lt;br /&gt;
&lt;br /&gt;
Lorsque aucune direction n&#039;est disponible, on remonte à la position précédente.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:recursive_backtracker.gif|vignette|centre|500px|Illustration du parcours en profondeur|alt=Parcours en profondeur.]]&lt;br /&gt;
&lt;br /&gt;
Pour sauvegarder l&#039;historique des positions, on peut utiliser une &#039;&#039;&#039;pile&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Une pile est une liste dans laquelle seul le dernier élément peut être récupéré.&lt;br /&gt;
&lt;br /&gt;
Une pile contient 2 méthodes :&lt;br /&gt;
* push(elem) : ajoute elem à la pile&lt;br /&gt;
* pop() -&amp;gt; elem : retourne le dernier élément de la pile (elem dans notre cas)&lt;br /&gt;
&lt;br /&gt;
Dans mon implémentation de la pile, une erreur est levée si l&#039;on appelle la méthode pop sur une pile vide.&lt;br /&gt;
&lt;br /&gt;
=== Kruskal ===&lt;br /&gt;
&lt;br /&gt;
Kruskal&lt;br /&gt;
&lt;br /&gt;
=== Prim ===&lt;br /&gt;
&lt;br /&gt;
== Résolution ==&lt;br /&gt;
&lt;br /&gt;
?&lt;br /&gt;
&lt;br /&gt;
=== Exploration exhaustive ===&lt;br /&gt;
&lt;br /&gt;
=== Mur droit ===&lt;br /&gt;
&lt;br /&gt;
== Structures de données ==&lt;br /&gt;
&lt;br /&gt;
=== Union-Find ===&lt;br /&gt;
&lt;br /&gt;
Dijoint Set&lt;br /&gt;
&lt;br /&gt;
=== Pile ===&lt;br /&gt;
&lt;br /&gt;
Stack&lt;br /&gt;
&lt;br /&gt;
=== File ===&lt;br /&gt;
&lt;br /&gt;
Queue&lt;br /&gt;
&lt;br /&gt;
== Affichage ==&lt;br /&gt;
&lt;br /&gt;
tkinter &lt;br /&gt;
&lt;br /&gt;
[https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#Exploration_exhaustive tkinter]&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
Le code source est disponible à l&#039;adresse Github suivante : https://github.com/Rominos111/Labyrinthe_VISI201&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
&lt;br /&gt;
== Annexes ==&lt;/div&gt;</summary>
		<author><name>Theodet</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11661</id>
		<title>Génération et résolution de labyrinthes II</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11661"/>
		<updated>2019-05-17T09:19:22Z</updated>

		<summary type="html">&lt;p&gt;Theodet : /* Génération */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__FORCETOC__[[Fichier:labyrinthe_photo.png|vignette|300px|Labyrinthe généré avec Kruskal et résolu avec le parcours en profondeur. En route foncé, l&#039;entrée. En vert, la sortie. En bleu, le chemin. En rouge clair, les cellules visitées lors de la résolution.|alt=&amp;quot;Labyrinthe&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
Lorem ipsum&lt;br /&gt;
&lt;br /&gt;
== Représentation ==&lt;br /&gt;
&lt;br /&gt;
=== Propriétés ===&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe est une grille de cellules reliées, ou non, entre elles.&lt;br /&gt;
&lt;br /&gt;
Deux cellules sont reliées entre elles par une &#039;&#039;&#039;porte&#039;&#039;&#039;, ou séparées par un &#039;&#039;&#039;mur&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Tout labyrinthe a &#039;&#039;&#039;une entrée&#039;&#039;&#039; et &#039;&#039;&#039;une sortie&#039;&#039;&#039;, et quelle que soit l&#039;entrée ou la sortie, le chemin entre ces deux cellules est &#039;&#039;&#039;unique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Modélisation en graphe ===&lt;br /&gt;
&lt;br /&gt;
En théorie des graphes, un graphe est un ensemble de &#039;&#039;&#039;points&#039;&#039;&#039; (ou nœuds ou sommets) reliés ensemble par des &#039;&#039;&#039;lignes&#039;&#039;&#039; (ou liens ou arêtes).&lt;br /&gt;
&lt;br /&gt;
Un graphe peut être &#039;&#039;&#039;connexe&#039;&#039;&#039; (en un seul morceau) ou &#039;&#039;&#039;non connexe&#039;&#039;&#039; (en plusieurs morceaux).&lt;br /&gt;
&lt;br /&gt;
Un graphe peut aussi être &#039;&#039;&#039;cyclique&#039;&#039;&#039; si les points sont reliés en formant une boucle ou &#039;&#039;&#039;acyclique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Enfin, un graphe peut être &#039;&#039;&#039;orienté&#039;&#039;&#039; (si les arêtes sont à sens unique) ou &#039;&#039;&#039;non orienté&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:graphe_cyclique.png|vignette|centre|500px|Exemple de graphe connexe cyclique non orienté|alt=Graphe cyclique]]&lt;br /&gt;
&lt;br /&gt;
Un &#039;&#039;&#039;arbre&#039;&#039;&#039; est un graphe connexe, acyclique et non orienté.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Arbre.PNG|vignette|centre|500px|Exemple d&#039;arbre|alt=Arbre]]&lt;br /&gt;
&lt;br /&gt;
En plaçant un point sur chaque cellule de notre labyrinthe, et en reliant deux cellules séparées par une porte, on peut dessiner un arbre comme ceci :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:labyrinthe_avec_arbre.png|vignette|centre|500px|Exemple de labyrinthe avec son arbre. Pour plus de simplicité, on attribue à chaque nœud une position.|alt=Labyrinthe avec arbre]]&lt;br /&gt;
&lt;br /&gt;
== Génération ==&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe rectangulaire de largeur &amp;lt;math&amp;gt; L &amp;lt;/math&amp;gt; et de hauteur &amp;lt;math&amp;gt; H &amp;lt;/math&amp;gt; contient exactement &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; portes.&lt;br /&gt;
&lt;br /&gt;
Du point de vue du graphe, il y a donc &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; arêtes.&lt;br /&gt;
&lt;br /&gt;
Maintenant, comment répartir toutes ces portes de façon à ce que toutes les cellules soient accessibles et qu&#039;il n&#039;existe qu&#039;un unique chemin entre l&#039;entrée et la sortie ?&lt;br /&gt;
&lt;br /&gt;
De nombreux algorithmes existent, dont le parcours en profondeur et l&#039;algorithme de Kruskal.&lt;br /&gt;
Chaque algorithme est différent et produit des labyrinthes visuellement différents.&lt;br /&gt;
&lt;br /&gt;
=== Parcours en profondeur ===&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;algorithme du parcours en profondeur (&amp;quot;recursive backtracker&amp;quot; en anglais), on commence sur une cellule aléatoire dans le labyrinthe.&lt;br /&gt;
&lt;br /&gt;
On se dirige dans une direction aléatoire et on casse le mur en face, tout en marquant la cellule précédente comme visitée.&lt;br /&gt;
&lt;br /&gt;
Lorsque aucune direction n&#039;est disponible, on remonte à la position précédente.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:recursive_backtracker.gif|vignette|centre|500px|Illustration du parcours en profondeur|alt=Parcours en profondeur.]]&lt;br /&gt;
&lt;br /&gt;
Pour sauvegarder l&#039;historique des positions, on peut utiliser une &#039;&#039;&#039;pile&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Une pile est une liste dans laquelle seul le dernier élément peut être récupéré.&lt;br /&gt;
&lt;br /&gt;
Une pile contient 2 méthodes :&lt;br /&gt;
* push(elem) : ajoute elem à la pile&lt;br /&gt;
* pop() -&amp;gt; elem : retourne le dernier élément de la pile (elem dans notre cas)&lt;br /&gt;
&lt;br /&gt;
Dans mon implémentation de la pile, une erreur est levée si l&#039;on appelle la méthode pop sur une pile vide.&lt;br /&gt;
&lt;br /&gt;
=== Kruskal ===&lt;br /&gt;
&lt;br /&gt;
Kruskal&lt;br /&gt;
&lt;br /&gt;
=== Prim ===&lt;br /&gt;
&lt;br /&gt;
?&lt;br /&gt;
&lt;br /&gt;
== Résolution ==&lt;br /&gt;
&lt;br /&gt;
?&lt;br /&gt;
&lt;br /&gt;
=== Exploration exhaustive ===&lt;br /&gt;
&lt;br /&gt;
=== Mur droit ===&lt;br /&gt;
&lt;br /&gt;
== Structures de données ==&lt;br /&gt;
&lt;br /&gt;
=== Union-Find ===&lt;br /&gt;
&lt;br /&gt;
Dijoint Set&lt;br /&gt;
&lt;br /&gt;
=== Pile ===&lt;br /&gt;
&lt;br /&gt;
Stack&lt;br /&gt;
&lt;br /&gt;
=== File ===&lt;br /&gt;
&lt;br /&gt;
Queue&lt;br /&gt;
&lt;br /&gt;
== Affichage ==&lt;br /&gt;
&lt;br /&gt;
tkinter &lt;br /&gt;
&lt;br /&gt;
[https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#Exploration_exhaustive tkinter]&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
Le code source est disponible à l&#039;adresse Github suivante : https://github.com/Rominos111/Labyrinthe_VISI201&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
&lt;br /&gt;
== Annexes ==&lt;/div&gt;</summary>
		<author><name>Theodet</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11660</id>
		<title>Génération et résolution de labyrinthes II</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11660"/>
		<updated>2019-05-17T09:19:01Z</updated>

		<summary type="html">&lt;p&gt;Theodet : /* Génération */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__FORCETOC__[[Fichier:labyrinthe_photo.png|vignette|300px|Labyrinthe généré avec Kruskal et résolu avec le parcours en profondeur. En route foncé, l&#039;entrée. En vert, la sortie. En bleu, le chemin. En rouge clair, les cellules visitées lors de la résolution.|alt=&amp;quot;Labyrinthe&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
Lorem ipsum&lt;br /&gt;
&lt;br /&gt;
== Représentation ==&lt;br /&gt;
&lt;br /&gt;
=== Propriétés ===&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe est une grille de cellules reliées, ou non, entre elles.&lt;br /&gt;
&lt;br /&gt;
Deux cellules sont reliées entre elles par une &#039;&#039;&#039;porte&#039;&#039;&#039;, ou séparées par un &#039;&#039;&#039;mur&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Tout labyrinthe a &#039;&#039;&#039;une entrée&#039;&#039;&#039; et &#039;&#039;&#039;une sortie&#039;&#039;&#039;, et quelle que soit l&#039;entrée ou la sortie, le chemin entre ces deux cellules est &#039;&#039;&#039;unique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Modélisation en graphe ===&lt;br /&gt;
&lt;br /&gt;
En théorie des graphes, un graphe est un ensemble de &#039;&#039;&#039;points&#039;&#039;&#039; (ou nœuds ou sommets) reliés ensemble par des &#039;&#039;&#039;lignes&#039;&#039;&#039; (ou liens ou arêtes).&lt;br /&gt;
&lt;br /&gt;
Un graphe peut être &#039;&#039;&#039;connexe&#039;&#039;&#039; (en un seul morceau) ou &#039;&#039;&#039;non connexe&#039;&#039;&#039; (en plusieurs morceaux).&lt;br /&gt;
&lt;br /&gt;
Un graphe peut aussi être &#039;&#039;&#039;cyclique&#039;&#039;&#039; si les points sont reliés en formant une boucle ou &#039;&#039;&#039;acyclique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Enfin, un graphe peut être &#039;&#039;&#039;orienté&#039;&#039;&#039; (si les arêtes sont à sens unique) ou &#039;&#039;&#039;non orienté&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:graphe_cyclique.png|vignette|centre|500px|Exemple de graphe connexe cyclique non orienté|alt=Graphe cyclique]]&lt;br /&gt;
&lt;br /&gt;
Un &#039;&#039;&#039;arbre&#039;&#039;&#039; est un graphe connexe, acyclique et non orienté.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Arbre.PNG|vignette|centre|500px|Exemple d&#039;arbre|alt=Arbre]]&lt;br /&gt;
&lt;br /&gt;
En plaçant un point sur chaque cellule de notre labyrinthe, et en reliant deux cellules séparées par une porte, on peut dessiner un arbre comme ceci :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:labyrinthe_avec_arbre.png|vignette|centre|500px|Exemple de labyrinthe avec son arbre. Pour plus de simplicité, on attribue à chaque nœud une position.|alt=Labyrinthe avec arbre]]&lt;br /&gt;
&lt;br /&gt;
== Génération ==&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe rectangulaire de largeur L et de hauteur H contient exactement &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; portes.&lt;br /&gt;
&lt;br /&gt;
Du point de vue du graphe, il y a donc &amp;lt;math&amp;gt;L \times H - 1&amp;lt;/math&amp;gt; arêtes.&lt;br /&gt;
&lt;br /&gt;
Maintenant, comment répartir toutes ces portes de façon à ce que toutes les cellules soient accessibles et qu&#039;il n&#039;existe qu&#039;un unique chemin entre l&#039;entrée et la sortie ?&lt;br /&gt;
&lt;br /&gt;
De nombreux algorithmes existent, dont le parcours en profondeur et l&#039;algorithme de Kruskal.&lt;br /&gt;
Chaque algorithme est différent et produit des labyrinthes visuellement différents.&lt;br /&gt;
&lt;br /&gt;
=== Parcours en profondeur ===&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;algorithme du parcours en profondeur (&amp;quot;recursive backtracker&amp;quot; en anglais), on commence sur une cellule aléatoire dans le labyrinthe.&lt;br /&gt;
&lt;br /&gt;
On se dirige dans une direction aléatoire et on casse le mur en face, tout en marquant la cellule précédente comme visitée.&lt;br /&gt;
&lt;br /&gt;
Lorsque aucune direction n&#039;est disponible, on remonte à la position précédente.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:recursive_backtracker.gif|vignette|centre|500px|Illustration du parcours en profondeur|alt=Parcours en profondeur.]]&lt;br /&gt;
&lt;br /&gt;
Pour sauvegarder l&#039;historique des positions, on peut utiliser une &#039;&#039;&#039;pile&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Une pile est une liste dans laquelle seul le dernier élément peut être récupéré.&lt;br /&gt;
&lt;br /&gt;
Une pile contient 2 méthodes :&lt;br /&gt;
* push(elem) : ajoute elem à la pile&lt;br /&gt;
* pop() -&amp;gt; elem : retourne le dernier élément de la pile (elem dans notre cas)&lt;br /&gt;
&lt;br /&gt;
Dans mon implémentation de la pile, une erreur est levée si l&#039;on appelle la méthode pop sur une pile vide.&lt;br /&gt;
&lt;br /&gt;
=== Kruskal ===&lt;br /&gt;
&lt;br /&gt;
Kruskal&lt;br /&gt;
&lt;br /&gt;
=== Prim ===&lt;br /&gt;
&lt;br /&gt;
?&lt;br /&gt;
&lt;br /&gt;
== Résolution ==&lt;br /&gt;
&lt;br /&gt;
?&lt;br /&gt;
&lt;br /&gt;
=== Exploration exhaustive ===&lt;br /&gt;
&lt;br /&gt;
=== Mur droit ===&lt;br /&gt;
&lt;br /&gt;
== Structures de données ==&lt;br /&gt;
&lt;br /&gt;
=== Union-Find ===&lt;br /&gt;
&lt;br /&gt;
Dijoint Set&lt;br /&gt;
&lt;br /&gt;
=== Pile ===&lt;br /&gt;
&lt;br /&gt;
Stack&lt;br /&gt;
&lt;br /&gt;
=== File ===&lt;br /&gt;
&lt;br /&gt;
Queue&lt;br /&gt;
&lt;br /&gt;
== Affichage ==&lt;br /&gt;
&lt;br /&gt;
tkinter &lt;br /&gt;
&lt;br /&gt;
[https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#Exploration_exhaustive tkinter]&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
Le code source est disponible à l&#039;adresse Github suivante : https://github.com/Rominos111/Labyrinthe_VISI201&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
&lt;br /&gt;
== Annexes ==&lt;/div&gt;</summary>
		<author><name>Theodet</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11659</id>
		<title>Génération et résolution de labyrinthes II</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11659"/>
		<updated>2019-05-17T09:17:43Z</updated>

		<summary type="html">&lt;p&gt;Theodet : /* Parcours en profondeur */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__FORCETOC__[[Fichier:labyrinthe_photo.png|vignette|300px|Labyrinthe généré avec Kruskal et résolu avec le parcours en profondeur. En route foncé, l&#039;entrée. En vert, la sortie. En bleu, le chemin. En rouge clair, les cellules visitées lors de la résolution.|alt=&amp;quot;Labyrinthe&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
Lorem ipsum&lt;br /&gt;
&lt;br /&gt;
== Représentation ==&lt;br /&gt;
&lt;br /&gt;
=== Propriétés ===&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe est une grille de cellules reliées, ou non, entre elles.&lt;br /&gt;
&lt;br /&gt;
Deux cellules sont reliées entre elles par une &#039;&#039;&#039;porte&#039;&#039;&#039;, ou séparées par un &#039;&#039;&#039;mur&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Tout labyrinthe a &#039;&#039;&#039;une entrée&#039;&#039;&#039; et &#039;&#039;&#039;une sortie&#039;&#039;&#039;, et quelle que soit l&#039;entrée ou la sortie, le chemin entre ces deux cellules est &#039;&#039;&#039;unique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Modélisation en graphe ===&lt;br /&gt;
&lt;br /&gt;
En théorie des graphes, un graphe est un ensemble de &#039;&#039;&#039;points&#039;&#039;&#039; (ou nœuds ou sommets) reliés ensemble par des &#039;&#039;&#039;lignes&#039;&#039;&#039; (ou liens ou arêtes).&lt;br /&gt;
&lt;br /&gt;
Un graphe peut être &#039;&#039;&#039;connexe&#039;&#039;&#039; (en un seul morceau) ou &#039;&#039;&#039;non connexe&#039;&#039;&#039; (en plusieurs morceaux).&lt;br /&gt;
&lt;br /&gt;
Un graphe peut aussi être &#039;&#039;&#039;cyclique&#039;&#039;&#039; si les points sont reliés en formant une boucle ou &#039;&#039;&#039;acyclique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Enfin, un graphe peut être &#039;&#039;&#039;orienté&#039;&#039;&#039; (si les arêtes sont à sens unique) ou &#039;&#039;&#039;non orienté&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:graphe_cyclique.png|vignette|centre|500px|Exemple de graphe connexe cyclique non orienté|alt=Graphe cyclique]]&lt;br /&gt;
&lt;br /&gt;
Un &#039;&#039;&#039;arbre&#039;&#039;&#039; est un graphe connexe, acyclique et non orienté.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Arbre.PNG|vignette|centre|500px|Exemple d&#039;arbre|alt=Arbre]]&lt;br /&gt;
&lt;br /&gt;
En plaçant un point sur chaque cellule de notre labyrinthe, et en reliant deux cellules séparées par une porte, on peut dessiner un arbre comme ceci :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:labyrinthe_avec_arbre.png|vignette|centre|500px|Exemple de labyrinthe avec son arbre. Pour plus de simplicité, on attribue à chaque nœud une position.|alt=Labyrinthe avec arbre]]&lt;br /&gt;
&lt;br /&gt;
== Génération ==&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe rectangulaire de largeur L et de hauteur H contient exactement L*H-1 portes.&lt;br /&gt;
&lt;br /&gt;
Du point de vue du graphe, il y a donc L*H-1 arêtes.&lt;br /&gt;
&lt;br /&gt;
Maintenant, comment répartir toutes ces portes de façon à ce que toutes les cellules soient accessibles et qu&#039;il n&#039;existe qu&#039;un unique chemin entre l&#039;entrée et la sortie ?&lt;br /&gt;
&lt;br /&gt;
De nombreux algorithmes existent, dont le parcours en profondeur et l&#039;algorithme de Kruskal.&lt;br /&gt;
Chaque algorithme est différent et produit des labyrinthes visuellement différents.&lt;br /&gt;
&lt;br /&gt;
=== Parcours en profondeur ===&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;algorithme du parcours en profondeur (&amp;quot;recursive backtracker&amp;quot; en anglais), on commence sur une cellule aléatoire dans le labyrinthe.&lt;br /&gt;
&lt;br /&gt;
On se dirige dans une direction aléatoire et on casse le mur en face, tout en marquant la cellule précédente comme visitée.&lt;br /&gt;
&lt;br /&gt;
Lorsque aucune direction n&#039;est disponible, on remonte à la position précédente.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:recursive_backtracker.gif|vignette|centre|500px|Illustration du parcours en profondeur|alt=Parcours en profondeur.]]&lt;br /&gt;
&lt;br /&gt;
Pour sauvegarder l&#039;historique des positions, on peut utiliser une &#039;&#039;&#039;pile&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Une pile est une liste dans laquelle seul le dernier élément peut être récupéré.&lt;br /&gt;
&lt;br /&gt;
Une pile contient 2 méthodes :&lt;br /&gt;
* push(elem) : ajoute elem à la pile&lt;br /&gt;
* pop() -&amp;gt; elem : retourne le dernier élément de la pile (elem dans notre cas)&lt;br /&gt;
&lt;br /&gt;
Dans mon implémentation de la pile, une erreur est levée si l&#039;on appelle la méthode pop sur une pile vide.&lt;br /&gt;
&lt;br /&gt;
=== Kruskal ===&lt;br /&gt;
&lt;br /&gt;
Kruskal&lt;br /&gt;
&lt;br /&gt;
=== Prim ===&lt;br /&gt;
&lt;br /&gt;
?&lt;br /&gt;
&lt;br /&gt;
== Résolution ==&lt;br /&gt;
&lt;br /&gt;
?&lt;br /&gt;
&lt;br /&gt;
=== Exploration exhaustive ===&lt;br /&gt;
&lt;br /&gt;
=== Mur droit ===&lt;br /&gt;
&lt;br /&gt;
== Structures de données ==&lt;br /&gt;
&lt;br /&gt;
=== Union-Find ===&lt;br /&gt;
&lt;br /&gt;
Dijoint Set&lt;br /&gt;
&lt;br /&gt;
=== Pile ===&lt;br /&gt;
&lt;br /&gt;
Stack&lt;br /&gt;
&lt;br /&gt;
=== File ===&lt;br /&gt;
&lt;br /&gt;
Queue&lt;br /&gt;
&lt;br /&gt;
== Affichage ==&lt;br /&gt;
&lt;br /&gt;
tkinter &lt;br /&gt;
&lt;br /&gt;
[https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#Exploration_exhaustive tkinter]&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
Le code source est disponible à l&#039;adresse Github suivante : https://github.com/Rominos111/Labyrinthe_VISI201&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
&lt;br /&gt;
== Annexes ==&lt;/div&gt;</summary>
		<author><name>Theodet</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11658</id>
		<title>Génération et résolution de labyrinthes II</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11658"/>
		<updated>2019-05-17T09:14:06Z</updated>

		<summary type="html">&lt;p&gt;Theodet : /* Parcours en profondeur */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__FORCETOC__[[Fichier:labyrinthe_photo.png|vignette|300px|Labyrinthe généré avec Kruskal et résolu avec le parcours en profondeur. En route foncé, l&#039;entrée. En vert, la sortie. En bleu, le chemin. En rouge clair, les cellules visitées lors de la résolution.|alt=&amp;quot;Labyrinthe&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
Lorem ipsum&lt;br /&gt;
&lt;br /&gt;
== Représentation ==&lt;br /&gt;
&lt;br /&gt;
=== Propriétés ===&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe est une grille de cellules reliées, ou non, entre elles.&lt;br /&gt;
&lt;br /&gt;
Deux cellules sont reliées entre elles par une &#039;&#039;&#039;porte&#039;&#039;&#039;, ou séparées par un &#039;&#039;&#039;mur&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Tout labyrinthe a &#039;&#039;&#039;une entrée&#039;&#039;&#039; et &#039;&#039;&#039;une sortie&#039;&#039;&#039;, et quelle que soit l&#039;entrée ou la sortie, le chemin entre ces deux cellules est &#039;&#039;&#039;unique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Modélisation en graphe ===&lt;br /&gt;
&lt;br /&gt;
En théorie des graphes, un graphe est un ensemble de &#039;&#039;&#039;points&#039;&#039;&#039; (ou nœuds ou sommets) reliés ensemble par des &#039;&#039;&#039;lignes&#039;&#039;&#039; (ou liens ou arêtes).&lt;br /&gt;
&lt;br /&gt;
Un graphe peut être &#039;&#039;&#039;connexe&#039;&#039;&#039; (en un seul morceau) ou &#039;&#039;&#039;non connexe&#039;&#039;&#039; (en plusieurs morceaux).&lt;br /&gt;
&lt;br /&gt;
Un graphe peut aussi être &#039;&#039;&#039;cyclique&#039;&#039;&#039; si les points sont reliés en formant une boucle ou &#039;&#039;&#039;acyclique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Enfin, un graphe peut être &#039;&#039;&#039;orienté&#039;&#039;&#039; (si les arêtes sont à sens unique) ou &#039;&#039;&#039;non orienté&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:graphe_cyclique.png|vignette|centre|500px|Exemple de graphe connexe cyclique non orienté|alt=Graphe cyclique]]&lt;br /&gt;
&lt;br /&gt;
Un &#039;&#039;&#039;arbre&#039;&#039;&#039; est un graphe connexe, acyclique et non orienté.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Arbre.PNG|vignette|centre|500px|Exemple d&#039;arbre|alt=Arbre]]&lt;br /&gt;
&lt;br /&gt;
En plaçant un point sur chaque cellule de notre labyrinthe, et en reliant deux cellules séparées par une porte, on peut dessiner un arbre comme ceci :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:labyrinthe_avec_arbre.png|vignette|centre|500px|Exemple de labyrinthe avec son arbre. Pour plus de simplicité, on attribue à chaque nœud une position.|alt=Labyrinthe avec arbre]]&lt;br /&gt;
&lt;br /&gt;
== Génération ==&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe rectangulaire de largeur L et de hauteur H contient exactement L*H-1 portes.&lt;br /&gt;
&lt;br /&gt;
Du point de vue du graphe, il y a donc L*H-1 arêtes.&lt;br /&gt;
&lt;br /&gt;
Maintenant, comment répartir toutes ces portes de façon à ce que toutes les cellules soient accessibles et qu&#039;il n&#039;existe qu&#039;un unique chemin entre l&#039;entrée et la sortie ?&lt;br /&gt;
&lt;br /&gt;
De nombreux algorithmes existent, dont le parcours en profondeur et l&#039;algorithme de Kruskal.&lt;br /&gt;
Chaque algorithme est différent et produit des labyrinthes visuellement différents.&lt;br /&gt;
&lt;br /&gt;
=== Parcours en profondeur ===&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;algorithme du parcours en profondeur (&amp;quot;recursive backtracker&amp;quot; en anglais), on commence sur une cellule aléatoire dans le labyrinthe.&lt;br /&gt;
&lt;br /&gt;
On se dirige dans une direction aléatoire et on casse le mur en face, tout en marquant la cellule précédente comme visitée.&lt;br /&gt;
&lt;br /&gt;
Lorsque aucune direction n&#039;est disponible, on remonte à la position précédente.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:recursive_backtracker.gif|vignette|centre|500px|Illustration du parcours en profondeur|alt=Parcours en profondeur]]&lt;br /&gt;
&lt;br /&gt;
=== Kruskal ===&lt;br /&gt;
&lt;br /&gt;
Kruskal&lt;br /&gt;
&lt;br /&gt;
=== Prim ===&lt;br /&gt;
&lt;br /&gt;
?&lt;br /&gt;
&lt;br /&gt;
== Résolution ==&lt;br /&gt;
&lt;br /&gt;
?&lt;br /&gt;
&lt;br /&gt;
=== Exploration exhaustive ===&lt;br /&gt;
&lt;br /&gt;
=== Mur droit ===&lt;br /&gt;
&lt;br /&gt;
== Structures de données ==&lt;br /&gt;
&lt;br /&gt;
=== Union-Find ===&lt;br /&gt;
&lt;br /&gt;
Dijoint Set&lt;br /&gt;
&lt;br /&gt;
=== Pile ===&lt;br /&gt;
&lt;br /&gt;
Stack&lt;br /&gt;
&lt;br /&gt;
=== File ===&lt;br /&gt;
&lt;br /&gt;
Queue&lt;br /&gt;
&lt;br /&gt;
== Affichage ==&lt;br /&gt;
&lt;br /&gt;
tkinter &lt;br /&gt;
&lt;br /&gt;
[https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#Exploration_exhaustive tkinter]&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
Le code source est disponible à l&#039;adresse Github suivante : https://github.com/Rominos111/Labyrinthe_VISI201&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
&lt;br /&gt;
== Annexes ==&lt;/div&gt;</summary>
		<author><name>Theodet</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fichier:Recursive_backtracker.gif&amp;diff=11657</id>
		<title>Fichier:Recursive backtracker.gif</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fichier:Recursive_backtracker.gif&amp;diff=11657"/>
		<updated>2019-05-17T09:13:07Z</updated>

		<summary type="html">&lt;p&gt;Theodet : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Theodet</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11656</id>
		<title>Génération et résolution de labyrinthes II</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=G%C3%A9n%C3%A9ration_et_r%C3%A9solution_de_labyrinthes_II&amp;diff=11656"/>
		<updated>2019-05-17T09:09:56Z</updated>

		<summary type="html">&lt;p&gt;Theodet : /* Définition */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__FORCETOC__[[Fichier:labyrinthe_photo.png|vignette|300px|Labyrinthe généré avec Kruskal et résolu avec le parcours en profondeur. En route foncé, l&#039;entrée. En vert, la sortie. En bleu, le chemin. En rouge clair, les cellules visitées lors de la résolution.|alt=&amp;quot;Labyrinthe&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
Lorem ipsum&lt;br /&gt;
&lt;br /&gt;
== Représentation ==&lt;br /&gt;
&lt;br /&gt;
=== Propriétés ===&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe est une grille de cellules reliées, ou non, entre elles.&lt;br /&gt;
&lt;br /&gt;
Deux cellules sont reliées entre elles par une &#039;&#039;&#039;porte&#039;&#039;&#039;, ou séparées par un &#039;&#039;&#039;mur&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Tout labyrinthe a &#039;&#039;&#039;une entrée&#039;&#039;&#039; et &#039;&#039;&#039;une sortie&#039;&#039;&#039;, et quelle que soit l&#039;entrée ou la sortie, le chemin entre ces deux cellules est &#039;&#039;&#039;unique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Modélisation en graphe ===&lt;br /&gt;
&lt;br /&gt;
En théorie des graphes, un graphe est un ensemble de &#039;&#039;&#039;points&#039;&#039;&#039; (ou nœuds ou sommets) reliés ensemble par des &#039;&#039;&#039;lignes&#039;&#039;&#039; (ou liens ou arêtes).&lt;br /&gt;
&lt;br /&gt;
Un graphe peut être &#039;&#039;&#039;connexe&#039;&#039;&#039; (en un seul morceau) ou &#039;&#039;&#039;non connexe&#039;&#039;&#039; (en plusieurs morceaux).&lt;br /&gt;
&lt;br /&gt;
Un graphe peut aussi être &#039;&#039;&#039;cyclique&#039;&#039;&#039; si les points sont reliés en formant une boucle ou &#039;&#039;&#039;acyclique&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Enfin, un graphe peut être &#039;&#039;&#039;orienté&#039;&#039;&#039; (si les arêtes sont à sens unique) ou &#039;&#039;&#039;non orienté&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:graphe_cyclique.png|vignette|centre|500px|Exemple de graphe connexe cyclique non orienté|alt=Graphe cyclique]]&lt;br /&gt;
&lt;br /&gt;
Un &#039;&#039;&#039;arbre&#039;&#039;&#039; est un graphe connexe, acyclique et non orienté.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Arbre.PNG|vignette|centre|500px|Exemple d&#039;arbre|alt=Arbre]]&lt;br /&gt;
&lt;br /&gt;
En plaçant un point sur chaque cellule de notre labyrinthe, et en reliant deux cellules séparées par une porte, on peut dessiner un arbre comme ceci :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:labyrinthe_avec_arbre.png|vignette|centre|500px|Exemple de labyrinthe avec son arbre. Pour plus de simplicité, on attribue à chaque nœud une position.|alt=Labyrinthe avec arbre]]&lt;br /&gt;
&lt;br /&gt;
== Génération ==&lt;br /&gt;
&lt;br /&gt;
Un labyrinthe rectangulaire de largeur L et de hauteur H contient exactement L*H-1 portes.&lt;br /&gt;
&lt;br /&gt;
Du point de vue du graphe, il y a donc L*H-1 arêtes.&lt;br /&gt;
&lt;br /&gt;
Maintenant, comment répartir toutes ces portes de façon à ce que toutes les cellules soient accessibles et qu&#039;il n&#039;existe qu&#039;un unique chemin entre l&#039;entrée et la sortie ?&lt;br /&gt;
&lt;br /&gt;
De nombreux algorithmes existent, dont le parcours en profondeur et l&#039;algorithme de Kruskal.&lt;br /&gt;
Chaque algorithme est différent et produit des labyrinthes visuellement différents.&lt;br /&gt;
&lt;br /&gt;
=== Parcours en profondeur ===&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;algorithme du parcours en profondeur (&#039;recursive backtracker&#039; en anglais), on commence sur une cellule aléatoire dans le labyrinthe.&lt;br /&gt;
On se dirige dans une direction aléatoire et on casse le mur en face. Lorsqu&#039;aucun&lt;br /&gt;
&lt;br /&gt;
=== Kruskal ===&lt;br /&gt;
&lt;br /&gt;
Kruskal&lt;br /&gt;
&lt;br /&gt;
=== Prim ===&lt;br /&gt;
&lt;br /&gt;
?&lt;br /&gt;
&lt;br /&gt;
== Résolution ==&lt;br /&gt;
&lt;br /&gt;
?&lt;br /&gt;
&lt;br /&gt;
=== Exploration exhaustive ===&lt;br /&gt;
&lt;br /&gt;
=== Mur droit ===&lt;br /&gt;
&lt;br /&gt;
== Structures de données ==&lt;br /&gt;
&lt;br /&gt;
=== Union-Find ===&lt;br /&gt;
&lt;br /&gt;
Dijoint Set&lt;br /&gt;
&lt;br /&gt;
=== Pile ===&lt;br /&gt;
&lt;br /&gt;
Stack&lt;br /&gt;
&lt;br /&gt;
=== File ===&lt;br /&gt;
&lt;br /&gt;
Queue&lt;br /&gt;
&lt;br /&gt;
== Affichage ==&lt;br /&gt;
&lt;br /&gt;
tkinter &lt;br /&gt;
&lt;br /&gt;
[https://fr.wikipedia.org/wiki/Mod%C3%A9lisation_math%C3%A9matique_de_labyrinthe#Exploration_exhaustive tkinter]&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
Le code source est disponible à l&#039;adresse Github suivante : https://github.com/Rominos111/Labyrinthe_VISI201&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
&lt;br /&gt;
== Annexes ==&lt;/div&gt;</summary>
		<author><name>Theodet</name></author>
	</entry>
</feed>