From f387949bbf84ddb038296f4220da5630da653cda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Wikle=20DUBARD?= <loic97429@gmail.com> Date: Wed, 1 Jan 2020 23:17:54 +0100 Subject: [PATCH] =?UTF-8?q?phase2=20finie=20manque=20juste=20d=C3=A9bit=20?= =?UTF-8?q?maximal=20+=20tests=20+=20rapport?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Makefile | 20 ++++++-- src/graphe.mli | 1 - src/main_phase1.ml | 32 +++++++++++++ src/main_phase2.ml | 41 ++++++++++++++++ src/phase1.ml | 12 +++-- src/phase2.ml | 114 +++++++++++++++++++++++++++++++++------------ src/set.mli | 0 src/test_phase1.ml | 2 + src/test_phase2.ml | 16 +++++++ 9 files changed, 198 insertions(+), 40 deletions(-) delete mode 100644 src/graphe.mli create mode 100644 src/main_phase1.ml create mode 100644 src/main_phase2.ml delete mode 100644 src/set.mli create mode 100644 src/test_phase1.ml create mode 100644 src/test_phase2.ml diff --git a/Makefile b/Makefile index 1767d5b..4c7a5f7 100644 --- a/Makefile +++ b/Makefile @@ -7,13 +7,23 @@ # $? liste des dépendances plus récentes que la cible # $* Le nom du fichier sans suffixe -all: phase1 phase2 +main: phase1 phase2 -phase1: src/phase1.ml - ocamlc $^ -o build/phase1.out +all: main tests -phase2: src/phase2.ml - ocamlc $^ -o build/phase2.out +tests: test_phase1.out test_phase2.out + +phase1: src/phase1.ml src/main_phase1.ml + (cd src ; ocamlc -o ../build/$@ phase1.ml main_phase1.ml) + +phase2: src/phase2.ml src/main_phase2.ml + (cd src ; ocamlc -o ../build/$@ phase2.ml main_phase2.ml) + +test_phase1.out: src/phase1.ml src/test_phase1.ml + (cd src ; ocamlc -o ../build/$@ phase1.ml test_phase1.ml) + +test_phase2.out: src/phase1.ml src/test_phase1.ml + (cd src ; ocamlc -o ../build/$@ phase2.ml test_phase2.ml) clean: rm -rf *.cmi *.cmo diff --git a/src/graphe.mli b/src/graphe.mli deleted file mode 100644 index e178204..0000000 --- a/src/graphe.mli +++ /dev/null @@ -1 +0,0 @@ -module type graphe = Map.make() \ No newline at end of file diff --git a/src/main_phase1.ml b/src/main_phase1.ml new file mode 100644 index 0000000..fe4799a --- /dev/null +++ b/src/main_phase1.ml @@ -0,0 +1,32 @@ +open Phase1 + +(* + * @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 "output : \n" + +(* +* @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 = int_of_string (input_line file) + +(* affichage final *) +let _ = + let f l = Printf.printf "%s\n" (String.concat " " l) + in + let graphe_test = make_graphe n file + in + let liste_chemins = chemins source graphe_test + in + let liste_result = plus_courts_chemins source puits liste_chemins + in + List.map f liste_result \ No newline at end of file diff --git a/src/main_phase2.ml b/src/main_phase2.ml new file mode 100644 index 0000000..11ef291 --- /dev/null +++ b/src/main_phase2.ml @@ -0,0 +1,41 @@ +open Phase2 + +(* + * @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 "output : \n" + +(* +* @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 = int_of_string (input_line file) + +let g = make_graphe n file +let lc = filtre source puits (chemins source g) +let gcr = flot_maximal lc g +let ls = liste_sommets_graphe g +let result = reverse_graphe g gcr ls + +(* affichage final *) +let rec affiche_result r liste_sommet = match liste_sommet with + | [] -> [] + | e::m -> + let arrete = Graphe.find e r + in + let f k v a = Printf.printf "%s %s %i\n" e k v ; 0 + in + Arreteliste.fold f arrete 0 |> ignore; + affiche_result r m + +let ls_result = liste_sommets_graphe result +let _ = Printf.printf "%i\n" (nb_arrete result) +let _ = affiche_result result ls_result \ No newline at end of file diff --git a/src/phase1.ml b/src/phase1.ml index 1b9d475..bc2620c 100644 --- a/src/phase1.ml +++ b/src/phase1.ml @@ -9,6 +9,7 @@ module Graphe = Map.Make(String) module Clesliste = Set.Make(String) +(*** (* * @ensures : vérification du nombre d'agruments * @raises : erreur si le nombre d'aguments est différent de 1 @@ -27,20 +28,20 @@ let file = open_in Sys.argv.(1) let source = input_line file let puits = input_line file let n = input_line file - +***) (* * [make_graphe n] * @ensures : retourne le "graphe" à n arrètes correspondant au fichier ouvert dans le channel file *) -let rec make_graphe n = +let rec make_graphe n file = 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 (Clesliste.add b (Clesliste.empty)) Graphe.empty) else - let g = make_graphe (n-1) + let g = make_graphe (n-1) file in if (Graphe.mem a g) then let l = Graphe.find a g in @@ -116,16 +117,17 @@ let plus_courts_chemins s p c = in remplissage liste distances minimum - +(*** (* test du dénombrement de l'ensemble des chemins possibles *) let _ = Printf.printf "Chemins les plus courts : \n" ; let f l = Printf.printf "%s\n" (String.concat " " l) in - let graphe_test = make_graphe (int_of_string n) + let graphe_test = make_graphe (int_of_string n) file in let liste_chemins = chemins source graphe_test in let liste_result = plus_courts_chemins source puits liste_chemins in List.map f liste_result +***) \ No newline at end of file diff --git a/src/phase2.ml b/src/phase2.ml index 99f9e2e..215fb85 100644 --- a/src/phase2.ml +++ b/src/phase2.ml @@ -10,44 +10,24 @@ module Graphe = Map.Make(String) module Arreteliste = 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 - - (* * [make_graphe n] * @ensures : retourne le "graphe" à n arrètes correspondant au fichier ouvert dans le channel file *) -let rec make_graphe n = +let rec make_graphe n file = let line = input_line file in let l = String.split_on_char ' ' line in match l with | [a ; b ; c] -> if n = 1 - then (Graphe.add a (Arreteliste.add b c Arreteliste.empty) Graphe.empty) + then (Graphe.add a (Arreteliste.add b (int_of_string c) Arreteliste.empty) Graphe.empty) else - let g = make_graphe (n-1) + let g = make_graphe (n-1) file in if (Graphe.mem a g) then let l = Graphe.find a g in let f = Graphe.remove a g in - Graphe.add a (Arreteliste.add b c l) f - else Graphe.add a (Arreteliste.add b c Arreteliste.empty) g + Graphe.add a (Arreteliste.add b (int_of_string c) l) f + else Graphe.add a (Arreteliste.add b (int_of_string c) Arreteliste.empty) g | _ -> failwith("erreur dans le graphe !") (* @@ -107,9 +87,8 @@ let capacite c g = in let liste = liste_capacite c in - let f b = min liste (List.nth liste 0) - in - List.map f c + min liste (List.nth liste 0) + (* [graphe_capacite_residuelles c n g] graphe des capacité résiduelles de g aprèes avoir retirer des arretes du chemin c le nombre n *) let rec graphe_capacites_residuelles c n g = match c with @@ -123,4 +102,81 @@ let rec graphe_capacites_residuelles c n g = match c with let new_e1 = Arreteliste.add e2 (t-n) (Arreteliste.remove e2 s) in let new_g = Graphe.add e1 new_e1 (Graphe.remove e1 g) - in graphe_capacites_residuelles (e2::l) n new_g \ No newline at end of file + in graphe_capacites_residuelles (e2::l) n new_g + + +(* [indice_chemin_max lc g i j a] l'indice du chemin de capacité maximum de la liste de chemins lc + * @requires: i,j=0 au premier appel (désigne un indice de lc) + *) +let rec indice_chemin_max lc g i j a = match lc with + | [] -> j + | c::l -> + let toto = capacite c g in + if toto > a + then indice_chemin_max l g (i+1) i toto + else indice_chemin_max l g (i+1) j a + +(* [remove_from_liste i l] enleve le ieme élèment de la liste l + *) +let rec remove_from_list i l = match l with + | [] -> [] + | e::m -> if i = 0 + then m else e::(remove_from_list (i-1) m) + +(* + * [liste_sommets_graphe g] + * @ensures : la listes des clés du graphe g + *) + let liste_sommets_graphe g = + let f k v a = k::a + in + Graphe.fold f g [] + +(* [reverse_graphe g gcr l] donne le flot final à partir du graphe initial, du graphe des capacités résiduelles final et de la liste des sommets *) +let rec reverse_graphe g gcr l = match l with + | [] -> Graphe.empty + | e::m -> + let v1 = Graphe.find e g + in + let v2 = Graphe.find e gcr + in + let f k v a = let w = Arreteliste.find k v2 in + if v > w then Arreteliste.add k (v - w) a else a + in + let new_arrete = Arreteliste.fold f v1 (Arreteliste.empty) + in + Graphe.add e new_arrete (reverse_graphe g gcr m) + +(* [flot_maximal lc g] grâce à la liste de chemins lc donne le graphe des capacités résiduelles final à partir du graphe de départ g *) +let rec flot_maximal lc g = + match lc with + | [] -> g + | c::l -> + let c = List.nth lc 0 + in + let cap_c = capacite c g + in + let i = indice_chemin_max lc g 0 0 cap_c + in + let chemin_max = List.nth lc i + in + let cap_chemin_max = capacite chemin_max g + in + let new_lc = remove_from_list i lc + in + let graphe_cap_res = graphe_capacites_residuelles chemin_max cap_chemin_max g + in + flot_maximal new_lc graphe_cap_res + +(* + * [debit_maximal g l a] donne le débit maximal entre la source et le puits avec l la liste des sommets de g + *) +let rec debit_maximal g l a = match l with + | [] -> a + | e::m -> failwith("TODO") + +(* [nb_arrete g] donne le nombre d'arretes élémentaire du graphe g *) +let rec nb_arrete g = + let f k v a = a + (List.length (liste_sommets v)) + in + Graphe.fold f g 0 \ No newline at end of file diff --git a/src/set.mli b/src/set.mli deleted file mode 100644 index e69de29..0000000 diff --git a/src/test_phase1.ml b/src/test_phase1.ml new file mode 100644 index 0000000..19e1d62 --- /dev/null +++ b/src/test_phase1.ml @@ -0,0 +1,2 @@ +open Phase1 + diff --git a/src/test_phase2.ml b/src/test_phase2.ml new file mode 100644 index 0000000..5f2328d --- /dev/null +++ b/src/test_phase2.ml @@ -0,0 +1,16 @@ +open Phase2 + +let g = make_graphe (int_of_string n) file +let lc = chemins source g +let lc_s_puits = filtre source puits lc +let c = List.nth lc_s_puits 0 +let test = capacite c g +let i = indice_chemin_max lc_s_puits g 0 0 test + +let _ = print_int test + +let _ = print_int i + +let _ = List.map (fun l -> Printf.printf "%s\n" (String.concat " " l)) lc_s_puits + +let test_cap_res = graphe_capacites_residuelles c test g -- GitLab