Polytech’Lille — GIS 3 — Calcul Numérique Le Problème de la Coupe Maximale La principale difficulté consiste à accepter d’entrer dans le sujet, qui relève davantage de l’informatique théorique que de la thématique GIS. C’est un sujet expérimental : je ne l’ai pas fait moi-même. On utilise des méthodes d’algèbre linéaire numérique sur des matrices exactes et l’expérience prouve que les algorithmes numériques classiques n’ont pas été prévus pour cela. J’aimerais bien voir l’algorithme complet programmé. Et voir ce qu’il donne en pratique. Ce serait bien de lancer l’algorithme sur une famille d’exemples et de mesurer l’erreur par rapport à la solution optimale obtenue séparément par l’algorithme exponentiel naïf. Ce serait bien aussi de voir le comportement en pratique de l’algorithme de décomposition en valeurs singulières sur des matrices d’adjacence de graphes. Le projet peut comporter une implantation de l’algorithme de SVD comme dans le sujet principal. Se reporter à ce sujet pour les détails mais utiliser impérativement la subroutine LAPACK spécialisée DBDSQR parce que la méthode fondée sur DSYEV ne marche pas sur des matrices d’adjacence de graphes, qui sont souvent de rang très inférieur au rang maximal. Table des matières 1 Énoncé 2 2 Premières formulations 2 3 Considérations sur la complexité 2 4 La décomposition en valeurs singulières 3 5 Formulations approchées 4 6 La borne sur l’erreur 6.1 Preuves . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 6 7 L’algorithme 7.1 Complexité . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 9 A Un exemple complet 9 B Relation avec la conjecture P ̸= NP 15 Le document qui suit est fortement inspiré de [2, pages 22-24], avec quelques corrections mineures et quelques variantes dans l’énoncé des bornes lorsque je ne comprenais pas le raisonnement. La présentation de la SVD doit beaucoup à [4, Lectures 4-5]. La section B a considérablement bénéficié de discussions avec M.-É. Voge et S. Tison. 1 1 Énoncé Le problème de la coupe de valeur maximale consiste à partitionner l’ensemble S des n sommets d’un graphe orienté en deux sous-ensembles S1 et S2 = S \ S1 de façon à maximiser la valeur de la coupe, c’est-à-dire le nombre d’arcs allant de S1 vers S2 . Exemple. Voici un exemple de coupe de valeur maximale d’un graphe à n = 5 sommets. Les sommets de l’ensemble S1 = {1, 2, 4} sont grisés. Les sommets de l’ensemble S2 = {3, 5} sont blancs. La valeur de la coupe, c’est-à-dire le nombre d’arcs de S1 vers S2 , est égale à 5. 1 3 4 2 5 2 Premières formulations Soit A la matrice d’adjacence du graphe. À chaque sommet 1 ≤ i ≤ n, on associe la T variable indicatrice ( ) ξi , valant 1 si i ∈ S1 et 0 sinon. On cherche donc un vecteur x = ξ1 ξ2 · · · ξn qui maximise la valeur de la coupe, c’est-à-dire le nombre ∑ ξi (1 − ξj ) aij . (1) 1≤i,j≤n En effet, on a ξi (1 − ξj ) aij = 1 si, et seulement si, i ∈ S1 , j ∈ S2 et il existe un arc de i vers j. En notant 1 le vecteur dont toutes les coordonnées valent 1, le problème à résoudre (maximiser (1)) peut se reformuler matriciellement en maximiser xT A (1 − x) (ξi ∈ {0, 1}) . (2) 3 Considérations sur la complexité La taille de la donnée est représentée par la variable n (le nombre de sommets). Le nombre d’arcs est majoré par n2 . On s’intéresse à la complexité en temps, dans le pire des cas. Cette complexité est donc une fonction f (n) qui compte des opérations élémentaires (non précisées). La complexité est dite polynomiale si f (n) est un polynôme en n. Les exposants ne doivent donc pas dépendre de n. Il existe un algorithme naïf de complexité exponentielle : il consiste à énumérer les 2n coupes possibles et en extraire une qui soit de valeur maximale. Le problème de la coupe maximale est NP-dur. Par conséquent, si on connaissait un algorithme polynomial de résolution du problème de la coupe maximale, la conjecture P ̸= NP serait résolue. Voir la section B, page 15. 2 L’idée, c’est que la SVD (décomposition en valeurs singulières) peut être utilisée pour calculer une solution approchée du problème de la coupe maximale avec une complexité polynomiale. Quand on explique la SVD à quelqu’un au détour d’un couloir, on explique que « c’est une factorisation de matrice qui permet de trouver la matrice singulière la plus proche d’une matrice A donnée ». Un peu plus précisément, la SVD va nous permettre de calculer des matrices Ak (1 ≤ k ≤ n) qui sont toutes des approximations de la matrice d’adjacence A, parce qu’elles vérifient (8), page 4 (voir [4, Theorem 5.8, page 35]). Très informellement (c’est l’idée bien qu’elle soit un peu fausse, énoncée comme ça), en travaillant sur Ak plutôt que sur A, l’exposant n de l’algorithme naïf va se transformer en exposant k. Par conséquent, pour k fixé, on va obtenir un algorithme de complexité polynomiale en n. 4 La décomposition en valeurs singulières Le texte qui suit est fortement inspiré de [4, Lectures 4, 5]. On se restreint au cas d’une matrice réelle carrée A de dimension n × n (dans notre cas, A sera la matrice d’adjacence du graphe). Voici l’idée dans le cas d’une matrice A de dimension 2 × 2. L’ensemble des vecteurs de longueur 1 peut être assimilé à un cercle C. L’ensemble des vecteurs A v tels que v ∈ C est une ellipse (pour un dessin, voir [4, Figure 4.1, page 26]). Cette ellipse a deux demi-axes principaux σ1 u1 et σ2 u2 où u1 et u2 sont deux vecteurs orthogonaux de dimension n de longueur 1 et σ1 ≥ σ2 ≥ 0 sont les longueurs des demi-axes. Les réels σi sont les valeurs singulières de A. Les vecteurs u1 , u2 sont appelés vecteurs singuliers gauches. Il existe deux vecteurs v1 , v2 ∈ C (orthogonaux) tels que A vi = σi ui . Ces deux vecteurs sont appelés vecteurs singuliers droits. Notons ( ) σ1 0 Σ = , 0 σ2 ( ) u1 u2 , U = ( ) v1 v2 . V = On obtient alors la décomposition en valeurs singulières de A AV = U Σ A = U ΣV T (3) La décomposition en valeurs singulières (3) peut aussi s’écrire A = An , où Ak = k ∑ i=1 3 σi ui viT . (4) Voir [4, Theorem 5.7, page 35]. Plusieurs théorèmes lient la norme deux et la norme de Frobenius de A à ses valeurs singulières. On rappelle que ∥A∥2 = ∥A∥F = max ∥A v∥2 , v t.q. ∥v∥2 =1 √∑ a2ij . On a les relations suivantes [4, Theorem 5.3, page 34] : ∥A∥2 = σ1 , √ ∥A∥F = σ12 + σ22 + · · · + σn2 . (5) (6) La relation (5) paraphrase la façon dont on a présenté la SVD. L’inégalité suivante donne une intuition sur la manière dont ces bornes vont pouvoir être utilisées ∥A∥F ≤ n (parce que aij = 0 ou aij = 1) (7) Si on suppose les k premières valeurs singulières non nulles, les sommes partielles Ak sont les meilleures approximations possibles de A par une matrice de rang k. Plus précisément, on a pour tout k < n ∥A − Ak ∥2 = inf rang(B)≤k ∥A − B∥2 = σk+1 (8) Voir [4, Theorem 5.8, page 35]. 5 Formulations approchées On considère une décomposition en valeurs singulières (3) de la matrice d’adjacence A du graphe. On fixe un entier k ≤ n et on effectue une première approximation du problème initial (2) par le problème suivant, où Ak est définie dans (4) : maximiser xT Ak (1 − x) (ξi ∈ {0, 1}) . (9) On effectue même une seconde approximation du problème initial en remplaçant Ak par Ãk définie par Ãk = k ∑ σi ũi ṽiT , (10) i=1 où ũi et ṽi sont les vecteurs obtenus en approximant les coordonnées des vecteurs ui et vi par le multiple entier le plus proche de 1 · n k2 On obtient le problème : maximiser xT Ãk (1 − x) (ξi ∈ {0, 1}) . 4 (11) Exemple (suite). La matrice d’adjacence 0 1 1 0 0 1 A= 1 0 0 0 0 1 0 1 0 Pour k = 1, on a en appliquant (4), 0 0 A1 = σ1 u1 v1T ≃ 0 0 0 0.296 0.375 0 0.375 0.078 est 0 0 1 0 0 0 1 0 1 0 . 0.827 1.045 0 1.045 0.218 0 0.592 0 0.749 0 0 0 0.749 0 0.0156 . On remarque que les matrices Ak (k < n) ne sont pas des matrices d’adjacence. Leurs coordonnées sont des réels de signe quelconque. Dans l’algorithme de la section 7, on évite de former explicitement les matrices Ak et Ãk en considérant directement les vecteurs ui , vi , ũi , ṽi . Pour k = 1, on est donc amené à considérer 0.484 0 0.612 0.280 σ1 ≃ 2.189 , u1 = 0 , v1 ≃ 0.780 . 0.612 0 0.128 0.559 Les coordonnées des vecteurs ui et vi sont des réels. La dernière approximation (10) consiste à les approximer par des rationnels, multiples de 1/5 : 2 0 5 3 1 5 5 , ṽ1 = 4 . 0 ũ1 = 3 5 0 5 1 5 3 5 6 La borne sur l’erreur L’algorithme de la section 7 résout le problème (11) : il retourne un vecteur x, représentant une coupe, qui maximise (11). D’après les propositions 1 et 2, la valeur de cette coupe diffère de la valeur maximale des coupes d’une quantité inférieure ou égale à : 3 3 n2 n2 √ + · k k+1 5 Remarque. Imaginons un algorithme qui tire une coupe aléatoirement. Quelle erreur ferait-il dans le pire des cas ? Il retournerait une coupe de valeur nulle alors que la coupe maximale est de valeur inférieure ou égale à n2 · 4 En effet, la valeur maximale des coupes d’un graphe à n sommets correspond à deux ensembles S1 et S2 ayant même nombre de sommets (donc de cardinal n/2) et tels qu’il existe un arc de chaque sommet de S1 vers chaque sommet de S2 . On voit donc que l’algorithme de la section 7 ne commence à être intéressant que pour des valeurs de k ≥ 15. 6.1 Preuves Proposition 1 Pour tout vecteur x (ξi ∈ {0, 1}) n2 |xT Ak (1 − x) − xT A (1 − x)| ≤ √ · k+1 Preuve Comme les vecteurs √ x et 1−x ne contiennent que des zéros et des uns, leur longueur est inférieure ou égale à n. Par définition de la norme deux de la matrice A, on a donc √ ∥(A − Ak ) (1 − x)∥2 ≤ n ∥A − Ak ∥2 . Parce que xT (A − Ak ) (1 − x) est le produit scalaire de xT avec le vecteur (A − Ak ) (1 − x), on a (inégalité de Cauchy-Schwarz [4, Lecture 3, page 21]) |xT (A − Ak ) (1 − x)| ≤ n ∥A − Ak ∥2 . (12) De plus, 2 2 (k + 1) σk+1 ≤ σ12 + · · · + σk+1 ≤ ∥A∥2F ≤ n2 . La première inégalité est évidente. La deuxième découle de (6) et la troisième de (7). Par conséquent n σk+1 ≤ √ · k+1 En utilisant (12) et (8), on conclut la preuve de la proposition. □ Les lemmes élémentaires ci-dessous permettent d’alléger la preuve de la proposition 2. Lemme 1 Si |a|, |b| ≤ M et |a − a′ |, |b − b′ | ≤ δ ≤ M alors |a b − a′ b′ | ≤ 3 M δ. Preuve En effet, |a b − a′ b′ | = |a (b − b′ ) + b′ (a − a′ )| ≤ |a| × |b − b′ | + (|b| + | − b + b′ |) × |a − a′ | ≤ 3 M δ . □ 6 Lemme 2 Soit a un vecteur de coordonnées α1 , α2 , . . . , αn et de longueur 1. Alors √ |α1 + α2 + · · · + αn | ≤ n. Preuve La formule suivante est vraie génériquement : n (α12 + α22 + ··· + αn2 ) = (α1 + α2 + · · · + αn ) + 2 n ∑ n ∑ (αi − αj )2 . (13) i=1 j=i+1 Comme a est de longueur 1 et que la double somme est positive ou nulle, on voit que n ≥ (α1 + α2 + · · · + αn )2 , ce qui conclut la preuve du lemme. □ Proposition 2 Si un vecteur x est solution du problème (11) alors 3 3 n2 |x Ãk (1 − x) − x Ak (1 − x)| ≤ · k T T Preuve On peut réécrire |xT Ãk (1 − x) − xT Ak (1 − x)| en k k k ∑ ∑ ∑ T T T T T T T σi x ũi ṽi (1 − x) − σi x ui vi (1 − x) = σi (x ũi ṽi (1 − x) − x ui vi (1 − x)) . i=1 i=1 i=1 √ Chaque produit scalaire xT ui ≤ n d’après le lemme 2, parce que ui est de longueur 1 et que le produit par xT revient à calculer une √ somme partielle des coordonnées de ui . De même, T chaque produit scalaire vi (1 − x) ≤ n. Comme chaque produit scalaire xT ũi est lui-aussi une somme partielle des coordonnées de ũi et que les coordonnées de ces vecteurs diffèrent de celles des vecteurs ui d’au plus 1/(n k 2 ), on a n 1 |xT ũi − xT ui | ≤ = 2· 2 nk k T T La même borne s’applique à |ṽi (1 − x) − vi (1 − x)|. √ Le lemme 1 peut alors s’appliquer en prenant M = n et δ = 1/k 2 et on a, pour tout 1 ≤ i ≤ k, √ 3 n T T T |x ũi ṽi (1 − x) − x ui vi (1 − x)| ≤ · k2 Par conséquent, |x Ãk (1 − x) − x Ak (1 − x)| ≤ k σ1 T T 3 √ 3 n 3 n2 ≤ · k2 k Pour la première inégalité, on a majoré toutes les valeurs singulières par σ1 . Pour la seconde, on a utilisé (6) et (7). □ 7 7 L’algorithme Dans cette section, on note n0 le nombre de sommets du graphe. Le symbole n désigne le nombre de sommets considérés jusqu’ici. Bien sûr, on fait varier n de 1 à n0 de sorte qu’à la fin de l’algorithme, les notations sont rentrées dans le rang (si j’ose dire). Dans cet algorithme, l’indice k est une constante. L’algorithme que nous allons établir sera polynomial en n mais exponentiel en k. À tout vecteur x, de dimension n, on associe une matrice W (x) de dimension k × 2 définie comme suit. Les vecteurs ũi et ṽi ont été précalculés une fois pour toutes, jusqu’à la dimension n0 , par une décomposition en valeurs singulières. On ne forme pas explicitement la matrice Ãk . xT ũ1 ṽ1T (1 − x) xT ũ2 ṽ T (1 − x) 2 W (x) = .. . .. . . xT ũk ṽkT (1 − x) L’algorithme fait varier n de 1 à n0 . À chaque itération, il construit un nouveau dictionnaire 1 Dn à partir du dictionnaire précédent Dn−1 . Ces dictionnaires contiennent des couples ⟨W (x), x⟩. Les clés des couples sont les matrices W (x). Il se peut très bien que deux vecteurs x ̸= x′ définissent la même matrice W (x) = W (x′ ). Dans ce cas, le dictionnaire ne mémorise qu’un seul des deux couples. C’est un point clé (si j’ose dire) de l’algorithme, puisque c’est lui qui va assurer la complexité polynomiale. Enfin, on remarque que les clés sont des matrices de nombres rationnels : les tests d’égalité entre clés sont exacts. Le premier dictionnaire D0 contient un unique couple constitué d’un vecteur x de dimension 0 et de la matrice nulle de dimension k × 2. Plaçons-nous à l’étape n et construisons Dn à partir de Dn−1 . Pour chaque couple ⟨W (x), x⟩ de Dn−1 , on enregistre (au plus) deux couples dans Dn en prolongeant les n − 1 coordonnées déjà fixées de x par ξn = 1 ou par ξn = 0. Dans chaque cas, la nouvelle matrice W (x) s’obtient par une mise-à-jour élémentaire de l’ancienne : si ξn = 1, il suffit d’ajouter à la première colonne de W le vecteur formé des n-ièmes coordonnées des vecteurs ũ1 , ũ2 , . . . , ũk ; si ξn = 0, il suffit d’ajouter à la seconde colonne de W le vecteur formé des n-ièmes coordonnées des vecteurs ṽ1T , ṽ2T , . . . , ṽkT . À la fin de l’algorithme, on énumère tous les couples du dictionnaire et on extrait la solution x du problème (11) par un calcul de maximum naïf. 1. Un dictionnaire au sens des structures de données [1, Partie 3, page 191]. Ceux qui ne connaissent pas peuvent assimiler un dictionnaire à une liste. 8 7.1 Complexité Par un raisonnement √ très proche de celui tenu dans la preuve de la proposition 2, on T remarque que x ui ≤ n et donc que xT ũi ≤ √ √ n 1 = n+ n + 2 = b. 2 nk k Le produit scalaire xT ũi est une somme de multiples entiers de 1/(n k 2 ). Il est donc lui-aussi un multiple entier de 1/(n k 2 ). Dans l’intervalle [−b, b] il existe au plus 3 p = (2 b + 1) n k 2 = 2 n 2 k 2 + n (k 2 + 2) multiples entiers de 1/(n k 2 ). Les matrices W (x) ne peuvent donc prendre que p2 k ∈ Θ(n3 k ) valeurs distinctes. La taille du dictionnaire et donc la complexité de l’algorithme sont alors majorés par une fonction polynomiale en n mais exponentielle en k. Remarque. Les bornes sur l’erreur commencent à être intéressantes pour k ≥ 15. Sachant que n ≥ k, dans le premier cas intéressant, la taille du dictionnaire est de l’ordre de 450 n45 clés, ce qui rend cet algorithme inutile en pratique, bien qu’intéressant théoriquement. Il faut bien sûr de se méfier de ce type de remarque. En d’autres temps, on a considéré que la multiplication d’entiers par FFT était un algorithme impraticable. La technologie a évolué et c’est aujourd’hui un algorithme courant. Enfin, les bornes sur l’erreur concernent le pire des cas. En pratique, l’algorithme se comporte peut-être beaucoup mieux que cela. A Un exemple complet La matrice de l’énoncé. > restart; > with(LinearAlgebra): > A := <<0 | 1 | 1 | 0 > <0 | 0 | 1 | 0 > <1 | 0 | 0 | 1 > <0 | 0 | 1 | 0 > <0 | 1 | 0 | 0 | | | | | 0>, 1>, 0>, 1>, 0>>; [0 [ [0 [ A := [1 [ [0 [ [0 1 1 0 0 1 0 0 0 1 0 1 0 1 0 0 9 0] ] 1] ] 0] ] 1] ] 0] On fixe n. > n := RowDimension (A); n := 5 On calcule la SVD de A. > U, Sigma, Vt := SingularValues (A, output = ['U', 'S', 'Vt']): > 'Sigma' = Sigma; [2.18890105931673 ] [ ] [1.41421356237310 ] [ ] Sigma = [1.41421356237309 ] [ ] [0.456850251747857] [ ] [ 0. ] On fixe k. > k := 1; k := 1 On calcule la matrice Ak . > Ak := Matrix(n,n): > for i from 1 to k do > Ak := Ak + Sigma[i]*Column(U,i).Row(Vt,i) > end do: > Ak; [0. [ [0. [ [0. [ [0. [ [0. , , , , , 0.296396101212393 , 0.827326835353988 , 0. , 0.592792202424786] ] 0.374574312188794 , 1.04554472558998 , 0. , 0.749148624377588] ] 0. , 0. , 0. , 0.] ] 0.374574312188794 , 1.04554472558998 , 0. , 0.749148624377588] ] 0.0781782109764007 , 0.218217890235992 , 0. , 0.156356421952802] La fonction qui arrondit au multiple entier le plus proche de 1/(n k 2 ). Dans une implantation FORTRAN, il vaut peut-être mieux stocker des entiers plutôt que des rationnels, en multipliant tous ces nombres par n k 2 . 10 > rnd := r -> round (r*n*k**2) / (n*k**2); 2 round(r n k ) rnd := r -> ------------2 n k Les colonnes des matrices suivantes sont les vecteurs ũi et ṽiT . > Utilde := map (rnd, U); [2/5 [ [3/5 [ Utilde := [ 0 [ [3/5 [ [1/5 0 3/5 -3/5 0 -2/5 1/5 -1 0 0 0 -2/5 1/5 0 3/5 4/5 0 ] ] -4/5] ] 0 ] ] 4/5 ] ] 0 ] > Vttilde := map (rnd, Vt); [ 0 [ [-4/5 [ Vttilde := [ 0 [ [ 0 [ [4/5 1/5 4/5 0 0 0 -4/5 4/5 0 0 2/5 -3/5 0 0 0 -4/5 3/5 ] ] 0 ] ] -2/5] ] 3/5 ] ] 0 ] La fonction qui calcule une approximation de la valeur d’une coupe x à partir de la matrice W . > valeur := proc (W) > local i; > return add (W[i,1]*Sigma[i]*W[i,2], i = 1 .. k) > end proc; La fonction qui met-à-jour W après qu’on a fixé xn à 0 ou à 1. 11 > W_update := proc (W, x, n) > local i; > if x[n] = 1 then > for i from 1 to k do > W[i,1] := W[i,1] + Utilde[n,i] > end do > else > for i from 1 to k do > W[i,2] := W[i,2] + Vttilde[i,n] > end do > end if > end proc; Pour tout n, le dictionnaire Dn est donné par deux listes : LWn , qui contient la n-ième liste de matrices W ; Lxn , qui contient n-ième liste de vecteurs x. Bien sûr, pour tout i, LWn (i) est la matrice W associée à Lxn (i). Le test basé sur select sert à éviter de stocker dans LWn deux matrices W identiques. > LW[0] := [ Matrix (k,2) ]; LW[0] := [[0 0]] > Lx[0] := [ Vector[column] (n) ]; [0] [ ] [0] [ ] Lx[0] := [[0]] [ ] [0] [ ] [0] 12 > n0 := n: > for n from 1 to n0 do > LW[n] := []: > Lx[n] := []; > for i from 1 to nops (LW[n-1]) do > W0 := Copy (LW[n-1][i]); > x0 := Copy (Lx[n-1][i]); > x0[n] := 0; > W_update (W0, x0, n); > W1 := Copy (LW[n-1][i]); > x1 := Copy (Lx[n-1][i]); > x1[n] := 1; > W_update (W1, x1, n); > if select (LinearAlgebra:-Equal, LW[n], W0) = [] then > LW[n] := [ op(LW[n]), W0 ]; > Lx[n] := [ op(Lx[n]), x0 ] > end if; > if select (LinearAlgebra:-Equal, LW[n], W1) = [] then > LW[n] := [ op(LW[n]), W1 ]; > Lx[n] := [ op(Lx[n]), x1 ] > end if; > end do > end do: Le résultat final. > n := n0: > LW[n]; [[0 8/5], [1/5 1], [3/5 8/5], [4/5 1], [0 [3/5 4/5], [4/5 1/5], [3/5 7/5], [4/5 [7/5 4/5], [3/5 3/5], [4/5 0], [6/5 [2/5 8/5], [3/5 1], [1 [3/5 1/5], [1 [8/5 7/5], [9/5 [9/5 0]] 4/5], [6/5 4/5], [1 8/5], [6/5 1/5], [1 3/5], [6/5 4/5], [1/5 4/5], [6/5 3/5], [7/5 1], [2/5 1/5], 7/5], 0], 4/5], 7/5], [6/5 4/5], 0], [8/5 3/5], Les 2n matrices ont été mémorisées. On n’a donc pas construit deux matrices W identiques. > nops (LW[n]); 32 13 Les valeurs de toutes ces coupes calculées avec W . Ce sont donc des approximations des vraies valeurs des coupes ! > map (valeur, LW[n]); [0., 0.437780211863347, 2.10134501694407, 1.75112084745339, 0., 0.0875560423726694, 1.05067250847203, 0.350224169490678, 1.83867688982606, 1.40089667796271, 3.67735377965211, 2.45156918643474, 0.788004381354024, 0., 1.57600876270805, 0., 1.40089667796271, 1.31334063559004, 3.50224169490678, 2.62668127118008, 0.700448338981355, 0.262668127118008, 1.75112084745339, 0.525336254236016, 3.06446148304343, 2.10134501694407, 4.90313837286948, 3.15201752541610, 1.31334063559004, 0., 2.10134501694407, 0.] Recherche du maximum > best := 1: > for i from 2 to nops (LW[n]) do > if valeur(LW[n][i]) > valeur (LW[n][best]) then > best := i > end if > end do: Son indice > best; 27 La matrice W correspondante. > LW[n][best]; [8/5 7/5] La coupe correspondante. > x := Lx[n][best]; [1] [ ] [1] [ ] x := [0] [ ] [1] [ ] [0] 14 La coupe mais présentée sous la forme d’une partition de l’ensemble des sommets. Sur cet exemple, on a bien calculé une coupe de valeur maximale. Le pire des cas ne se produit donc pas systématiquement ! > S1 = { seq (i*x[i], i = 1 .. n) } minus { 0 }, > S2 = { seq (i*(1-x[i]), i = 1 .. n) } minus { 0 }; S1 = {1, 2, 4}, S2 = {3, 5} B Relation avec la conjecture P ̸= NP L’une des conjectures les plus célèbres de l’informatique théorique s’écrit P ̸= NP. L’ensemble P est l’ensemble des problèmes de décision pouvant être résolus par des algorithmes ayant une complexité en temps, polynomiale en la taille de la donnée. L’ensemble NP est l’ensemble des problèmes de décision pouvant être résolus par des « algorithmes non déterministes » ayant une complexité en temps, polynomiale en la taille de la donnée. Problèmes de décision ou d’optimisation. Un problème de décision est un problème pour lequel la réponse est vrai ou faux. Il existe un célèbre problème de décision appelé MAX CUT [3, page 97]. Son énoncé est : Étant donné un graphe G et une borne w, existe-t-il une coupe de G de valeur supérieure ou égale à w ? Dans le projet de calcul numérique, nous nous intéressons au problème d’optimisation de la coupe maximale (souvent appelé MAX CUT aussi, pour ne rien arranger) : Étant donné un graphe G, déterminer une coupe de G de valeur maximale. On reviendra sur les relations entre ces deux problèmes. Le problème de décision MAX CUT appartient à NP. Un problème de décision appartient à NP s’il existe un algorithme paramétré par un certificat, qui vérifie le certificat avec une complexité en temps polynomiale en la taille de la donnée. Dans le cas du problème de décision MAX CUT, le certificat pourrait être une coupe x. L’algorithme de vérification consisterait alors simplement à calculer la valeur de la coupe x et à vérifier qu’elle est supérieure ou égale à la borne w. Toujours dans notre cas, la donnée est une représentation du graphe G (ce pourrait être la matrice d’adjacence du graphe) ainsi que la borne w. La taille de la donnée peut être représentée par le nombre n de sommets du graphe. L’algorithme de vérification a manifestement une complexité en temps polynomiale en n. Le sigle NP signifie Nondeterministic Polynomial. Il correspond à une autre définition possible de l’ensemble NP, fondée sur la notion d’algorithme non déterministe. Sur l’exemple du problème de décision MAX CUT, un algorithme non déterministe consisterait à construire une coupe x aléatoire, puis à vérifier que la valeur de x est bien supérieure ou égale à w. 15 L’algorithme déterministe naïf. L’algorithme déterministe naïf (aussi bien pour le problème de décision que pour le problème d’optimisation) consiste à énumérer les 2n coupes possibles et à calculer le maximum des valeurs qu’elles définissent. Il a une complexité en temps exponentielle en n. La fonction 2n croît beaucoup plus vite que n’importe quelle fonction polynomiale. Dire qu’il existe un algorithme déterministe de complexité polynomiale pour résoudre le problème de la coupe maximale c’est dire qu’on peut faire beaucoup mieux qu’explorer tous les cas, par exemple qu’il suffit d’explorer une infime fraction (tendant vers zéro quand n tend vers l’infini) de l’ensemble des coupes, pour trouver une coupe de valeur maximale. Le problème de décision MAX CUT est NP-complet. problème de décision MAX CUT est NP-complet : On peut montrer que le 1. il est NP ; 2. tout autre problème de décision NP peut se réduire, avec une complexité en temps polynomiale, en le problème de décision MAX CUT. Le verbe se réduire a ici le sens de se recoder, ou se reformuler. Par exemple, le problème du calcul des racines d’un polynôme peut se réduire en le problème du calcul des valeurs propres d’une matrice (la matrice compagnon du polynôme). Un autre exemple de réduction est donné, dans le cadre de l’algorithme du simplexe, par la méthode des deux phases. L’appartenance à NP est facile. La complétude de MAX CUT est montrée dans [3]. La NP-complétude du problème de décision MAX CUT a la conséquence suivante : s’il existe un algorithme déterministe de complexité polynomiale pour résoudre le problème de décision MAX CUT, alors il existe un algorithme déterministe de complexité polynomiale pour résoudre n’importe quel problème de décision NP et . . . P = NP. Or l’ensemble NP contient un grand nombre de problèmes très naturels de décision, similaires à MAX CUT dans le sens où le meilleur algorithme déterministe connu ne fait pas beaucoup mieux qu’explorer tous les cas, dont le nombre est exponentiel en la taille de la donnée. Supposer P = NP, c’est donc imaginer que tous ces problèmes très naturels de décision contiennent une structure cachée qui permet, quand on la connaît, de n’explorer qu’une infime partie des possibilités. Les chercheurs qui se sont penchés sur la question n’y croient pas et pensent que P ̸= NP. Mais l’histoire des sciences enseigne qu’il vaut mieux être prudent. Le problème d’optimisation MAX CUT est NP-dur. Supposons qu’on connaisse un algorithme déterministe qui résolve le problème d’optimisation MAX CUT avec une complexité en temps polynomiale en la taille de la donnée. On pourrait se servir de cet algorithme pour résoudre le problème de décision MAX CUT et on aurait P = NP. Un tel problème (pas nécessairement un problème de décision, d’ailleurs) est dit NP-dur. Le projet de calcul numérique flirte avec la conjecture : il consiste à programmer un algorithme déterministe de complexité polynomiale en la taille de la donnée, qui résout le problème d’optimisation MAX CUT . . . à un chouïa près ! 16 Références [1] Thomas Cormen, Charles Leiserson, Ronald Rivest, and Clifford Stein. Introduction à l’algorithmique. Dunod, Paris, 2ème edition, 2002. [2] Venkatesam Guruswami. Singular value decomposition. https://www.cs.cmu.edu/ ~venkatg/teaching/CStheory-infoage/book-chapter-4.pdf, 2012. [3] Richard M. Karp. Reducibility Among Combinatorial Problems. In Complexity of Computer Computations, pages 85–103, 1972. [4] Lloyd Nicholas Trefethen and David Bau. Numerical Linear Algebra. SIAM, 1997. 17