JALLAT_kruskal4.ml 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. type 'a poids = Poids of 'a | Infini;;
  2. let g_ex = [|[1;3];[0;2;3;4];[1;4];[0;1;4;5];[1;2;3;5;6];[3;4;6];[4;5]|] ;;
  3. let w_ex = [|[|Infini;Poids 7;Infini;Poids 5;Infini;Infini;Infini|];
  4. [|Poids 7;Infini;Poids 8;Poids 9;Poids 7;Infini;Infini|];
  5. [|Infini;Poids 8;Infini;Infini;Poids 5;Infini;Infini|];
  6. [|Poids 5;Poids 9;Infini;Infini;Poids 15;Poids 6;Infini|];
  7. [|Infini;Poids 7;Poids 5;Poids 15;Infini;Poids 8;Poids 9|];
  8. [|Infini;Infini;Infini;Poids 6;Poids 8;Infini;Poids 11|];
  9. [|Infini;Infini;Infini;Infini;Poids 9;Poids 11;Infini|]
  10. |] ;;
  11. (*Schema classique de tri par insertion, version recursif*)
  12. (*Bien penser que les éléments de la liste et x sont des couples, représentant les arretes*)
  13. let rec insertion_liste_triee (w: int poids array array) (l: 'a list) (x : 'a) : 'a list
  14. = match l with
  15. | [] -> [x]
  16. | (t1,t2)::q -> if w.(x).(t1) <= w.(x).(t2) then x::l else (t1,t2)::(insertion_liste_triee w q x)
  17. ;;
  18. let liste_triee_arrete w =
  19. let n = Array.length w and l = ref [] in
  20. for i=0 to n-1 do
  21. for j=i+1 to n-1 do
  22. (*si l'arrete existe, alors seulement on l'insere, on va pas chercher à insérer des arretes qui n'existe pas*)
  23. if w.(i).(j) <> Infini then l := insertion_liste_triee w !l (i,j)
  24. done
  25. done;
  26. !l
  27. ;;
  28. liste_triee_arrete w_ex;;
  29. (*Sert à remettre toutes les composantes connexes dans le tableau représentant les composantes connexes*)
  30. (*Est donc utilisé dès que l'on rajoute une arrête qui ne crée pas de cycle*)
  31. let maj_composantes compo i j =
  32. let n = Array.length compo and ci = compo.(i) and cj = compo.(j) in
  33. for k=0 to n-1 do
  34. if compo.(k) = cj then compo.(k) <- ci
  35. done
  36. ;;
  37. (*Recursive terminale, qui va checker si ça crée un cycle, puis ajouter l'arrete sinon*)
  38. let rec kruskal1_aux compo liste_triee acc = match liste_triee with
  39. (*Si la liste est vide, on a fini, on renvoie l'acc, structure de récursive terminale*)
  40. | [] -> acc
  41. (*Si la liste n'est pas vide, on va regarder si l'arrete crée un cycle*)
  42. (*Si elle crée un cycle, on passe à l'arrete suivante*)
  43. (*Sinon, on ajoute l'arrete à l'acc, et on met à jour les composantes connexes*)
  44. (*On rappelle la fonction avec la liste_triee sans l'arrete ajoutée, et l'acc avec l'arrete ajoutée*)
  45. |(t1,t2)::q -> if compo.(x) = compo.(y) then
  46. begin
  47. kruskal1_aux compo q acc
  48. end
  49. else
  50. begin
  51. maj_composantes compo x y;
  52. kruskal1_aux compo q ((t1,t2)::acc)
  53. end
  54. ;;
  55. (*Fonction chapeau, qui va tout d'abord créer un tableau des composantes connexes, que j'ai nommé compo*)
  56. (*cette petite function ajoute chaque point à sa propre composante connexe*)
  57. (*puis ont ajoute récursivement les arrêtes, tout en vérifiant qu'elles ne créent pas de cycle*)
  58. (*Travail effectué par kruskal1_aux*)
  59. let kruskal1 (w: int poids array array) : (int * int) list =
  60. let n = Array.length w and compo = Array.init n (fun i -> i) in
  61. let liste_triee = liste_triee_arrete w in
  62. kruskal1_aux compo liste_triee []
  63. ;;