Représentations de graphes
Contents
Représentations de graphes#
Graphe utilisé pour les exemples ci-dessous :
Remarque : les fonctions add_edge
et is_edge
ci-dessous marchent aussi sur un graphe orienté.
Matrice d’adjacence#
let g_mat = [|
[|0; 0; 0; 0; 0; 0; 1|];
[|0; 0; 1; 1; 1; 0; 0|];
[|0; 1; 0; 0; 1; 1; 0|];
[|0; 1; 0; 0; 1; 0; 0|];
[|0; 0; 1; 1; 0; 0; 0|];
[|0; 0; 1; 0; 1; 0; 0|];
[|1; 0; 0; 0; 0; 0; 0|];
|]
val g_mat : int array array =
[|[|0; 0; 0; 0; 0; 0; 1|]; [|0; 0; 1; 1; 1; 0; 0|];
[|0; 1; 0; 0; 1; 1; 0|]; [|0; 1; 0; 0; 1; 0; 0|];
[|0; 0; 1; 1; 0; 0; 0|]; [|0; 0; 1; 0; 1; 0; 0|];
[|1; 0; 0; 0; 0; 0; 0|]|]
let add_edge g u v = (* ajoute l'arête (u, v) dans un graphe g représenté par matrice d'adjacence *)
g.(u).(v) <- 1
val add_edge : int array array -> int -> int -> unit = <fun>
let is_edge g u v = (* teste si g contient l'arĂŞte (u, v) *)
g.(u).(v) = 1
let () = assert (is_edge g_mat 4 2 && not (is_edge g_mat 2 0))
val is_edge : int array array -> int -> int -> bool = <fun>
Liste d’adjacence#
let g_list = [|[6]; [2; 3; 4]; [1; 4; 5]; [1; 4]; [1; 2; 3; 5]; [4; 2]; [0]|]
val g_list : int list array =
[|[6]; [2; 3; 4]; [1; 4; 5]; [1; 4]; [1; 2; 3; 5]; [4; 2]; [0]|]
let add_edge g u v = (* ajoute l'arête (u, v) dans un graphe g représenté par liste d'adjacence *)
g.(u) <- v::g.(u)
val add_edge : 'a list array -> int -> 'a -> unit = <fun>
let is_edge g u v = (* teste si g contient l'arĂŞte (u, v) *)
List.mem v g.(u);;
let () = assert (is_edge g_list 4 2 && not (is_edge g_list 2 0))
val is_edge : 'a list array -> int -> 'a -> bool = <fun>
Dictionnaire d’adjacence#
Ici, on utilise un dictionnaire (par table de hachage) pour représenter le graphe. Chaque élément de la table de hachage sera un ensemble, obtenu avec le module Set
(utilisant un arbre binaire de recherche équilibré).
module S = Set.Make(Int) (* structure d'ensemble d'entiers *)
module S :
sig
type elt = Int.t
type t = Set.Make(Int).t
val empty : t
val is_empty : t -> bool
val mem : elt -> t -> bool
val add : elt -> t -> t
val singleton : elt -> t
val remove : elt -> t -> t
val union : t -> t -> t
val inter : t -> t -> t
val disjoint : t -> t -> bool
val diff : t -> t -> t
val compare : t -> t -> int
val equal : t -> t -> bool
val subset : t -> t -> bool
val iter : (elt -> unit) -> t -> unit
val map : (elt -> elt) -> t -> t
val fold : (elt -> 'a -> 'a) -> t -> 'a -> 'a
val for_all : (elt -> bool) -> t -> bool
val exists : (elt -> bool) -> t -> bool
val filter : (elt -> bool) -> t -> t
val filter_map : (elt -> elt option) -> t -> t
val partition : (elt -> bool) -> t -> t * t
val cardinal : t -> int
val elements : t -> elt list
val min_elt : t -> elt
val min_elt_opt : t -> elt option
val max_elt : t -> elt
val max_elt_opt : t -> elt option
val choose : t -> elt
val choose_opt : t -> elt option
val split : elt -> t -> t * bool * t
val find : elt -> t -> elt
val find_opt : elt -> t -> elt option
val find_first : (elt -> bool) -> t -> elt
val find_first_opt : (elt -> bool) -> t -> elt option
val find_last : (elt -> bool) -> t -> elt
val find_last_opt : (elt -> bool) -> t -> elt option
val of_list : elt list -> t
val to_seq_from : elt -> t -> elt Seq.t
val to_seq : t -> elt Seq.t
val to_rev_seq : t -> elt Seq.t
val add_seq : elt Seq.t -> t -> t
val of_seq : elt Seq.t -> t
end
let g_dict = Hashtbl.create 42;;
let () = for i = 0 to Array.length g_list - 1 do
Hashtbl.add g_dict i (S.of_list g_list.(i))
done
val g_dict : ('_weak1, '_weak2) Hashtbl.t = <abstr>
Hashtbl.create 42
permet de créer une table de hachage avec un tableau de taille initiale 42
. Lorsqu’on ajoute des associations à la table de hachage, la taille du tableau peut augmenter (pour éviter un trop grand nombre de collisions).
let is_edge g u v = (* teste si g contient l'arĂŞte (u, v) *)
Hashtbl.find g u
|> S.mem v
let () = assert (is_edge g_dict 3 1 && not (is_edge g_dict 2 0))
val is_edge : ('a, S.t) Hashtbl.t -> 'a -> S.elt -> bool = <fun>
let add_edge g u v = (* ajoute l'arĂŞte (u, v) Ă g *)
let s = Hashtbl.find g u in
Hashtbl.add g u (S.add v s)
val add_edge : ('a, S.t) Hashtbl.t -> 'a -> S.elt -> unit = <fun>
Module#
Type de module pour un graphe :
module type Graph = sig
type vertex
type t
val empty : int -> t
val n : t -> int
val is_edge : vertex -> vertex -> t -> bool
val add_edge : vertex -> vertex -> t -> unit
val del_edge : vertex -> vertex -> t -> unit
end
module type Graph =
sig
type vertex
type t
val empty : int -> t
val n : t -> int
val is_edge : vertex -> vertex -> t -> bool
val add_edge : vertex -> vertex -> t -> unit
val del_edge : vertex -> vertex -> t -> unit
end
module MatrixGraph : (Graph with type vertex := int) = struct
type vertex = int
type t = vertex array array
let empty n = Array.make_matrix n n 0
let n = Array.length
let is_edge i j m = m.(i).(j) <> 0
let add_edge i j m = m.(i).(j) <- 1
let del_edge i j m = m.(i).(j) <- 0
end
module MatrixGraph :
sig
type t
val empty : int -> t
val n : t -> int
val is_edge : int -> int -> t -> bool
val add_edge : int -> int -> t -> unit
val del_edge : int -> int -> t -> unit
end
Exemple d’utilisation :
let g = MatrixGraph.empty 4;; (* graphe Ă 4 sommets *)
let () = MatrixGraph.add_edge 0 1 g;; (* ajout d'une arĂŞte entre les sommets *)
MatrixGraph.is_edge 0 3 g;; (* false *)
let () = MatrixGraph.add_edge 0 3 g;;
MatrixGraph.is_edge 0 3 g;; (* true *)
val g : MatrixGraph.t = <abstr>
- : bool = false
- : bool = true