Corrigé X-ENS 2026 Informatique A MP — Partie III (III.1 à III.8) : Quantification de produit : k-moyennes et distances approchées
Sujet officiel du concours X-ENS, session 2026, épreuve Informatique A MP. Corrigé rédigé par Ibrahim Alame.
Sujet officiel (PDF, site du concours)
Énoncé
La base db contient vecteurs de ; dist2 p1 p2 calcule en le carré de leur distance euclidienne. Pour les -moyennes, centroids est une matrice de centroïdes et centroid_of.(i) est l'indice du centroïde le plus proche de db.(i).
type vector = float array (* vecteur *)
type matrix = vector array (* tableau de vecteurs *)
type square = float array array (* matrice carrée n x n *)
val dist2 : vector -> vector -> float
(* fonctions fournies à partir de III.4 *)
val vector_sum : vector -> vector -> vector (* somme *)
val matrix_sum : square -> square -> square (* somme *)
val vector_div : vector -> float -> vector (* division *)
(* fournie à partir de III.7 *)
val submatrix : matrix -> int -> matrix list
III.1. Écrire compute_all_dist2 : matrix -> square (matrice des ), avec Array.init_matrix.
III.2. Complexité de la recherche du plus proche voisin d'un vecteur query parmi les vecteurs (sans code).
III.3. Écrire pick : matrix -> matrix -> int array -> unit : pick db centroids centroid_of met à jour en place centroid_of.
III.4. Écrire update : int -> matrix -> int array -> matrix -> unit : update k db centroid_of centroids recalcule en place les centroïdes.
III.5. Votre code peut-il mettre à jour moins de centroïdes ?
III.6. Écrire kmeans : matrix -> int -> int -> int array * matrix : kmeans db k n_iter fait n_iter itérations et renvoie (centroid_of, centroids), les centroïdes étant initialisés aux premiers vecteurs.
Chaque vecteur est coupé en paquets consécutifs de taille ( divise ) ; les -moyennes sur le -ième paquet de tous les vecteurs donnent , indice du centroïde du -ième paquet de . submatrix db m renvoie la liste des matrices des paquets.
III.7. Écrire approx_dist : matrix -> int -> int -> int -> square : approx_dist db k n_iter m calcule la matrice des , où est le carré de la distance entre les centroïdes et du -ième paquet.
III.8. On pré-calcule les dans un dictionnaire (les et les centroïdes étant connus). (a) Complexité de ce pré-calcul en fonction de , , . (b) Borner le nombre de valeurs distinctes des en fonction de et . (c) Complexité, après pré-calcul, de la recherche des plus proches voisins de db.(i) pour la distance approchée. (d) Même question pour un nouveau vecteur .
Corrigé
Pour les tests, dist2, vector_sum, matrix_sum, vector_div et submatrix ont été écrites selon leur spécification (OCaml 5.4, qui fournit Array.init_matrix).
III.1. Le coefficient est dist2 db.(i) db.(j) :
let compute_all_dist2 (db : matrix) : square =
let n = Array.length db in
Array.init_matrix n n (fun i j -> dist2 db.(i) db.(j))
Array.init_matrix appelle la fonction une fois par case : appels à dist2 en , soit . Sur , , , on obtient les lignes , , . On pourrait n'en calculer que la moitié par symétrie, sans changer l'ordre de grandeur.
III.2. Il faut, dans le cas général, calculer la distance de query à chacun des vecteurs (un vecteur non examiné pourrait être le plus proche), chaque calcul coûtant , en retenant le minimum courant en par vecteur : la complexité est . On compare les carrés des distances, qui sont rangés dans le même ordre que les distances (la racine est croissante). Si query est l'un des db.(i) et que la matrice de III.1 est déjà calculée, il suffit de parcourir sa ligne (en excluant ) : , mais après un pré-calcul en .
III.3. Pour chaque vecteur, on cherche le centroïde de carré de distance minimal (premier indice en cas d'égalité).
let pick (db : matrix) (centroids : matrix)
(centroid_of : int array) : unit =
let k = Array.length centroids in
Array.iteri (fun i p ->
let best = ref 0 and d_best = ref (dist2 p centroids.(0)) in
for j = 1 to k - 1 do
let dj = dist2 p centroids.(j) in
if dj < !d_best then begin best := j; d_best := dj end
done;
centroid_of.(i) <- !best)
db
Invariant de la boucle for : après le tour , !best est l'indice d'un centroïde le plus proche de parmi les centroïdes et !d_best son carré de distance. Complexité : appels à dist2 par vecteur, soit .
100 % gratuit
La suite du corrigé est sur Adloun
Le corrigé rédigé en entier, question par question, et le tuteur pour poser des questions sur ce sujet.
Voir le corrigé complet, gratuitementInscription gratuite en 30 secondes (e-mail, nom d'utilisateur, mot de passe, classe ou profil), sans carte bancaire : arrivée directe sur le corrigé.