diff --git a/Makefile b/Makefile index 01e24a1554809291de7fd09c404d1a60c3aa081b..6949d32194970f9026bbca44dba00580e89813e7 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,6 @@ +# fichier : Makefile +# auteur : Dubard Loïc + # $@ nom de la cible # $< nom de la première dépendance # $^ liste des dépendances @@ -6,12 +9,14 @@ all: phase1 phase2 -phase1: +phase1: src/main.ml + ocamlc $^ -o build/a.out phase2: + echo TODO clean: rm -rf *.cmi *.cmo archive: src/ rapport.pdf - tar zcvf DUBARD_LOIC_IPF_S3.tar.gz $^ \ No newline at end of file + tar zcvf DUBARD_LOIC.tar.gz $^ \ No newline at end of file diff --git a/src/graphe.mli b/src/graphe.mli new file mode 100644 index 0000000000000000000000000000000000000000..e178204605bbca7c6d8a7db56de39c2bee0ae251 --- /dev/null +++ b/src/graphe.mli @@ -0,0 +1 @@ +module type graphe = Map.make() \ No newline at end of file diff --git a/src/main.ml b/src/main.ml new file mode 100644 index 0000000000000000000000000000000000000000..9b99fe3a02e4bf41dc57027fd834dffe9e64daa8 --- /dev/null +++ b/src/main.ml @@ -0,0 +1,48 @@ +(* + * fichier : main.ml + * auteur : dubard loïc + *) + +(* + * définition du type graphe qui est une map de liste dont les clés sont des string + *) +module Graphe = Map.Make(String) + +(* + * @ensures : vérification du nombre d'agruments + * @raises : erreur si le nombre d'aguments est différent de 1 + *) +let _ = if Array.length Sys.argv = 1 + then failwith "Erreur : Veuillez ajouter un nom de fichier !\n" + else if Array.length Sys.argv > 2 + then failwith "Erreur : Trop d'arguments !\n" + else Printf.printf "ouverture de : %s\n" Sys.argv.(1) + +(* + * @ensures : lit le fichier en entrée + * @raises : fail si le fichier n'est pas trouvé -> "No such file or directory" + *) +let file = open_in Sys.argv.(1) +let source = input_line file +let puits = input_line file +let n = input_line file + + +(* + * @ensures : retourne le "graphe" correspondant au fichier entré + *) +let rec make_graphe n = + let line = input_line file in + let l = String.split_on_char ' ' line in + match l with + | [a ; b] -> if n = 1 + then (Graphe.add a (b::[]) Graphe.empty) + else + let g = make_graphe n + in + if (Graphe.mem a g) + then let l = Graphe.find a g in + let f = Graphe.remove a g in + Graphe.add a (b::l) f + else Graphe.add a (b::[]) g + | _ -> failwith("erreur dans le graphe !") diff --git a/src/set.mli b/src/set.mli new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/sujet.html b/sujet.html new file mode 100644 index 0000000000000000000000000000000000000000..44be75d128ca5ad6a9a35dc379f3aa984c75530f --- /dev/null +++ b/sujet.html @@ -0,0 +1,415 @@ +<!DOCTYPE html> +<html><head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <link rel="stylesheet" type="text/css" href="sujet_files/urbain_style.html"> + <title>Projet programmation fonctionnelle</title> +</head> +<body><div id="wholepage"> +<p></p> +<name> +<h1>Programmation fonctionnelle: projet 2019</h1> +</name> +<br> + +<h3>Dates et principe</h3> Cette page peut être mise à jour, avec +informations complémentaires, précisions, etc. Pensez à y revenir +souvent.<br> + +<hr> +Projet à rendre pour le vendredi <b>10/01/2020</b> à <b>23h59</b>, +aucun retard ne sera toléré.<br> Des soutenances pourront être +organisées ensuite.<br><br> + +Lire tout le sujet (tout ? tout).<br><br> + +Un rendu de projet comprend : +<ul> + <li> Un rapport précisant et justifiant vos choix (de structures, + etc.), les problèmes techniques qui se posent et les solutions + trouvées ; il donne en conclusion les limites de votre programme. Le + rapport sera de préférence composé avec LaTeX. Le soin apporté à la + grammaire et à l'orthographe est largement pris en compte.</li> +<li> Un manuel d'utilisation, même minimal.</li> +<li> Un code <em>abondamment</em> commenté ; la première partie + des commentaires comportera systématiquement les + lignes :<br></li> +<ol> +<li><tt>@requires </tt> décrivant les pré-conditions : +c'est-à-dire conditions sur les paramètres pour une bonne utilisation +(<b>pas de typage ici</b>),</li> +<li><tt>@ensures </tt> décrivant la propriété vraie à la sortie de la +fonction lorsque les pré-conditions sont respectées, le cas échéant +avec mention des comportements en cas de succès et en cas +d'échec,</li> +<li><tt>@raises </tt> énumérant les exceptions éventuellement levées + (et précisant dans quel(s) cas elles le sont).</li> +</ol> +On pourra préciser des informations additionnelles si des techniques +particulières méritent d'être mentionnées.<br><br> Le code doit +enfin <b>compiler</b> sans erreur (évidemment) et sans warning sur les machines des salles de TP. +</ul> +Avez-vous lu tout le sujet ? + +<hr> + +<h4>Protocole de dépôt</h4> +<p> + Vous devez rendre : + </p><ul> + <li>votre rapport au format <tt>pdf</tt></li> + <li>vos fichiers de code.</li> + <li>vos tests.</li> + </ul> + rassemblés dans une archive tar gzippée identifiée + comme <em>votre_prénom_votre_nom</em><tt>.tgz</tt>.<br> La + commande devrait ressembler à :<br> + <tt>tar cvfz randolph_carter.tgz rapport.pdf fichiers.ml + autres_truc_éventuels</tt>… +<p></p> +<p> + <b>Lisez le man</b> et testez le contenu de votre archive. Une + commande comme par exemple :<br> + <tt>tar tvf randolph_carter.tgz</tt><br> doit lister les fichiers + et donner leur taille.<br> Une archive qui ne contient pas les + fichiers demandés ne sera pas excusable. Une archive qui n'est pas + au bon format ne sera pas considérée. +</p> +<p> +<b>Procédure de dépôt</b><br> Vous devez enregistrer votre archive +tar dans le dépôt dédié au cours IPF (ipf-s3-projet-2018) en vous +connectant à <tt>http://exam.ensiie.fr</tt>. Ce dépôt sera ouvert +jusqu'au 10 janvier inclus. +</p> + +<hr> + +<h3>Contexte</h3> +<p> Le but de ce projet est de maximiser le flux de café entre le bar de + l'ENSIIE (considéré idéalement comme une source infinie de café) et le +bureau de M. Forest (considéré effectivement comme un puits infini de +café).</p> + +<p> + Dans le monde moderne de l'enseignement en école d'ingénieur nécessite de maximiser ce flux pour des raisons évidentes. + Votre projet se développera en plusieurs étapes : + </p><ol> + <li>dans un premier temps, étant donnée une représentation adaptée +du plan de l'école, vous chercherez les chemins les plus rapides (les +plus courts), de la source au puits, </li> + <li>dans un second temps, après avoir pris en compte la capacité des + différents couloirs et escaliers, vous chercherez à trouver un moyen de + maximiser le flux possible de café. Votre programme disposera d'un +temps fini pour répondre.</li> + </ol> +<p></p> + +<h3>Travail à effectuer</h3> +<p>Vous devrez produire un programme par phase ci-dessous dont le nom devra être <tt>phase1</tt>, <tt>phase2</tt>,... et un Makefile pour générer les différents executables.</p> + +<h4>Phase 1:</h4> + +<p>Dans un premier temps, nous allons nous contenter de recenser les +différents plus courts chemins (en nombre d'arêtes) entre la source et +le puits.</p> + +<p>Pour cela, votre programme devra en argument un nom de fichier dans +lequel sera codé le nom de la source, du puits et les différents chemins + entre différents points du bâtiment (cf <a href="#format-entree-1">format d'entrée</a>). Il devra calculer puis retourner <b>tous</b> les chemins les plus courts entre la sources et le puits selon le bon format de sortie (cf <a href="#format-sortie-1">format de sortie</a>).</p> + +<h5><a name="format-entree-1">format d'entrée</a> :</h5> + Les fichiers d'entrées seront au format suivant : + <ol> + <li>Une première ligne contenant un mot (suite de caractères alpha numériques et de "_") désignant la source</li> + <li>Une seconde ligne contenant un mot désignant le puit</li> + <li>Une troisième ligne contenant un entier <tt>n</tt> désignant le nombre de chemins élémentaires</li> + <li><tt>n</tt> lignes contenant chacune deux mots désignant chacun +un point de départ et un point d'arrivée pour des chemins élémentaires. +Ces chemins seront considérés comme à sens unique. + </li></ol> + Vous trouverez <a href="http://web4.ensiie.fr/~forest/IPF/PROJET/phase1/input.txt">ici</a> un exemple très minimal de fichier d'entrée pour la phase 1. + +<h5><a name="format-sortie-1">format de sortie</a> :</h5> +<p>Pour chaque plus court chemin entre la source et le puits : une ligne + contenant les noms des sommets de ce chemin séparés par des espaces </p> +<p>L'ordre entre les differents chemins n'est pas spécifié et n'a pas d'importance</p> + Vous trouverez <a href="http://web4.ensiie.fr/~forest/IPF/PROJET/phase1/output.txt">ici</a> un exemple de sortie correspondant au fichier <a href="http://web4.ensiie.fr/~forest/IPF/PROJET/phase1/input.txt">d'exemple d'entrée</a> + +<h4>Phase 2:</h4> +Nous allons maintenant nous interesser à l'obtention d'un flux maximal. +Pour cela, nous allons devoir doter nos arcs d'une capacité maximale +(les couloirs et escaliers de l'école ne pouvant pas laisser passer plus + d'un certain nombre d'étudiants en parallèle. + + +<p>Il existe de nombreux algorithme pour résoudre ce problème. Il vous est conseillé d'utilisé l'algorithme de <a href="https://en.wikipedia.org/wiki/Dinic's_algorithm">Dinic</a>. Cet algorithme procède de la manière suivante : + </p><ol> + <li>On commence par initialiser le flux à 0 et l'utilisation de chaque lien à 0,</li> + <li>Tant qu'il existe un chemin entre la source et le puit dans le graphe des capacités résiduelles :</li> + <ol type="a"> + <li>Construire le graphe des capacités résiduelles correspondant au graphe de départ et aux flux déjà utilisés,</li> + <li>Chercher un flux bloquant dans le graphe résiduel. Un flux +bloquant est un flux dont tous les plus courts chemins entre la source +et le puit sont utilisés à leur capicité maximale.</li> + <li>Augmenter le flux global de la valeur précédement trouvée. + </li></ol> + </ol> + + + +<p></p> + +<h5><a name="format-entree-2">format d'entrée</a> :</h5> + Les fichiers d'entrées seront au format suivant : + <ol> + <li>Une première ligne contenant un mot (suite de caractères alpha numériques et de "_") désignant la source</li> + <li>Une seconde ligne contenant un mot désignant le puit</li> + <li>Une troisième ligne contenant un entier <tt>n</tt> désignant le nombre de chemins élémentaires</li> + <li><tt>n</tt> lignes contenant chacune deux mots et un entier +désignant respectivement un point de départ et un point d'arrivée et une + capacité pour des chemins élémentaires (un entier). Ces chemins seront +considérés comme à sens unique. + </li></ol> + Vous trouverez <a href="http://web4.ensiie.fr/~forest/IPF/PROJET/phase2/input.txt">ici</a> un exemple très minimal de fichier d'entrée pour la phase 2. + +<h5><a name="format-sortie-2">format de sortie</a> :</h5> +<ol> + <li>Une première ligne contenant le débit maximal entre la source et le puit,</li> + <li>Une seconde ligne contenant un entier <tt>k</tt> désignant le nombre chemins élémentaires utilisés pour obtenir ce flux maximum</li> + <li><tt>k</tt> lignes contenant chacune deux mots et un entier +désignant respectivement un point de départ et un point d'arrivée et la +capacité utilisée sur ce chemin élémentaire. +</li></ol> + Vous trouverez <a href="http://web4.ensiie.fr/~forest/IPF/PROJET/phase2/output.txt">ici</a> un exemple de sortie correspondant au fichier <a href="http://web4.ensiie.fr/~forest/IPF/PROJET/phase2/input.txt">d'exemple d'entrée</a> + +<h4>Phase 3 :</h4> Plus tard...<p>ou pas</p> + + +<!-- <p><b>Ne remplir que la première phase de ce travail n'est pas +--> <!-- envisageable, répondre correctement aux deux premières phases +est --> <!-- acceptable. Une solution, même imparfaite, à la +troisième --> <!-- phase sera considérée comme un bon travail.</b></p> +--> + +<!-- Lire les interfaces des modules Ocaml <em>String</em> +et <em>Map</em> --> <!-- est conseillé. --> + + + +<!-- <p>Votre programme devra trouver une tournée aussi --> +<!-- optimale que possible répondant aux contraintes suivantes : --> +<!-- <ul> --> +<!-- <li>la ville de départ et la ville d'arrivée de la tournée doivent --> +<!-- être les mêmes; </li> --> +<!-- <li>toutes les villes doivent être visitées au moins une fois (il --> +<!-- est possible de visiter plusisieurs fois la même ville);</li> --> +<!-- <li>la distance totale parcourue doit être aussi réduite que --> +<!-- possible;</li> --> +<!-- <li>si une ville A est reliée directement à une ville B, alors la --> +<!-- ville B est reliée directement à la ville A par un trajet de même --> +<!-- longueur (les routes sont toutes à double sens). </li> --> +<!-- </ul> --> +<!-- </p> --> + +<!-- La distance de parcours entre deux villes sera toujours la distance --> +<!-- euclidienne entre leurs coordonnées. --> + +<!-- <p> --> +<!-- Étonnamment, ce problème est particulièrement complexe à résoudre de --> +<!-- manière optimale. On ne connaît pas (et il est peu probable que l'on --> +<!-- connaisse un jour) d'algorithme exact (qui trouve une tournée --> +<!-- optimale) fondamentalement plus efficace que d'énumérer toutes les --> +<!-- tournées possibles pour sélectionner la meilleure. --> + +<!-- Votre planificateur devant répondre avant la mort thermique de --> +<!-- l'univers, il ne vous est pas demandé de donner une solution --> +<!-- optimale mais une approximation raisonnable de cette solution. --> +<!-- </p> --> + +<!-- <p> --> +<!-- Une assez bonne approximation (de l'ordre de quelques fois la distance --> +<!-- minimale) peut être trouvée en un temps raisonnable de la manière suivante : --> +<!-- <ol> --> +<!-- <li>on commence par choisir une première tournée sur un petit --> +<!-- nombre de villes;</li> --> +<!-- <li>on incorpore petit à petit les villes manquantes de manière à --> +<!-- ne pas trop augmenter la longueur totale de la tournée;</li> --> +<!-- <li>on applique enfin un certain nombre d'heuristiques locales --> +<!-- permettant de diminuer encore la longueur de la tournée. --> +<!-- </ol> --> +<!-- </p> --> + +<!-- <p> --> +<!-- Pour chacune des trois phases, on peut trouver plusieurs --> +<!-- alternatives crédibles. --> +<!-- <ol> --> +<!-- <li><a name="phase-1">la recherche d'une tournée sur un petit nombre de ville peut --> +<!-- être ainsi :</a> --> +<!-- <ol type="a"> --> +<!-- <li>on se restreint à une tournée de départ sur une seule --> +<!-- ville,</li> --> +<!-- <li>ou bien on part d'une tournée sur --> +<!-- l'<a href="https://en.wikipedia.org/wiki/Convex_hull">enveloppe --> +<!-- convexe</a> de l'ensemble des villes; --> +<!-- </ol> --> +<!-- </li><br> --> +<!-- <li><a name="phase-2">l'incorporation peut se faire systématiquement d'une des manières suivantes :</a> --> +<!-- <ol type="a"> --> +<!-- <li><span style="font-style:italic">insertion d'une ville aléatoire</span> : on choisit une --> +<!-- ville non encore présente sur la tournée de manière --> +<!-- quelconque, on incorpore cette ville à la tournée partielle de --> +<!-- manière à réduire le plus possible la distance totale --> +<!-- parcourue pour la nouvelle tournée;</li> --> +<!-- <li><span style="font-style:italic">insertion de la ville la plus proche</span> : on choisit une --> +<!-- (souvent la) ville dont la distance minimale aux villes de la --> +<!-- tournée partielle est minimale et on incorpore cette ville à --> +<!-- la tournée partielle de manière à réduire le plus possible la --> +<!-- distance totale parcourue pour la nouvelle tournée;</li> --> +<!-- <li><span style="font-style:italic">insertion de la ville la plus lointaine</span> : on choisit une --> +<!-- (souvent la) ville dont la distance minimale aux villes de la --> +<!-- tournée partielle est maximale et on incorpore cette ville à --> +<!-- la tournée partielle de manière à réduire le plus possible la --> +<!-- distance totale parcourue pour la nouvelle tournée;</li> --> +<!-- </ol> --> +<!-- </li> --> +<!-- <br> --> +<!-- <li><a name="phase-3">plusieurs algorithme d'optimisation sont mis à votre --> +<!-- disposition :</a> --> +<!-- <ol type="a"> --> +<!-- <li>la méthode de <span style="font-style:italic">repositionnement de noeud</span> : --> +<!-- <ol> --> +<!-- <li>on sélectionne un trajet A-B-C (les liaisons entre les villes A et B et B et C étant directes) tel qu'il existe un trajet direct entre A et C;</li> --> +<!-- <li>retire la ville B de la tournée;</li> --> +<!-- <li>on cherche à insérer la ville B dans la tournée de manière à minimiser la longueur totale de la tournée.</li> --> +<!-- </ol> --> +<!-- On conserve la nouvelle tournée si sa longueur totale est plus courte que l'ancienne tournée. --> +<!-- </li> --> +<!-- <br> --> +<!-- <li>la méthode de <span style="font-style:italic">l'inversion --> +<!-- locale</span> consiste : --> +<!-- <p> --> +<!-- Supposons que notre tournée se décompose comme suit : --> +<!-- <ol> --> +<!-- <li>une liaison directe entre les ville A et B;</li> --> +<!-- <li>une liaison indirecte entre les villes B et C;</li> --> +<!-- <li>une liaison directe entre les ville C et D.</li> --> +<!-- </ol> --> +<!-- </p> --> +<!-- <p>la méthode de <span style="font-style:italic">l'inversion --> +<!-- locale</span> sur ce trajet consiste à prendre en --> +<!-- considération le chemin suivant (dans la mesure où il --> +<!-- existe des liaisons directes entre A et C et B et D) --> +<!-- <ol> --> +<!-- <li>une liaison directe entre les ville A et C;</li> --> +<!-- <li>une liaison indirecte entre les villes C et B (dont --> +<!-- l'existence est garanti par le fait que les chemins sont --> +<!-- inversibles);</li> --> +<!-- <li>une liaison directe entre les ville B et D.</li> --> +<!-- </ol> --> +<!-- </p> --> +<!-- <p> --> +<!-- On remplace l'ancien trajet par le nouveau si la distance --> +<!-- totale parcourue est plus courte. Cette inversion --> +<!-- est <b>locale</b> dans le sens où elle n'intervient que --> +<!-- sur la partie de la tournée située entre A et D --> +<!-- </p> --> +<!-- On ne --> +<!-- conserve le nouveau chemin que si il est localement meilleur --> +<!-- que l'ancien. --> +<!-- </li> --> +<!-- </ol> --> +<!-- </li> --> +<!-- </ol> --> +<!-- <p> --> +<!-- <hr> --> + +<!-- <h3>Travail à effectuer</h3> --> + +<!-- Vous devrez produire une bibliothèque implantant les différents algorithmes definis ci-dessus. --> +<!-- Vous serez évalués, en particulier, sur les critères suivants : --> +<!-- <ul> --> +<!-- <li> la <b>qualité</b> de vos interfaces et de votre documentation; --> +<!-- <li> la <b>pertinance</b> des structures de données employées; --> +<!-- <li> la <b>modularité</b> de votre code: éviter autant que possible les répétitions de code (y compris entre les différentes phases du projet);</li> --> +<!-- <li> la <b>présence</b> de tests et une analyse critique des résultats obtenus. </li> --> +<!-- </ul> --> + +<!-- Vous devrez également produire, pour chaque phase, un programme principal fournissant une recherche de tournée efficace avec les contraintes fixées. --> + +<!-- <\!-- Pour chaque phase, vous devez impérativement : -\-> --> +<!-- <\!-- <ol> -\-> --> +<!-- <\!-- <li value="1"> Proposer une structure de données <b>pertinente</b> -\-> --> +<!-- <\!-- pour les information sur le problème (le format fourni en entrée n'est pas forcément adapté à votre problème).</li> -\-> --> +<!-- <\!-- <li> Fournir un algorithme et un code de recherche de tournée efficace.</li> -\-> --> +<!-- <\!-- </ol> -\-> --> + +<!-- <hr> --> + +<!-- <h3>Phase 1: graphe complet</h3> --> +<!-- Lors de cette phase, toutes les villes seront deux à deux reliées directement. --> + +<!-- Votre programme devra prendre deux noms de fichiers en argument : --> +<!-- <ol> --> +<!-- <li> le premier fichier contiendra des informations relative au paramétrage de votre programme (cf <a href="#params">paramétrage</a>);</li> --> +<!-- <li> le second fichier contiendra les informations utiles sur les villes (cf <a href="#format-entree">format d'entrée</a>). --> +<!-- </ol> --> + +<!-- il devra (dans le temps autorisé qui sera de l'ordre de quelques secondes), trouver une tournée et l'afficher sur la sortie standard (cf <a href="#format-sortie">format de sortie</a>) --> + +<!-- <h4><a name="params">paramétrage :</a></h4> --> + +<!-- le format du fichier de paramétres sera le suivant : --> +<!-- <ul> --> +<!-- <\!-- <li>une ligne contenant un entier exprimant le temps en seconde alloué à votre programme pour s'executer</li> -\-> --> +<!-- <li>une ligne contenant un mot (soit "ONE" soit "HULL") --> +<!-- décrivant le type de recherche souhaitée pour la première --> +<!-- phase. "ONE" désignera la recherche initiale d'une ville unique --> +<!-- et "HULL" désignera la recherche initiale à l'aide de --> +<!-- l'enveloppe convexe. (<a href="#phase-1">infos</a>)</li> --> +<!-- <li>une ligne contenant un mot (soit "RANDOM", soit "NEAREST" soit "FARTHEST") décrivant le type de recherche souhaitée pour la complétion de la tournée. "RANDOM" désignera la méthode de d'incorporation aléatoire, "NEAREST" l'insertion de la ville la plus proche, et "FARTHEST" l'insertion de la ville la plus lointaine (<a href="#phase-2">infos</a>)</li> --> +<!-- <li>une ligne contenant un mots (soit "REPOSITIONNEMENT" soit "INVERSION") décrivant le type d'optimisation souhaitée. "REPOSITIONNEMENT" désignera la méthode de repositionnement et "INVERSION" la méthode d'inversion locales (<a href="#phase-3">infos</a>)</li> --> +<!-- </ul> --> + +<!-- <h4><a name="format-entree">format d'entrée</a> :</h4> --> +<!-- <ul> --> +<!-- <li>Une première ligne contenant un unique entier <tt>n</tt>.</li> --> +<!-- <li> <tt>n</tt> lignes comprenant chacune la description d'une ville au format : --> +<!-- <div style="margin-left: 80px;"> <nom de la ville> <longitude > < lattitude></div> --> +<!-- les noms sont des chaînes de caractères, les coordonnées sont des flottant.</li> --> +<!-- </ul> --> + + + +<!-- <h4><a name="format-sortie">format de sortie :</a></h4> --> +<!-- Votre code devra écrire sur la sortie standard de votre programme le --> +<!-- parcours trouvé au format suivant: --> +<!-- <div style="margin-left: 80px;"> --> +<!-- <distance> : <ville_1> ... <ville_k> <ville_1></div> --> +<!-- où <distance> est la distance totale parcourue sur la tournée et le reste est la description de la tournée. --> + + +<!-- <hr> --> + +<!-- <h3>Phase 2 : graphes non orientés connexes</h3> --> +<!-- Pour cette phase votre progamme devra travailler sur un graphe où certaines routes seront fermées (inaccessible). On garantira que le graphe des villes reste connexe et symétrique. --> + +<!-- Votre travail devra reprendre le travail de la partie 1 en prenant ces contraintes. --> + +<!-- <h4><a name="format-entree-2">format d'entrée</a> :</h4> --> +<!-- <ul> --> +<!-- <li>Une première ligne contenant un unique entier <tt>n</tt>.</li> --> +<!-- <li> <tt>n</tt> lignes comprenant chacune la description d'une ville au format : --> +<!-- <div style="margin-left: 80px;"> <nom de la ville> <longitude > < lattitude></div> --> +<!-- les noms sont des chaîes de caractères, les coordonnées sont des flottant.</li> --> +<!-- <li><tt>n</tt> lignes décrivant les routes. Chaque ligne sera au format : --> +<!-- <div><départ> : <arrivée_1> ... <arrivée_k></div> --> +<!-- Chaque ville apparaîtra exactement une fois comme ville de départ. --> +<!-- </ul> --> + + +<hr> + +<h3>Merci pour ce sujet...</h3> Vous pouvez remercier (comme moi) +M. Mouilleron à qui je n'ai servi que de rédacteur final et qui a corrigé de la plupart des pheauthes. + + +</div></body></html> \ No newline at end of file diff --git a/sujet_files/urbain_style.html b/sujet_files/urbain_style.html new file mode 100644 index 0000000000000000000000000000000000000000..7d97a2e8eb840d231d5cc8a6437c777c4607ad9a --- /dev/null +++ b/sujet_files/urbain_style.html @@ -0,0 +1,9 @@ +<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> +<html><head> +<title>404 Not Found</title> +</head><body> +<h1>Not Found</h1> +<p>The requested URL /~forest/IPF/PROJET/urbain_style.css was not found on this server.</p> +<hr> +<address>Apache/2.2.16 (Debian) Server at web4.ensiie.fr Port 80</address> +</body></html>