<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Algorithms on kenji.blog</title><link>http://kenji.blog/fr/tags/algorithms/</link><description>Recent content in Algorithms on kenji.blog</description><generator>Hugo -- gohugo.io</generator><language>fr</language><copyright>kenjinote</copyright><lastBuildDate>Sat, 12 Sep 2026 05:00:00 +0900</lastBuildDate><atom:link href="http://kenji.blog/fr/tags/algorithms/index.xml" rel="self" type="application/rss+xml"/><item><title>Algorithmes de graphes fréquents en programmation compétitive : Le guide complet</title><link>http://kenji.blog/fr/p/competitive-programming-graph-algorithms-guide/</link><pubDate>Sat, 12 Sep 2026 05:00:00 +0900</pubDate><guid>http://kenji.blog/fr/p/competitive-programming-graph-algorithms-guide/</guid><description>&lt;img src="http://kenji.blog/p/competitive-programming-graph-algorithms-guide/img/eyecatch.jpg" alt="Featured image of post Algorithmes de graphes fréquents en programmation compétitive : Le guide complet" />&lt;p>En programmation compétitive (CP), la théorie des graphes et ses algorithmes constituent l&amp;rsquo;un des thèmes les plus importants et incontournables. De nombreux problèmes posés lors de concours sur AtCoder, Codeforces ou TopCoder possèdent une structure de graphe en arrière-plan. Que ce soit pour trouver le chemin le plus court dans un réseau routier, minimiser les coûts de communication d&amp;rsquo;un réseau ou résoudre les dépendances entre tâches, ils constituent une arme puissante pour abstraire et résoudre des problèmes du monde réel.&lt;/p>
&lt;p>Dans cet article, nous couvrirons de manière exhaustive les principaux algorithmes de graphes fréquemment rencontrés en programmation compétitive (tri topologique, algorithme de Dijkstra, algorithme de Bellman-Ford, algorithme de Floyd-Warshall, algorithme de Kruskal, algorithme de Prim et décomposition en composantes fortement connexes). Nous aborderons leur contexte théorique, l&amp;rsquo;évaluation de leur complexité à l&amp;rsquo;aide de formules mathématiques, ainsi que des exemples d&amp;rsquo;implémentation hautement optimisés en C++ moderne (C++17/20). Il s&amp;rsquo;agit d&amp;rsquo;un véritable guide &amp;ldquo;complet&amp;rdquo; que nous vous proposons.&lt;/p>
&lt;hr>
&lt;h2 id="1-les-bases-et-les-contraintes-des-algorithmes-de-graphes">1. Les bases et les contraintes des algorithmes de graphes
&lt;/h2>&lt;p>Avant d&amp;rsquo;étudier les algorithmes, il est important de comprendre les contraintes générales et les ordres de grandeur de la complexité temporelle pour les problèmes de graphes en programmation compétitive. Un graphe est représenté par son nombre de sommets $V$ (Vertices) et son nombre d&amp;rsquo;arêtes $E$ (Edges).&lt;/p>
&lt;ul>
&lt;li>$O(V + E)$ : Complexité requise pour des problèmes où $V, E \le 10^5 \sim 10^6$. Cela correspond au parcours en profondeur (DFS) et au parcours en largeur (BFS).&lt;/li>
&lt;li>$O((V + E) \log V)$ : Fréquent pour des problèmes où $V, E \le 10^5 \sim 2 \cdot 10^5$. C&amp;rsquo;est la complexité de l&amp;rsquo;algorithme de Dijkstra ou de Prim lorsqu&amp;rsquo;une file de priorité est utilisée.&lt;/li>
&lt;li>$O(V^2)$ : Acceptable pour des graphes denses ($E \approx V^2$) où $V \le 2000 \sim 3000$.&lt;/li>
&lt;li>$O(V^3)$ : Pour des problèmes où $V \le 400 \sim 500$. L&amp;rsquo;algorithme de Floyd-Warshall en est un exemple représentatif.&lt;/li>
&lt;/ul>
&lt;p>En programmation compétitive, il est courant d&amp;rsquo;utiliser une &lt;strong>liste d&amp;rsquo;adjacence (Adjacency List)&lt;/strong> pour représenter un graphe. Comme la matrice d&amp;rsquo;adjacence consomme $O(V^2)$ en mémoire, elle entraînera un dépassement de la limite de mémoire (Memory Limit Exceeded) pour les problèmes comportant un grand nombre de sommets.&lt;/p>
&lt;hr>
&lt;h2 id="2-exploration-et-ordonnancement-des-graphes">2. Exploration et ordonnancement des graphes
&lt;/h2>&lt;h3 id="tri-topologique-topological-sort">Tri topologique (Topological Sort)
&lt;/h3>&lt;p>Le tri topologique est un algorithme qui aligne les sommets d&amp;rsquo;un graphe orienté acyclique (DAG : Directed Acyclic Graph) de sorte que chaque arête orientée aille d&amp;rsquo;un sommet précédent vers un sommet suivant. Il est utilisé pour résoudre les dépendances entre les tâches (par exemple : la tâche B ne peut commencer que lorsque la tâche A est terminée) ou pour déterminer l&amp;rsquo;ordre de calcul de la programmation dynamique (DP) sur un DAG.&lt;/p>
&lt;p>La complexité est de $O(V + E)$. Il existe deux implémentations : l&amp;rsquo;algorithme de Kahn (basé sur le parcours en largeur BFS en utilisant les degrés entrants) et celui basé sur le parcours en profondeur DFS avec post-ordre. Nous présenterons ici l&amp;rsquo;algorithme de Kahn, qui permet également de trouver facilement l&amp;rsquo;ordre topologique lexicographique minimal.&lt;/p>
&lt;div class="mermaid">graph LR
A["Tâche A"] --> B["Tâche B"]
A["Tâche A"] --> C["Tâche C"]
B["Tâche B"] --> D["Tâche D"]
C["Tâche C"] --> D["Tâche D"]
E["Tâche E"] --> C["Tâche C"]&lt;/div>
&lt;h4 id="exemple-dimplémentation-en-c-algorithme-de-kahn">Exemple d&amp;rsquo;implémentation en C++ (Algorithme de Kahn)
&lt;/h4>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;span class="lnt">31
&lt;/span>&lt;span class="lnt">32
&lt;/span>&lt;span class="lnt">33
&lt;/span>&lt;span class="lnt">34
&lt;/span>&lt;span class="lnt">35
&lt;/span>&lt;span class="lnt">36
&lt;/span>&lt;span class="lnt">37
&lt;/span>&lt;span class="lnt">38
&lt;/span>&lt;span class="lnt">39
&lt;/span>&lt;span class="lnt">40
&lt;/span>&lt;span class="lnt">41
&lt;/span>&lt;span class="lnt">42
&lt;/span>&lt;span class="lnt">43
&lt;/span>&lt;span class="lnt">44
&lt;/span>&lt;span class="lnt">45
&lt;/span>&lt;span class="lnt">46
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;iostream&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;vector&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;queue&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">using&lt;/span> &lt;span class="k">namespace&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// Fonction pour effectuer le tri topologique
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// Renvoie un tableau vide si un cycle existe
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">int&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">topological_sort&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span> &lt;span class="n">V&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="k">const&lt;/span> &lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">int&lt;/span>&lt;span class="o">&amp;gt;&amp;gt;&amp;amp;&lt;/span> &lt;span class="n">graph&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">int&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">in_degree&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">V&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Calcul des degrés entrants
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">for&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span> &lt;span class="n">u&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">u&lt;/span> &lt;span class="o">&amp;lt;&lt;/span> &lt;span class="n">V&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="o">++&lt;/span>&lt;span class="n">u&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span> &lt;span class="nl">v&lt;/span> &lt;span class="p">:&lt;/span> &lt;span class="n">graph&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">u&lt;/span>&lt;span class="p">])&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">in_degree&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">v&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="o">++&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Ajout des sommets de degré entrant 0 à la file (utiliser priority_queue&amp;lt;int, vector&amp;lt;int&amp;gt;, greater&amp;lt;int&amp;gt;&amp;gt; pour un ordre lexicographique minimal)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">queue&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">int&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">q&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="o">&amp;lt;&lt;/span> &lt;span class="n">V&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="o">++&lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">in_degree&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">q&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">push&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">int&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">res&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">while&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="o">!&lt;/span>&lt;span class="n">q&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">empty&lt;/span>&lt;span class="p">())&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">int&lt;/span> &lt;span class="n">u&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">q&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">front&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">q&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">pop&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">res&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">push_back&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">u&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Décrémenter le degré entrant des sommets adjacents
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">for&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span> &lt;span class="nl">v&lt;/span> &lt;span class="p">:&lt;/span> &lt;span class="n">graph&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">u&lt;/span>&lt;span class="p">])&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">in_degree&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">v&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="o">--&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">in_degree&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">v&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">q&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">push&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">v&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Vérifier si le graphe contient un cycle
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">res&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">size&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="o">!=&lt;/span> &lt;span class="n">V&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="p">{};&lt;/span> &lt;span class="c1">// Cycle présent
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">res&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;hr>
&lt;h2 id="3-problème-du-plus-court-chemin-à-source-unique-sssp--single-source-shortest-path">3. Problème du plus court chemin à source unique (SSSP : Single Source Shortest Path)
&lt;/h2>&lt;p>Il s&amp;rsquo;agit du problème consistant à trouver le chemin le plus court depuis un sommet source vers tous les autres sommets. L&amp;rsquo;algorithme applicable diffère selon que les poids des arêtes sont tous positifs ou s&amp;rsquo;il existe des poids négatifs.&lt;/p>
&lt;h3 id="algorithme-de-dijkstra">Algorithme de Dijkstra
&lt;/h3>&lt;p>L&amp;rsquo;algorithme de Dijkstra est un algorithme rapide de plus court chemin applicable lorsque &lt;strong>tous les poids des arêtes sont non négatifs&lt;/strong>. Il est basé sur une approche gloutonne : « figer le sommet pour lequel la distance la plus courte est actuellement connue, et mettre à jour (relâcher) la distance vers les sommets adjacents à partir de ce sommet ».&lt;/p>
&lt;h4 id="formule-de-relâchement-relaxation">Formule de relâchement (Relaxation)
&lt;/h4>&lt;p>Soit $s$ le sommet source, $d[u]$ la distance la plus courte jusqu&amp;rsquo;au sommet $u$, et $w(u, v)$ le poids de l&amp;rsquo;arête $(u, v)$.
La formule de mise à jour est la suivante :
&lt;/p>
$$ d[v] = \min(d[v], d[u] + w(u, v)) $$
&lt;p>En utilisant une file de priorité (&lt;code>std::priority_queue&lt;/code>), le sommet non visité avec la distance minimale peut être extrait en $O(\log V)$, donnant une complexité temporelle globale de $O((V + E) \log V)$. La complexité spatiale est de $O(V + E)$.&lt;/p>
&lt;div class="mermaid">graph TD
S["Source S(0)"] -- "2" --> A["Sommet A(2)"]
S["Source S(0)"] -- "5" --> B["Sommet B(5)"]
A["Sommet A(2)"] -- "1" --> B["Sommet B(3)"]
A["Sommet A(2)"] -- "4" --> C["Sommet C(6)"]
B["Sommet B(3)"] -- "1" --> C["Sommet C(4)"]&lt;/div>
&lt;p>Comme illustré ci-dessus, le coût pour aller directement de S à B est de 5, mais en passant par A, on peut l&amp;rsquo;atteindre avec un coût de 3. L&amp;rsquo;algorithme de Dijkstra effectue cette optimisation.&lt;/p>
&lt;h4 id="exemple-dimplémentation-en-c">Exemple d&amp;rsquo;implémentation en C++
&lt;/h4>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;span class="lnt">31
&lt;/span>&lt;span class="lnt">32
&lt;/span>&lt;span class="lnt">33
&lt;/span>&lt;span class="lnt">34
&lt;/span>&lt;span class="lnt">35
&lt;/span>&lt;span class="lnt">36
&lt;/span>&lt;span class="lnt">37
&lt;/span>&lt;span class="lnt">38
&lt;/span>&lt;span class="lnt">39
&lt;/span>&lt;span class="lnt">40
&lt;/span>&lt;span class="lnt">41
&lt;/span>&lt;span class="lnt">42
&lt;/span>&lt;span class="lnt">43
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;iostream&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;vector&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;queue&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">using&lt;/span> &lt;span class="k">namespace&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">const&lt;/span> &lt;span class="kt">long&lt;/span> &lt;span class="kt">long&lt;/span> &lt;span class="n">INF&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mf">1e18&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="c1">// Valeur suffisamment grande
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">struct&lt;/span> &lt;span class="nc">Edge&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">int&lt;/span> &lt;span class="n">to&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">long&lt;/span> &lt;span class="kt">long&lt;/span> &lt;span class="n">weight&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// Algorithme de Dijkstra
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// Renvoie un tableau des distances les plus courtes de la source s vers chaque sommet
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">long&lt;/span> &lt;span class="kt">long&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">dijkstra&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span> &lt;span class="n">V&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="k">const&lt;/span> &lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">Edge&lt;/span>&lt;span class="o">&amp;gt;&amp;gt;&amp;amp;&lt;/span> &lt;span class="n">graph&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="kt">int&lt;/span> &lt;span class="n">s&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">long&lt;/span> &lt;span class="kt">long&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">dist&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">V&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">INF&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">dist&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">s&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// File de priorité pour gérer {distance, sommet} (dans l&amp;#39;ordre croissant des distances)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">using&lt;/span> &lt;span class="n">P&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">pair&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">long&lt;/span> &lt;span class="kt">long&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="kt">int&lt;/span>&lt;span class="o">&amp;gt;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">priority_queue&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">P&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">P&lt;/span>&lt;span class="o">&amp;gt;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">greater&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">P&lt;/span>&lt;span class="o">&amp;gt;&amp;gt;&lt;/span> &lt;span class="n">pq&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">pq&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">push&lt;/span>&lt;span class="p">({&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">s&lt;/span>&lt;span class="p">});&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">while&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="o">!&lt;/span>&lt;span class="n">pq&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">empty&lt;/span>&lt;span class="p">())&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">auto&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="n">d&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">u&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">pq&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">top&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">pq&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">pop&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Ignorer si un chemin plus court a déjà été trouvé (suppression des informations obsolètes)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">dist&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">u&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">&amp;lt;&lt;/span> &lt;span class="n">d&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="k">continue&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Processus de relâchement
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">for&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="k">const&lt;/span> &lt;span class="k">auto&lt;/span>&lt;span class="o">&amp;amp;&lt;/span> &lt;span class="nl">edge&lt;/span> &lt;span class="p">:&lt;/span> &lt;span class="n">graph&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">u&lt;/span>&lt;span class="p">])&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">int&lt;/span> &lt;span class="n">v&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">edge&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">to&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">long&lt;/span> &lt;span class="kt">long&lt;/span> &lt;span class="n">cost&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">edge&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">weight&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">dist&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">v&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">dist&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">u&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="n">cost&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">dist&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">v&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">dist&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">u&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="n">cost&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">pq&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">push&lt;/span>&lt;span class="p">({&lt;/span>&lt;span class="n">dist&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">v&lt;/span>&lt;span class="p">],&lt;/span> &lt;span class="n">v&lt;/span>&lt;span class="p">});&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">dist&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>L&amp;rsquo;instruction &lt;code>if (dist[u] &amp;lt; d) continue;&lt;/code> est très importante. Dans l&amp;rsquo;algorithme de Dijkstra, le même sommet peut être inséré plusieurs fois dans la file, mais cette vérification permet d&amp;rsquo;élaguer les recherches inutiles.&lt;/p>
&lt;h3 id="algorithme-de-bellman-ford">Algorithme de Bellman-Ford
&lt;/h3>&lt;p>Si les poids des arêtes incluent des valeurs négatives, l&amp;rsquo;algorithme de Dijkstra ne peut pas déduire la bonne réponse. C&amp;rsquo;est là qu&amp;rsquo;intervient l&amp;rsquo;algorithme de Bellman-Ford. En répétant le processus de relâchement pour toutes les arêtes $V - 1$ fois, il calcule correctement le chemin le plus court même s&amp;rsquo;il y a des poids négatifs.&lt;/p>
&lt;p>Si une mise à jour se produit lors de la $V$-ème itération, cela signifie qu&amp;rsquo;il existe un &lt;strong>cycle négatif (Negative Cycle)&lt;/strong>. En programmation compétitive, le problème &amp;ldquo;Détecter un cycle négatif&amp;rdquo; est très fréquent, et l&amp;rsquo;algorithme de Bellman-Ford est excellent pour cela.&lt;/p>
&lt;p>La complexité temporelle est de $O(V \times E)$, ce qui est plus lent que l&amp;rsquo;algorithme de Dijkstra. Notez qu&amp;rsquo;il ne peut être appliqué que sous des contraintes telles que $V \le 2000, E \le 5000$.&lt;/p>
&lt;h4 id="exemple-dimplémentation-en-c-1">Exemple d&amp;rsquo;implémentation en C++
&lt;/h4>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;span class="lnt">31
&lt;/span>&lt;span class="lnt">32
&lt;/span>&lt;span class="lnt">33
&lt;/span>&lt;span class="lnt">34
&lt;/span>&lt;span class="lnt">35
&lt;/span>&lt;span class="lnt">36
&lt;/span>&lt;span class="lnt">37
&lt;/span>&lt;span class="lnt">38
&lt;/span>&lt;span class="lnt">39
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;iostream&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;vector&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">using&lt;/span> &lt;span class="k">namespace&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">const&lt;/span> &lt;span class="kt">long&lt;/span> &lt;span class="kt">long&lt;/span> &lt;span class="n">INF&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mf">1e18&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">struct&lt;/span> &lt;span class="nc">Edge&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">int&lt;/span> &lt;span class="n">from&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">int&lt;/span> &lt;span class="n">to&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">long&lt;/span> &lt;span class="kt">long&lt;/span> &lt;span class="n">weight&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// Algorithme de Bellman-Ford
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// Valeur de retour : {tableau des distances les plus courtes, booléen indiquant la présence d&amp;#39;un cycle négatif}
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="n">pair&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">long&lt;/span> &lt;span class="kt">long&lt;/span>&lt;span class="o">&amp;gt;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="kt">bool&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">bellman_ford&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span> &lt;span class="n">V&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="k">const&lt;/span> &lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">Edge&lt;/span>&lt;span class="o">&amp;gt;&amp;amp;&lt;/span> &lt;span class="n">edges&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="kt">int&lt;/span> &lt;span class="n">s&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">long&lt;/span> &lt;span class="kt">long&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">dist&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">V&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">INF&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">dist&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">s&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">bool&lt;/span> &lt;span class="n">negative_cycle&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nb">false&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Boucle exécutée V fois
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">for&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="o">&amp;lt;&lt;/span> &lt;span class="n">V&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="o">++&lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">bool&lt;/span> &lt;span class="n">updated&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nb">false&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="k">const&lt;/span> &lt;span class="k">auto&lt;/span>&lt;span class="o">&amp;amp;&lt;/span> &lt;span class="nl">edge&lt;/span> &lt;span class="p">:&lt;/span> &lt;span class="n">edges&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">dist&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">edge&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">from&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">!=&lt;/span> &lt;span class="n">INF&lt;/span> &lt;span class="o">&amp;amp;&amp;amp;&lt;/span> &lt;span class="n">dist&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">edge&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">to&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">dist&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">edge&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">from&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="n">edge&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">weight&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">dist&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">edge&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">to&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">dist&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">edge&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">from&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="n">edge&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">weight&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">updated&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nb">true&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Si une mise à jour survient à la V-ème itération, un cycle négatif existe
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">i&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="n">V&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">negative_cycle&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nb">true&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Arrêt anticipé s&amp;#39;il n&amp;#39;y a pas eu de mise à jour (optimisation)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="o">!&lt;/span>&lt;span class="n">updated&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="k">break&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="p">{&lt;/span>&lt;span class="n">dist&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">negative_cycle&lt;/span>&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;hr>
&lt;h2 id="4-problème-du-plus-court-chemin-entre-toutes-paires-de-sommets-apsp--all-pairs-shortest-path">4. Problème du plus court chemin entre toutes paires de sommets (APSP : All-Pairs Shortest Path)
&lt;/h2>&lt;h3 id="algorithme-de-floyd-warshall">Algorithme de Floyd-Warshall
&lt;/h3>&lt;p>Il s&amp;rsquo;agit d&amp;rsquo;un algorithme permettant de trouver la plus courte distance entre toutes les paires de sommets d&amp;rsquo;un graphe. Il est basé sur la programmation dynamique (DP). Son attrait réside dans le fait qu&amp;rsquo;il est très concis et extrêmement facile à implémenter.&lt;/p>
&lt;p>L&amp;rsquo;équation de transition d&amp;rsquo;état est la suivante. On choisit le plus court entre le chemin qui passe par le sommet $k$ et celui qui n&amp;rsquo;y passe pas :
&lt;/p>
$$ d[i][j] = \min(d[i][j], d[i][k] + d[k][j]) $$
&lt;p>Puisqu&amp;rsquo;il exécute une triple boucle, la complexité temporelle est de $O(V^3)$ et la complexité spatiale est de $O(V^2)$. Si le nombre de sommets est de $V \le 400$ environ, cela respectera la limite de temps d&amp;rsquo;exécution (généralement 2 secondes).&lt;/p>
&lt;h4 id="exemple-dimplémentation-en-c-2">Exemple d&amp;rsquo;implémentation en C++
&lt;/h4>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;iostream&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;vector&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;algorithm&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">using&lt;/span> &lt;span class="k">namespace&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">const&lt;/span> &lt;span class="kt">long&lt;/span> &lt;span class="kt">long&lt;/span> &lt;span class="n">INF&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mf">1e18&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// Algorithme de Floyd-Warshall
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// dist[i][j] est initialement le poids de l&amp;#39;arête de i vers j (INF s&amp;#39;il n&amp;#39;y a pas d&amp;#39;arête, 0 si i==j)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="kt">void&lt;/span> &lt;span class="nf">floyd_warshall&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span> &lt;span class="n">V&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">long&lt;/span> &lt;span class="kt">long&lt;/span>&lt;span class="o">&amp;gt;&amp;gt;&amp;amp;&lt;/span> &lt;span class="n">dist&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Sommet intermédiaire k
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">for&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span> &lt;span class="n">k&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">k&lt;/span> &lt;span class="o">&amp;lt;&lt;/span> &lt;span class="n">V&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="o">++&lt;/span>&lt;span class="n">k&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Sommet de départ i
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">for&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="o">&amp;lt;&lt;/span> &lt;span class="n">V&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="o">++&lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Sommet d&amp;#39;arrivée j
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">for&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span> &lt;span class="n">j&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">j&lt;/span> &lt;span class="o">&amp;lt;&lt;/span> &lt;span class="n">V&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="o">++&lt;/span>&lt;span class="n">j&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Vérifier la présence de INF pour éviter tout débordement
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">dist&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="p">][&lt;/span>&lt;span class="n">k&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">!=&lt;/span> &lt;span class="n">INF&lt;/span> &lt;span class="o">&amp;amp;&amp;amp;&lt;/span> &lt;span class="n">dist&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">k&lt;/span>&lt;span class="p">][&lt;/span>&lt;span class="n">j&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">!=&lt;/span> &lt;span class="n">INF&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">dist&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="p">][&lt;/span>&lt;span class="n">j&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">min&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">dist&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="p">][&lt;/span>&lt;span class="n">j&lt;/span>&lt;span class="p">],&lt;/span> &lt;span class="n">dist&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="p">][&lt;/span>&lt;span class="n">k&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="n">dist&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">k&lt;/span>&lt;span class="p">][&lt;/span>&lt;span class="n">j&lt;/span>&lt;span class="p">]);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>L&amp;rsquo;algorithme de Floyd-Warshall peut également détecter les cycles négatifs. Après la boucle, s&amp;rsquo;il existe au moins un sommet &lt;code>i&lt;/code> pour lequel &lt;code>dist[i][i] &amp;lt; 0&lt;/code>, alors le graphe contient un cycle négatif.&lt;/p>
&lt;hr>
&lt;h2 id="5-arbre-couvrant-de-poids-minimum-mst--minimum-spanning-tree">5. Arbre couvrant de poids minimum (MST : Minimum Spanning Tree)
&lt;/h2>&lt;p>Dans un graphe non orienté connexe, on appelle &lt;strong>arbre couvrant de poids minimum (MST)&lt;/strong> un arbre (sous-graphe sans cycle) reliant tous les sommets tel que la somme des poids de ses arêtes est minimale. Il est souvent demandé directement dans des problèmes de minimisation des coûts de construction de réseaux.&lt;/p>
&lt;h3 id="algorithme-de-kruskal">Algorithme de Kruskal
&lt;/h3>&lt;p>Il s&amp;rsquo;agit d&amp;rsquo;une approche gloutonne où toutes les arêtes sont triées par ordre croissant de poids, puis sélectionnées une par une sans former de cycle. La détection de cycle peut être traitée rapidement à l&amp;rsquo;aide d&amp;rsquo;une &lt;strong>structure de données d&amp;rsquo;ensembles disjoints (Union-Find, Disjoint Set)&lt;/strong>.&lt;/p>
&lt;p>La complexité temporelle est dominée par le tri des arêtes, atteignant $O(E \log E)$. C&amp;rsquo;est l&amp;rsquo;algorithme de construction de MST le plus fréquemment utilisé en programmation compétitive.&lt;/p>
&lt;div class="mermaid">graph TD
A["Sommet A"] -- "1 (Accepté)" --- B["Sommet B"]
B["Sommet B"] -- "2 (Accepté)" --- C["Sommet C"]
C["Sommet C"] -- "3 (Accepté)" --- D["Sommet D"]
A["Sommet A"] -- "4 (Rejeté : Cycle)" --- D["Sommet D"]&lt;/div>
&lt;h4 id="exemple-dimplémentation-en-c-3">Exemple d&amp;rsquo;implémentation en C++
&lt;/h4>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;span class="lnt">31
&lt;/span>&lt;span class="lnt">32
&lt;/span>&lt;span class="lnt">33
&lt;/span>&lt;span class="lnt">34
&lt;/span>&lt;span class="lnt">35
&lt;/span>&lt;span class="lnt">36
&lt;/span>&lt;span class="lnt">37
&lt;/span>&lt;span class="lnt">38
&lt;/span>&lt;span class="lnt">39
&lt;/span>&lt;span class="lnt">40
&lt;/span>&lt;span class="lnt">41
&lt;/span>&lt;span class="lnt">42
&lt;/span>&lt;span class="lnt">43
&lt;/span>&lt;span class="lnt">44
&lt;/span>&lt;span class="lnt">45
&lt;/span>&lt;span class="lnt">46
&lt;/span>&lt;span class="lnt">47
&lt;/span>&lt;span class="lnt">48
&lt;/span>&lt;span class="lnt">49
&lt;/span>&lt;span class="lnt">50
&lt;/span>&lt;span class="lnt">51
&lt;/span>&lt;span class="lnt">52
&lt;/span>&lt;span class="lnt">53
&lt;/span>&lt;span class="lnt">54
&lt;/span>&lt;span class="lnt">55
&lt;/span>&lt;span class="lnt">56
&lt;/span>&lt;span class="lnt">57
&lt;/span>&lt;span class="lnt">58
&lt;/span>&lt;span class="lnt">59
&lt;/span>&lt;span class="lnt">60
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;iostream&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;vector&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;algorithm&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">using&lt;/span> &lt;span class="k">namespace&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// Union-Find (Structure de données d&amp;#39;ensembles disjoints)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="k">struct&lt;/span> &lt;span class="nc">UnionFind&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">int&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">parent&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">rank&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">size&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">UnionFind&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span> &lt;span class="n">n&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="n">parent&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">n&lt;/span>&lt;span class="p">),&lt;/span> &lt;span class="n">rank&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">n&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">),&lt;/span> &lt;span class="n">size&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">n&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="o">&amp;lt;&lt;/span> &lt;span class="n">n&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">i&lt;/span>&lt;span class="o">++&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="n">parent&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">i&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">int&lt;/span> &lt;span class="nf">find&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span> &lt;span class="n">x&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">parent&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">x&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="n">x&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="k">return&lt;/span> &lt;span class="n">x&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Compression de chemin
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">return&lt;/span> &lt;span class="n">parent&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">x&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">find&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">parent&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">x&lt;/span>&lt;span class="p">]);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">bool&lt;/span> &lt;span class="nf">unite&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span> &lt;span class="n">x&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="kt">int&lt;/span> &lt;span class="n">y&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">int&lt;/span> &lt;span class="n">root_x&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">find&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">x&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">int&lt;/span> &lt;span class="n">root_y&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">find&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">y&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">root_x&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="n">root_y&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="k">return&lt;/span> &lt;span class="nb">false&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Fusion par rang
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">rank&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">root_x&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">&amp;lt;&lt;/span> &lt;span class="n">rank&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">root_y&lt;/span>&lt;span class="p">])&lt;/span> &lt;span class="n">swap&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">root_x&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">root_y&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">parent&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">root_y&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">root_x&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">rank&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">root_x&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="n">rank&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">root_y&lt;/span>&lt;span class="p">])&lt;/span> &lt;span class="n">rank&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">root_x&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="o">++&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">size&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">root_x&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">+=&lt;/span> &lt;span class="n">size&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">root_y&lt;/span>&lt;span class="p">];&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="nb">true&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">bool&lt;/span> &lt;span class="nf">same&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span> &lt;span class="n">x&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="kt">int&lt;/span> &lt;span class="n">y&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="k">return&lt;/span> &lt;span class="n">find&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">x&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="n">find&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">y&lt;/span>&lt;span class="p">);&lt;/span> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">struct&lt;/span> &lt;span class="nc">Edge&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">int&lt;/span> &lt;span class="n">u&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">v&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">long&lt;/span> &lt;span class="kt">long&lt;/span> &lt;span class="n">weight&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Fonction de comparaison pour le tri
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="kt">bool&lt;/span> &lt;span class="k">operator&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">const&lt;/span> &lt;span class="n">Edge&lt;/span>&lt;span class="o">&amp;amp;&lt;/span> &lt;span class="n">other&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="k">const&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">weight&lt;/span> &lt;span class="o">&amp;lt;&lt;/span> &lt;span class="n">other&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">weight&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// Algorithme de Kruskal
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="kt">long&lt;/span> &lt;span class="kt">long&lt;/span> &lt;span class="nf">kruskal&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span> &lt;span class="n">V&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">Edge&lt;/span>&lt;span class="o">&amp;gt;&amp;amp;&lt;/span> &lt;span class="n">edges&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Trier les arêtes par ordre croissant de poids
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">sort&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">edges&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">begin&lt;/span>&lt;span class="p">(),&lt;/span> &lt;span class="n">edges&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">end&lt;/span>&lt;span class="p">());&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">UnionFind&lt;/span> &lt;span class="n">uf&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">V&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">long&lt;/span> &lt;span class="kt">long&lt;/span> &lt;span class="n">mst_cost&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">int&lt;/span> &lt;span class="n">edge_count&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="k">const&lt;/span> &lt;span class="k">auto&lt;/span>&lt;span class="o">&amp;amp;&lt;/span> &lt;span class="nl">edge&lt;/span> &lt;span class="p">:&lt;/span> &lt;span class="n">edges&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">uf&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">unite&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">edge&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">u&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">edge&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">v&lt;/span>&lt;span class="p">))&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">mst_cost&lt;/span> &lt;span class="o">+=&lt;/span> &lt;span class="n">edge&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">weight&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">edge_count&lt;/span>&lt;span class="o">++&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// S&amp;#39;arrêter si V-1 arêtes ont été choisies (optimisation)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">edge_count&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="n">V&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="k">break&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">mst_cost&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="algorithme-de-prim">Algorithme de Prim
&lt;/h3>&lt;p>L&amp;rsquo;approche est très similaire à celle de l&amp;rsquo;algorithme de Dijkstra. En partant d&amp;rsquo;un sommet donné, on fait croître l&amp;rsquo;arbre en choisissant successivement l&amp;rsquo;arête de plus faible poids connectée directement à l&amp;rsquo;arbre déjà formé.&lt;/p>
&lt;p>La complexité est de $O((V + E) \log V)$ lorsqu&amp;rsquo;une file de priorité est utilisée. Pour les graphes denses (avec beaucoup d&amp;rsquo;arêtes), l&amp;rsquo;implémentation de Prim basée sur des tableaux en $O(V^2)$ peut être plus rapide que l&amp;rsquo;algorithme de Kruskal.&lt;/p>
&lt;h4 id="exemple-dimplémentation-en-c-4">Exemple d&amp;rsquo;implémentation en C++
&lt;/h4>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;span class="lnt">31
&lt;/span>&lt;span class="lnt">32
&lt;/span>&lt;span class="lnt">33
&lt;/span>&lt;span class="lnt">34
&lt;/span>&lt;span class="lnt">35
&lt;/span>&lt;span class="lnt">36
&lt;/span>&lt;span class="lnt">37
&lt;/span>&lt;span class="lnt">38
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;iostream&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;vector&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;queue&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">using&lt;/span> &lt;span class="k">namespace&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">struct&lt;/span> &lt;span class="nc">Edge&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">int&lt;/span> &lt;span class="n">to&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">long&lt;/span> &lt;span class="kt">long&lt;/span> &lt;span class="n">weight&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// Algorithme de Prim
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="kt">long&lt;/span> &lt;span class="kt">long&lt;/span> &lt;span class="nf">prim&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span> &lt;span class="n">V&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="k">const&lt;/span> &lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">Edge&lt;/span>&lt;span class="o">&amp;gt;&amp;gt;&amp;amp;&lt;/span> &lt;span class="n">graph&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">bool&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">used&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">V&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nb">false&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// {poids, sommet}
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">using&lt;/span> &lt;span class="n">P&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">pair&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">long&lt;/span> &lt;span class="kt">long&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="kt">int&lt;/span>&lt;span class="o">&amp;gt;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">priority_queue&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">P&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">P&lt;/span>&lt;span class="o">&amp;gt;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">greater&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">P&lt;/span>&lt;span class="o">&amp;gt;&amp;gt;&lt;/span> &lt;span class="n">pq&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">long&lt;/span> &lt;span class="kt">long&lt;/span> &lt;span class="n">mst_cost&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Prendre le sommet 0 comme origine
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">pq&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">push&lt;/span>&lt;span class="p">({&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">});&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">while&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="o">!&lt;/span>&lt;span class="n">pq&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">empty&lt;/span>&lt;span class="p">())&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">auto&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="n">cost&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">u&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">pq&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">top&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">pq&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">pop&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">used&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">u&lt;/span>&lt;span class="p">])&lt;/span> &lt;span class="k">continue&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">used&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">u&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nb">true&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">mst_cost&lt;/span> &lt;span class="o">+=&lt;/span> &lt;span class="n">cost&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="k">const&lt;/span> &lt;span class="k">auto&lt;/span>&lt;span class="o">&amp;amp;&lt;/span> &lt;span class="nl">edge&lt;/span> &lt;span class="p">:&lt;/span> &lt;span class="n">graph&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">u&lt;/span>&lt;span class="p">])&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="o">!&lt;/span>&lt;span class="n">used&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">edge&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">to&lt;/span>&lt;span class="p">])&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">pq&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">push&lt;/span>&lt;span class="p">({&lt;/span>&lt;span class="n">edge&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">weight&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">edge&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">to&lt;/span>&lt;span class="p">});&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">mst_cost&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;hr>
&lt;h2 id="6-avancé--décomposition-en-composantes-fortement-connexes-scc--strongly-connected-components">6. Avancé : Décomposition en composantes fortement connexes (SCC : Strongly Connected Components)
&lt;/h2>&lt;p>Dans un graphe orienté, un ensemble de sommets qui peuvent s&amp;rsquo;atteindre mutuellement est appelé composante fortement connexe (SCC). Si l&amp;rsquo;on regroupe chaque composante fortement connexe d&amp;rsquo;un graphe orienté quelconque, l&amp;rsquo;ensemble devient toujours un DAG (graphe orienté acyclique). C&amp;rsquo;est ce qu&amp;rsquo;on appelle la &lt;strong>décomposition en composantes fortement connexes&lt;/strong>. Il s&amp;rsquo;agit d&amp;rsquo;un prétraitement très important pour simplifier la structure du graphe et faciliter la résolution de problèmes.&lt;/p>
&lt;p>En programmation compétitive, cette méthode est souvent utilisée pour résoudre le problème 2-SAT ou pour contracter des graphes contenant des cycles en DAG afin d&amp;rsquo;appliquer la programmation dynamique (DP).&lt;/p>
&lt;h3 id="algorithme-de-kosaraju">Algorithme de Kosaraju
&lt;/h3>&lt;p>L&amp;rsquo;algorithme de Kosaraju est une méthode élégante et efficace qui permet de construire des SCC en n&amp;rsquo;effectuant que deux parcours en profondeur (DFS). Il fonctionne en temps linéaire avec une complexité de $O(V + E)$.&lt;/p>
&lt;p>Étapes de l&amp;rsquo;algorithme :&lt;/p>
&lt;ol>
&lt;li>Effectuer un DFS sur le graphe d&amp;rsquo;origine et enregistrer les sommets dans un tableau dans l&amp;rsquo;ordre de post-visite (post-order).&lt;/li>
&lt;li>Créer un &lt;strong>graphe inversé&lt;/strong> en inversant la direction de toutes les arêtes.&lt;/li>
&lt;li>En parcourant le tableau enregistré à l&amp;rsquo;étape 1 &lt;strong>de l&amp;rsquo;arrière vers l&amp;rsquo;avant&lt;/strong> (ordre de post-visite décroissant), effectuer un DFS sur le graphe inversé depuis les sommets non visités. L&amp;rsquo;ensemble des sommets atteints lors de ce seul DFS forme une SCC.&lt;/li>
&lt;/ol>
&lt;div class="mermaid">graph TD
subgraph "SCC 1"
A["Sommet A"] --> B["Sommet B"]
B["Sommet B"] --> A["Sommet A"]
end
subgraph "SCC 2"
C["Sommet C"] --> D["Sommet D"]
D["Sommet D"] --> C["Sommet C"]
end
B["Sommet B"] --> C["Sommet C"]&lt;/div>
&lt;h4 id="exemple-dimplémentation-en-c-5">Exemple d&amp;rsquo;implémentation en C++
&lt;/h4>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;span class="lnt">31
&lt;/span>&lt;span class="lnt">32
&lt;/span>&lt;span class="lnt">33
&lt;/span>&lt;span class="lnt">34
&lt;/span>&lt;span class="lnt">35
&lt;/span>&lt;span class="lnt">36
&lt;/span>&lt;span class="lnt">37
&lt;/span>&lt;span class="lnt">38
&lt;/span>&lt;span class="lnt">39
&lt;/span>&lt;span class="lnt">40
&lt;/span>&lt;span class="lnt">41
&lt;/span>&lt;span class="lnt">42
&lt;/span>&lt;span class="lnt">43
&lt;/span>&lt;span class="lnt">44
&lt;/span>&lt;span class="lnt">45
&lt;/span>&lt;span class="lnt">46
&lt;/span>&lt;span class="lnt">47
&lt;/span>&lt;span class="lnt">48
&lt;/span>&lt;span class="lnt">49
&lt;/span>&lt;span class="lnt">50
&lt;/span>&lt;span class="lnt">51
&lt;/span>&lt;span class="lnt">52
&lt;/span>&lt;span class="lnt">53
&lt;/span>&lt;span class="lnt">54
&lt;/span>&lt;span class="lnt">55
&lt;/span>&lt;span class="lnt">56
&lt;/span>&lt;span class="lnt">57
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;iostream&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;vector&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;algorithm&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">using&lt;/span> &lt;span class="k">namespace&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">struct&lt;/span> &lt;span class="nc">SCC&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">int&lt;/span> &lt;span class="n">V&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">int&lt;/span>&lt;span class="o">&amp;gt;&amp;gt;&lt;/span> &lt;span class="n">graph&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">rev_graph&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">int&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">order&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">comp&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">bool&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">used&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">SCC&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span> &lt;span class="n">n&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="n">V&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">n&lt;/span>&lt;span class="p">),&lt;/span> &lt;span class="n">graph&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">n&lt;/span>&lt;span class="p">),&lt;/span> &lt;span class="n">rev_graph&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">n&lt;/span>&lt;span class="p">),&lt;/span> &lt;span class="n">comp&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">n&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="o">-&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">),&lt;/span> &lt;span class="n">used&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">n&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nb">false&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">void&lt;/span> &lt;span class="nf">add_edge&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span> &lt;span class="n">from&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="kt">int&lt;/span> &lt;span class="n">to&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">graph&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">from&lt;/span>&lt;span class="p">].&lt;/span>&lt;span class="n">push_back&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">to&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">rev_graph&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">to&lt;/span>&lt;span class="p">].&lt;/span>&lt;span class="n">push_back&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">from&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 1er DFS (Enregistrement du post-ordre)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="kt">void&lt;/span> &lt;span class="nf">dfs1&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span> &lt;span class="n">u&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">used&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">u&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nb">true&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span> &lt;span class="nl">v&lt;/span> &lt;span class="p">:&lt;/span> &lt;span class="n">graph&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">u&lt;/span>&lt;span class="p">])&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="o">!&lt;/span>&lt;span class="n">used&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">v&lt;/span>&lt;span class="p">])&lt;/span> &lt;span class="n">dfs1&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">v&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">order&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">push_back&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">u&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 2ème DFS (Exploration du graphe inversé)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="kt">void&lt;/span> &lt;span class="nf">dfs2&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span> &lt;span class="n">u&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="kt">int&lt;/span> &lt;span class="n">id&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">used&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">u&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nb">true&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">comp&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">u&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">id&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span> &lt;span class="nl">v&lt;/span> &lt;span class="p">:&lt;/span> &lt;span class="n">rev_graph&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">u&lt;/span>&lt;span class="p">])&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="o">!&lt;/span>&lt;span class="n">used&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">v&lt;/span>&lt;span class="p">])&lt;/span> &lt;span class="n">dfs2&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">v&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">id&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Processus de construction des SCC. La valeur de retour est le nombre de groupes SCC
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="kt">int&lt;/span> &lt;span class="nf">build&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 1er DFS
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">for&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="o">&amp;lt;&lt;/span> &lt;span class="n">V&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="o">++&lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="o">!&lt;/span>&lt;span class="n">used&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="p">])&lt;/span> &lt;span class="n">dfs1&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">fill&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">used&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">begin&lt;/span>&lt;span class="p">(),&lt;/span> &lt;span class="n">used&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">end&lt;/span>&lt;span class="p">(),&lt;/span> &lt;span class="nb">false&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">int&lt;/span> &lt;span class="n">group_id&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 2ème DFS (dans l&amp;#39;ordre inverse de &amp;#34;order&amp;#34;)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">for&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">V&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="o">&amp;gt;=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="o">--&lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">int&lt;/span> &lt;span class="n">u&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">order&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="p">];&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="o">!&lt;/span>&lt;span class="n">used&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">u&lt;/span>&lt;span class="p">])&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">dfs2&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">u&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">group_id&lt;/span>&lt;span class="o">++&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">group_id&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Le tableau &lt;code>comp&lt;/code> stocke l&amp;rsquo;ID de la SCC à laquelle appartient chaque sommet. Cet ID possède en réalité une propriété très pratique : il est attribué dans l&amp;rsquo;ordre du tri topologique. Ainsi, en regardant les valeurs de &lt;code>comp&lt;/code>, on peut déterminer immédiatement les dépendances après contraction en DAG.&lt;/p>
&lt;hr>
&lt;h2 id="7-conclusion-et-conseils-dapprentissage">7. Conclusion et conseils d&amp;rsquo;apprentissage
&lt;/h2>&lt;p>Dans cet article, nous avons passé en revue les algorithmes de graphes fréquemment rencontrés en programmation compétitive.
Les clés pour s&amp;rsquo;améliorer sur les problèmes de graphes sont : &lt;strong>« implémenter l&amp;rsquo;algorithme à plusieurs reprises jusqu&amp;rsquo;à ce que cela devienne un réflexe »&lt;/strong> et &lt;strong>« s&amp;rsquo;entraîner à réfléchir à quel type de graphe un problème peut être réduit (que représentent les sommets, que représentent les arêtes) »&lt;/strong>.&lt;/p>
&lt;ol>
&lt;li>Tout d&amp;rsquo;abord, soyez capable d&amp;rsquo;écrire rapidement et sans erreur les algorithmes DFS / BFS.&lt;/li>
&lt;li>Ensuite, apprenez à coder de mémoire l&amp;rsquo;algorithme de Dijkstra et l&amp;rsquo;algorithme de Kruskal (indispensable pour les rangs marron-vert sur AtCoder).&lt;/li>
&lt;li>Enfin, élargissez vos connaissances avec Bellman-Ford, Floyd-Warshall, le tri topologique et les SCC (ce qui constituera une arme pour les rangs cyan-bleu sur AtCoder).&lt;/li>
&lt;/ol>
&lt;p>Nous vous recommandons fortement de les ajouter sous forme de snippets dans votre propre bibliothèque (en utilisant des outils de snippets ou en les sauvegardant sur votre dépôt GitHub) afin d&amp;rsquo;être prêt à les utiliser sans hésitation lors des compétitions réelles.&lt;/p>
&lt;p>Les algorithmes de graphes en programmation compétitive constituent le domaine où l&amp;rsquo;on ressent le plus la beauté et la puissance de l&amp;rsquo;algorithmique. N&amp;rsquo;hésitez pas à recopier le code de cet article et à vous mesurer à d&amp;rsquo;anciens problèmes sur les juges en ligne (Online Judges) !&lt;/p></description></item><item><title>Avis aux passionnés de mathématiques ! 10 superbes formules mathématiques utiles pour la programmation</title><link>http://kenji.blog/fr/p/10-beautiful-math-formulas-for-programming/</link><pubDate>Sat, 12 Sep 2026 01:00:00 +0900</pubDate><guid>http://kenji.blog/fr/p/10-beautiful-math-formulas-for-programming/</guid><description>&lt;img src="http://kenji.blog/p/10-beautiful-math-formulas-for-programming/img/eyecatch.jpg" alt="Featured image of post Avis aux passionnés de mathématiques ! 10 superbes formules mathématiques utiles pour la programmation" />&lt;h1 id="avis-aux-passionnés-de-mathématiques--10-superbes-formules-mathématiques-utiles-pour-la-programmation">Avis aux passionnés de mathématiques ! 10 superbes formules mathématiques utiles pour la programmation
&lt;/h1>&lt;p>La programmation et les mathématiques peuvent sembler à première vue être des domaines totalement différents. La programmation est le processus d&amp;rsquo;écriture de code logique et concret, tandis que les mathématiques sont la poursuite de vérités abstraites et universelles. Cependant, les mathématiques sont toujours au cœur de l&amp;rsquo;informatique. Derrière l&amp;rsquo;optimisation des algorithmes, la science des données, l&amp;rsquo;apprentissage automatique, l&amp;rsquo;infographie et même les applications quotidiennes, de belles formules mathématiques travaillent silencieusement et puissamment.&lt;/p>
&lt;p>Dans cet article, nous avons soigneusement sélectionné 10 formules qui ne sont pas seulement belles mathématiquement, mais qui jouent également un rôle extrêmement pratique et important dans le contexte de la programmation et des algorithmes. Nous approfondirons le contexte mathématique de chaque formule et expliquerons en détail comment elle est appliquée dans la pratique de la programmation, avec des extraits de code concrets en Python et C++.&lt;/p>
&lt;p>Bienvenue dans un monde où la beauté des mathématiques croise l&amp;rsquo;aspect pratique de la programmation.&lt;/p>
&lt;hr>
&lt;h2 id="1-identité-deuler-eulers-identity">1. Identité d&amp;rsquo;Euler (Euler&amp;rsquo;s Identity)
&lt;/h2>&lt;h3 id="beauté-de-la-formule-et-aperçu">Beauté de la formule et aperçu
&lt;/h3>&lt;p>Voici l&amp;rsquo;identité d&amp;rsquo;Euler, souvent qualifiée de &amp;ldquo;trésor de l&amp;rsquo;humanité&amp;rdquo; ou de &amp;ldquo;la plus belle équation du monde&amp;rdquo;. Les cinq constantes les plus importantes en mathématiques (le nombre de Néper $e$, l&amp;rsquo;unité imaginaire $i$, le nombre pi $\pi$, l&amp;rsquo;élément neutre de la multiplication $1$ et l&amp;rsquo;élément neutre de l&amp;rsquo;addition $0$) sont intégrées dans une seule formule simple.&lt;/p>
$$ e^{i\pi} + 1 = 0 $$
&lt;p>Cette équation est dérivée de la formule d&amp;rsquo;Euler plus générale $e^{i\theta} = \cos\theta + i\sin\theta$ en y substituant $\theta = \pi$.&lt;/p>
&lt;h3 id="applications-en-programmation">Applications en programmation
&lt;/h3>&lt;p>En programmation, notamment dans l&amp;rsquo;infographie et le développement de jeux, la formule d&amp;rsquo;Euler devient un outil extrêmement puissant pour gérer les &amp;ldquo;rotations&amp;rdquo;. La rotation d&amp;rsquo;un point dans un espace bidimensionnel peut être effectuée à l&amp;rsquo;aide de calculs matriciels, mais l&amp;rsquo;utilisation de nombres complexes rend le calcul extrêmement simple et intuitif. La rotation sur un plan complexe peut être réalisée en multipliant simplement par $e^{i\theta}$, ce qui rend le code très concis.&lt;/p>
&lt;h3 id="exemple-dimplémentation-c">Exemple d&amp;rsquo;implémentation (C++)
&lt;/h3>&lt;p>Voici un programme qui fait pivoter un point sur des coordonnées 2D d&amp;rsquo;un angle spécifié (en radians) à l&amp;rsquo;aide de la bibliothèque standard C++ &lt;code>&amp;lt;complex&amp;gt;&lt;/code>.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;span class="lnt">31
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;iostream&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;complex&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;cmath&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// Alias de type pour traiter les coordonnées 2D comme des nombres complexes
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="k">using&lt;/span> &lt;span class="n">Point2D&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">complex&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">double&lt;/span>&lt;span class="o">&amp;gt;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// Fonction pour faire pivoter un point autour de l&amp;#39;origine d&amp;#39;un angle theta (en radians)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="n">Point2D&lt;/span> &lt;span class="nf">rotatePoint&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">const&lt;/span> &lt;span class="n">Point2D&lt;/span>&lt;span class="o">&amp;amp;&lt;/span> &lt;span class="n">point&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="kt">double&lt;/span> &lt;span class="n">theta&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Créer le nombre complexe pour la rotation e^{i*theta} selon la formule d&amp;#39;Euler
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// En interne, cela correspond à cos(theta) + i*sin(theta)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">Point2D&lt;/span> &lt;span class="n">rotation&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cos&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">theta&lt;/span>&lt;span class="p">),&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">sin&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">theta&lt;/span>&lt;span class="p">));&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Appliquer la rotation via la multiplication de nombres complexes
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">return&lt;/span> &lt;span class="n">point&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">rotation&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kt">int&lt;/span> &lt;span class="nf">main&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Coordonnées initiales (x=1.0, y=0.0)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">Point2D&lt;/span> &lt;span class="n">p&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mf">1.0&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mf">0.0&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Rotation de 90 degrés (π/2 radians)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="kt">double&lt;/span> &lt;span class="n">theta&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">M_PI&lt;/span> &lt;span class="o">/&lt;/span> &lt;span class="mf">2.0&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">Point2D&lt;/span> &lt;span class="n">rotated_p&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">rotatePoint&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">p&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">theta&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;Original Point: (&amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">p&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">real&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;, &amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">p&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">imag&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;)&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="s">&amp;#34;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// La sortie attendue est d&amp;#39;environ (0, 1)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;Rotated Point: (&amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">rotated_p&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">real&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;, &amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">rotated_p&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">imag&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;)&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="s">&amp;#34;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>&lt;strong>Explication détaillée&lt;/strong> :
L&amp;rsquo;avantage de cette approche est que le calcul de la matrice de rotation (4 multiplications et 2 additions) peut être encapsulé sous forme d&amp;rsquo;opération sur les nombres complexes. De plus, dans l&amp;rsquo;espace tridimensionnel, on utilise les &amp;ldquo;quaternions&amp;rdquo;, qui sont une extension de ce concept. L&amp;rsquo;utilisation des quaternions permet d&amp;rsquo;éviter le problème fatal du &amp;ldquo;blocage de cardan&amp;rdquo; (Gimbal Lock) qui se produit avec les angles d&amp;rsquo;Euler, et d&amp;rsquo;obtenir une interpolation linéaire sphérique fluide (Slerp).&lt;/p>
&lt;hr>
&lt;h2 id="2-développement-de-taylor-taylor-series">2. Développement de Taylor (Taylor Series)
&lt;/h2>&lt;h3 id="beauté-de-la-formule-et-aperçu-1">Beauté de la formule et aperçu
&lt;/h3>&lt;p>Le développement de Taylor est une méthode mathématique qui exprime des fonctions complexes (telles que les fonctions trigonométriques et exponentielles) sous la forme d&amp;rsquo;une somme infinie de polynômes. Le développement de Taylor d&amp;rsquo;une fonction $f(x)$ autour d&amp;rsquo;un point $a$ est défini comme suit :&lt;/p>
$$ f(x) = \sum_{n=0}^\infty \frac{f^{(n)}(a)}{n!}(x-a)^n $$
&lt;p>En particulier, le cas où $a=0$ est appelé &amp;ldquo;développement de Maclaurin&amp;rdquo;.&lt;/p>
&lt;h3 id="applications-en-programmation-1">Applications en programmation
&lt;/h3>&lt;p>Les ordinateurs (CPU ou FPU) ne peuvent fondamentalement exécuter que des opérations arithmétiques basiques : addition, soustraction, multiplication et division. Alors, comment sont calculés &lt;code>sin(x)&lt;/code> ou &lt;code>exp(x)&lt;/code> ? Dans les processeurs modernes, l&amp;rsquo;algorithme CORDIC ou l&amp;rsquo;approximation de Tchebychev sont souvent utilisés, mais lorsque l&amp;rsquo;on implémente des fonctions mathématiques au niveau logiciel, ou que l&amp;rsquo;on crée ses propres fonctions d&amp;rsquo;approximation rapides en sacrifiant un peu de précision pour les performances, le développement de Taylor (ou ses variantes) est directement utile.&lt;/p>
&lt;h3 id="exemple-dimplémentation-python">Exemple d&amp;rsquo;implémentation (Python)
&lt;/h3>&lt;p>Voici un code Python qui calcule approximativement la fonction sinus à l&amp;rsquo;aide du développement de Maclaurin.&lt;/p>
$$ \sin(x) \approx x - \frac{x^3}{3!} + \frac{x^5}{5!} - \frac{x^7}{7!} + \dots $$
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;span class="lnt">31
&lt;/span>&lt;span class="lnt">32
&lt;/span>&lt;span class="lnt">33
&lt;/span>&lt;span class="lnt">34
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">math&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">taylor_sin&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">x&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">terms&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">10&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;&amp;#34;&amp;#34;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> Calcule une approximation de sin(x) en utilisant le développement de Taylor (développement de Maclaurin).
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> :param x: Angle (en radians)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> :param terms: Nombre de termes à calculer (plus il y en a, plus la précision est élevée)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> :return: Valeur approximative de sin(x)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> &amp;#34;&amp;#34;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Normaliser x dans la plage de -π à π en utilisant la périodicité (pour améliorer la précision)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">x&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">x&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="n">math&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">pi&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">%&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="mi">2&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">math&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">pi&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="n">math&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">pi&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">result&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mf">0.0&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="n">n&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="nb">range&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">terms&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Utiliser uniquement les termes impairs : 2n + 1&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">power&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">2&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">n&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="mi">1&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Le signe est inversé pour chaque terme : (-1)^n&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">sign&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">**&lt;/span> &lt;span class="n">n&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Calcul de la factorielle&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">fact&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">math&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">factorial&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">power&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Évaluation de la formule et addition&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">term&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">sign&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">x&lt;/span> &lt;span class="o">**&lt;/span> &lt;span class="n">power&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">/&lt;/span> &lt;span class="n">fact&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">result&lt;/span> &lt;span class="o">+=&lt;/span> &lt;span class="n">term&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">result&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Test&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">angle&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">math&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">radians&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">45&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="c1"># 45 degrés = π/4&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;Math library sin: &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">math&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">sin&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">angle&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;Taylor series sin: &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">taylor_sin&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">angle&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">terms&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">5&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>&lt;strong>Explication détaillée&lt;/strong> :
Dans le code ci-dessus, la valeur d&amp;rsquo;entrée &lt;code>x&lt;/code> est normalisée dans la plage $[-\pi, \pi]$. C&amp;rsquo;est parce que le développement de Taylor a la propriété de voir son erreur augmenter rapidement à mesure que l&amp;rsquo;on s&amp;rsquo;éloigne du centre du développement (ici 0) (erreur de troncature). Comme les calculs infinis sont impossibles en programmation, nous tronquons le calcul à un nombre fini de &lt;code>terms&lt;/code>, mais la gestion du compromis entre l&amp;rsquo;&amp;ldquo;erreur d&amp;rsquo;arrondi&amp;rdquo; et l&amp;rsquo;&amp;ldquo;erreur de troncature&amp;rdquo; qui en résulte est la clé de la programmation de calculs numériques.&lt;/p>
&lt;hr>
&lt;h2 id="3-théorème-de-bayes-bayes-theorem">3. Théorème de Bayes (Bayes&amp;rsquo; Theorem)
&lt;/h2>&lt;h3 id="beauté-de-la-formule-et-aperçu-2">Beauté de la formule et aperçu
&lt;/h3>&lt;p>Le théorème de Bayes est un théorème permettant de mettre à jour la probabilité d&amp;rsquo;un événement (probabilité a posteriori) sur la base de connaissances préalables (probabilité a priori) liées à cet événement. C&amp;rsquo;est l&amp;rsquo;une des formules les plus importantes en théorie des probabilités et en statistiques.&lt;/p>
$$ P(A|B) = \frac{P(B|A)P(A)}{P(B)} $$
&lt;p>Ici, $P(A|B)$ représente la probabilité que l&amp;rsquo;événement A se produise sous la condition que l&amp;rsquo;événement B s&amp;rsquo;est produit (probabilité a posteriori).&lt;/p>
&lt;h3 id="applications-en-programmation-2">Applications en programmation
&lt;/h3>&lt;p>Il est largement utilisé dans les domaines de l&amp;rsquo;apprentissage automatique et de la science des données sous le nom de &amp;ldquo;classificateur naïf de Bayes&amp;rdquo; (Naive Bayes Classifier). Un exemple typique d&amp;rsquo;application est le filtrage des courriers indésirables (spam). Le calcul de &amp;ldquo;Quelle est la probabilité que cet e-mail soit un spam s&amp;rsquo;il contient le mot &amp;lsquo;gratuit&amp;rsquo; ?&amp;rdquo; est effectué dynamiquement sur la base de données passées.&lt;/p>
&lt;div class="mermaid">graph TD
Email["E-mail entrant"] --> Extract["Extraire les mots"]
Extract --> W1["Mot : 'Gratuit'"]
Extract --> W2["Mot : 'Argent'"]
Extract --> Wn["Mot : 'Réunion'"]
W1 --> Prob["Calculer P(Spam | Mots)"]
W2 --> Prob
Wn --> Prob
Prob --> Bayes["Appliquer le théorème de Bayes"]
Bayes --> Class{"P(Spam) > 0.9 ?"}
Class -- "Oui" --> Spam["Déplacer vers le dossier Spam"]
Class -- "Non" --> Ham["Livrer à la boîte de réception"]&lt;/div>
&lt;h3 id="exemple-dimplémentation-python-1">Exemple d&amp;rsquo;implémentation (Python)
&lt;/h3>&lt;p>Voici un code illustrant la logique de base d&amp;rsquo;un filtre anti-spam.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;span class="lnt">31
&lt;/span>&lt;span class="lnt">32
&lt;/span>&lt;span class="lnt">33
&lt;/span>&lt;span class="lnt">34
&lt;/span>&lt;span class="lnt">35
&lt;/span>&lt;span class="lnt">36
&lt;/span>&lt;span class="lnt">37
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">calculate_spam_probability&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">prob_spam&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">prob_word_given_spam&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">prob_word_given_ham&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;&amp;#34;&amp;#34;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> Calcule la probabilité qu&amp;#39;un e-mail contenant un certain mot soit un spam en utilisant le théorème de Bayes.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> :param prob_spam: P(Spam) - Probabilité a priori que l&amp;#39;e-mail soit un spam
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> :param prob_word_given_spam: P(Word|Spam) - Probabilité que le mot soit inclus dans un spam
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> :param prob_word_given_ham: P(Word|Ham) - Probabilité que le mot soit inclus dans un e-mail normal
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> :return: P(Spam|Word) - Probabilité qu&amp;#39;il s&amp;#39;agisse d&amp;#39;un spam si le mot est inclus
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> &amp;#34;&amp;#34;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Probabilité a priori d&amp;#39;un e-mail normal P(Ham) = 1 - P(Spam)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">prob_ham&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mf">1.0&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="n">prob_spam&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Probabilité d&amp;#39;apparition de ce mot dans tous les e-mails P(Word) = P(Word|Spam)P(Spam) + P(Word|Ham)P(Ham)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Ceci est dû au théorème des probabilités totales&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">prob_word&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">prob_word_given_spam&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">prob_spam&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">prob_word_given_ham&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">prob_ham&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Théorème de Bayes P(Spam|Word) = P(Word|Spam) * P(Spam) / P(Word)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="n">prob_word&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="mf">0.0&lt;/span> &lt;span class="c1"># Évitement de la division par zéro&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">prob_spam_given_word&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">prob_word_given_spam&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">prob_spam&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">/&lt;/span> &lt;span class="n">prob_word&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">prob_spam_given_word&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Exemple : Probabilité avec le mot &amp;#34;gagnant&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Données passées : 20% de tous les e-mails sont des spams&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">p_spam&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mf">0.2&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 80% des spams contiennent le mot &amp;#34;gagnant&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">p_win_given_spam&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mf">0.8&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 1% des e-mails normaux contiennent le mot &amp;#34;gagnant&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">p_win_given_ham&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mf">0.01&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">result&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">calculate_spam_probability&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">p_spam&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">p_win_given_spam&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">p_win_given_ham&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;Probabilité qu&amp;#39;un e-mail contenant le mot &amp;#39;gagnant&amp;#39; soit un spam : &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">result&lt;/span>&lt;span class="si">:&lt;/span>&lt;span class="s2">.2%&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>&lt;strong>Explication détaillée&lt;/strong> :
Dans une implémentation réelle (classificateur naïf de Bayes), les probabilités de plusieurs mots sont multipliées ensemble. Cependant, si l&amp;rsquo;on multiplie des probabilités (valeurs entre 0 et 1) des milliers de fois, la valeur devient nulle en raison des limites de la représentation en virgule flottante des ordinateurs (sous-dépassement ou underflow). Par conséquent, dans la programmation réelle, la technique consistant à convertir le produit des probabilités en &amp;ldquo;somme de logarithmes&amp;rdquo; (&lt;code>log(a * b) = log(a) + log(b)&lt;/code>) est une technique essentielle.&lt;/p>
&lt;hr>
&lt;h2 id="4-entropie-de-shannon-shannon-entropy">4. Entropie de Shannon (Shannon Entropy)
&lt;/h2>&lt;h3 id="beauté-de-la-formule-et-aperçu-3">Beauté de la formule et aperçu
&lt;/h3>&lt;p>Définie par Claude Shannon, le père de la théorie de l&amp;rsquo;information, l&amp;rsquo;&amp;ldquo;entropie&amp;rdquo; est une formule qui quantifie l&amp;rsquo;&amp;ldquo;incertitude&amp;rdquo;, le &amp;ldquo;désordre&amp;rdquo; ou la &amp;ldquo;quantité moyenne d&amp;rsquo;information&amp;rdquo; possédée par une source d&amp;rsquo;information.&lt;/p>
$$ H(X) = - \sum_{i=1}^n P(x_i) \log_2 P(x_i) $$
&lt;h3 id="applications-en-programmation-3">Applications en programmation
&lt;/h3>&lt;p>L&amp;rsquo;entropie est indispensable dans la compression des données de fichiers (le codage de Huffman et les limites théoriques de l&amp;rsquo;algorithme de compression ZIP), l&amp;rsquo;évaluation de la force des nombres aléatoires en cryptographie, et les algorithmes d&amp;rsquo;&amp;ldquo;arbres de décision&amp;rdquo; (Decision Trees, tels que ID3 ou C4.5) en apprentissage automatique. Lors de la construction d&amp;rsquo;un arbre de décision, l&amp;rsquo;algorithme cherche à trouver la caractéristique qui maximise la réduction de l&amp;rsquo;entropie (gain d&amp;rsquo;information) lors de la division des données.&lt;/p>
&lt;h3 id="exemple-dimplémentation-python-2">Exemple d&amp;rsquo;implémentation (Python)
&lt;/h3>&lt;p>Voici une fonction qui calcule l&amp;rsquo;entropie d&amp;rsquo;une chaîne de caractères (jeu de données) et évalue sa quantité d&amp;rsquo;information.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;span class="lnt">31
&lt;/span>&lt;span class="lnt">32
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">math&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">collections&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">Counter&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">calculate_entropy&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">data&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;&amp;#34;&amp;#34;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> Calcule l&amp;#39;entropie de Shannon de l&amp;#39;ensemble de données donné (chaîne de caractères ou liste).
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> &amp;#34;&amp;#34;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="ow">not&lt;/span> &lt;span class="n">data&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="mf">0.0&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Compter le nombre d&amp;#39;occurrences de chaque élément&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">counts&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">Counter&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">data&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">total_len&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nb">len&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">data&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">entropy&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mf">0.0&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="n">element&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">count&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="n">counts&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">items&lt;/span>&lt;span class="p">():&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Probabilité d&amp;#39;occurrence P(x_i)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">probability&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">count&lt;/span> &lt;span class="o">/&lt;/span> &lt;span class="n">total_len&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># - P(x_i) * log2(P(x_i))&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">entropy&lt;/span> &lt;span class="o">-=&lt;/span> &lt;span class="n">probability&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">math&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">log2&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">probability&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">entropy&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Tests&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Si tous les caractères sont les mêmes, l&amp;#39;incertitude est de 0&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">data_deterministic&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;AAAAAAAAAA&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Pour des caractères aléatoires, l&amp;#39;incertitude est élevée&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">data_random&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;ABACBCBACB&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;Entropy of &amp;#39;&lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">data_deterministic&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">&amp;#39;: &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">calculate_entropy&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">data_deterministic&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;Entropy of &amp;#39;&lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">data_random&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">&amp;#39;: &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">calculate_entropy&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">data_random&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>&lt;strong>Explication détaillée&lt;/strong> :
L&amp;rsquo;unité de l&amp;rsquo;entropie est le &amp;ldquo;bit&amp;rdquo; (bits). Si l&amp;rsquo;entropie est de &lt;code>1.5&lt;/code>, cela signifie qu&amp;rsquo;en moyenne un minimum de 1,5 bits par élément est nécessaire pour représenter ces données. Dans le domaine de la programmation, elle est calculée quotidiennement comme repère pour mesurer l&amp;rsquo;efficacité des algorithmes de compression et comme indicateur clé dans la sélection des caractéristiques des modèles d&amp;rsquo;apprentissage automatique.&lt;/p>
&lt;hr>
&lt;h2 id="5-transformée-de-fourier-rapide-fast-fourier-transform---fft">5. Transformée de Fourier rapide (Fast Fourier Transform - FFT)
&lt;/h2>&lt;h3 id="beauté-de-la-formule-et-aperçu-4">Beauté de la formule et aperçu
&lt;/h3>&lt;p>La transformée de Fourier discrète (DFT) convertit un signal du domaine temporel en un signal du domaine fréquentiel. Sa formule mathématique est la suivante :&lt;/p>
$$ X_k = \sum_{n=0}^{N-1} x_n e^{-i 2\pi k n / N} $$
&lt;p>Si vous calculez cette DFT de manière naïve, la complexité temporelle sera de $O(N^2)$, et à mesure que la quantité de données augmente, le calcul deviendra de plus en plus lent de façon exponentielle. L&amp;rsquo;algorithme qui accélère considérablement cela jusqu&amp;rsquo;à $O(N \log N)$ grâce à l&amp;rsquo;approche diviser pour régner est la &amp;ldquo;Transformée de Fourier rapide&amp;rdquo; (FFT). Il est classé parmi les 10 algorithmes les plus importants du 20ème siècle.&lt;/p>
&lt;div class="mermaid">graph TD
A["Tableau d'entrée de taille N"] --> B["Diviser en indices pairs et impairs"]
B --> C["Indices pairs (N/2)"]
B --> D["Indices impairs (N/2)"]
C --> E["FFT récursive sur les pairs"]
D --> F["FFT récursive sur les impairs"]
E --> G["Combiner à l'aide des facteurs de rotation"]
F --> G
G --> H["Spectre de fréquence de sortie"]&lt;/div>
&lt;h3 id="applications-en-programmation-4">Applications en programmation
&lt;/h3>&lt;p>La FFT est une technologie indispensable qui soutient la société moderne. Elle fonctionne partout : reconnaissance vocale (Siri, Alexa), compression de données MP3 et JPEG/MPEG, communications numériques comme la 4G/LTE et le Wi-Fi, et même la multiplication d&amp;rsquo;entiers extrêmement grands (algorithme de Schönhage-Strassen).&lt;/p>
&lt;h3 id="exemple-dimplémentation-python-3">Exemple d&amp;rsquo;implémentation (Python)
&lt;/h3>&lt;p>Voici un exemple simple d&amp;rsquo;implémentation de l&amp;rsquo;algorithme récursif de type Cooley-Tukey. (&lt;em>En pratique, on utilise des bibliothèques hautement optimisées en C ou en assembleur comme &lt;code>FFTW&lt;/code> ou &lt;code>numpy.fft&lt;/code>&lt;/em>)&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;span class="lnt">31
&lt;/span>&lt;span class="lnt">32
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">cmath&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">fft&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">x&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;&amp;#34;&amp;#34;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> Calcule la Transformée de Fourier Rapide (FFT) 1D (méthode de Cooley-Tukey).
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> La longueur N de la liste d&amp;#39;entrée doit être une puissance de 2.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> &amp;#34;&amp;#34;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">N&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nb">len&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">x&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Cas de base&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="n">N&lt;/span> &lt;span class="o">&amp;lt;=&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">x&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Division en éléments d&amp;#39;indices pairs et impairs (Divide)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">even&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">fft&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">x&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">::&lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="p">])&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">odd&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">fft&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">x&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">::&lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="p">])&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Combinaison des résultats (Conquer)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">T&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="n">cmath&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">exp&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="n">j&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">cmath&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">pi&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">k&lt;/span> &lt;span class="o">/&lt;/span> &lt;span class="n">N&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">odd&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">k&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="k">for&lt;/span> &lt;span class="n">k&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="nb">range&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">N&lt;/span> &lt;span class="o">//&lt;/span> &lt;span class="mi">2&lt;/span>&lt;span class="p">)]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Réduction de la complexité des calculs grâce à la symétrie&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="n">even&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">k&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="n">T&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">k&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="k">for&lt;/span> &lt;span class="n">k&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="nb">range&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">N&lt;/span> &lt;span class="o">//&lt;/span> &lt;span class="mi">2&lt;/span>&lt;span class="p">)]&lt;/span> &lt;span class="o">+&lt;/span> \
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">[&lt;/span>&lt;span class="n">even&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">k&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="n">T&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">k&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="k">for&lt;/span> &lt;span class="n">k&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="nb">range&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">N&lt;/span> &lt;span class="o">//&lt;/span> &lt;span class="mi">2&lt;/span>&lt;span class="p">)]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Test : signal simple&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">signal&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="mf">1.0&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mf">1.0&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mf">1.0&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mf">1.0&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mf">0.0&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mf">0.0&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mf">0.0&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mf">0.0&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">spectrum&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">fft&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">signal&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;Frequency Spectrum (Magnitude):&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">for&lt;/span> &lt;span class="n">k&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">val&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="nb">enumerate&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">spectrum&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Calcul de la valeur absolue (amplitude)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;Freq &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">k&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">: &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="nb">abs&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">val&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="si">:&lt;/span>&lt;span class="s2">.3f&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>&lt;strong>Explication détaillée&lt;/strong> :
La clé de cet algorithme est qu&amp;rsquo;il exploite la symétrie et la périodicité des nombres complexes appelés &amp;ldquo;facteurs de rotation&amp;rdquo; (Twiddle factors). Cela évite les redondances dans les calculs et réduit le nombre d&amp;rsquo;opérations de $1 048 576$ à seulement environ $10 240$ pour $N=1024$. On peut dire que c&amp;rsquo;est véritablement un miracle né de la fusion des mathématiques et des algorithmes.&lt;/p>
&lt;hr>
&lt;h2 id="6-formule-de-la-haversine-haversine-formula">6. Formule de la haversine (Haversine Formula)
&lt;/h2>&lt;h3 id="beauté-de-la-formule-et-aperçu-5">Beauté de la formule et aperçu
&lt;/h3>&lt;p>C&amp;rsquo;est une formule pour calculer la distance la plus courte (distance du grand cercle) entre deux points sur une surface sphérique telle que la surface de la Terre.&lt;/p>
$$ a = \sin^2\left(\frac{\Delta\phi}{2}\right) + \cos\phi_1 \cos\phi_2 \sin^2\left(\frac{\Delta\lambda}{2}\right) $$
$$ c = 2\cdot \text{atan2}\left(\sqrt{a}, \sqrt{1-a}\right) $$
$$ d = R \cdot c $$
&lt;p>(Ici, $\phi$ est la latitude, $\lambda$ est la longitude, et $R$ est le rayon de la Terre)&lt;/p>
&lt;h3 id="applications-en-programmation-5">Applications en programmation
&lt;/h3>&lt;p>Dans les applications de suivi GPS ou les services basés sur la localisation comme Uber ou Pokémon GO, cette équation est indispensable pour calculer la distance entre deux coordonnées de latitude et longitude. Le calcul de la distance en ligne droite à l&amp;rsquo;aide du théorème de Pythagore produit de grandes erreurs sur les longues distances car il ne tient pas compte de la courbure de la Terre.&lt;/p>
&lt;h3 id="exemple-dimplémentation-python-4">Exemple d&amp;rsquo;implémentation (Python)
&lt;/h3>&lt;p>Voici une fonction qui prend deux coordonnées (latitude et longitude) et renvoie la distance (en kilomètres) entre elles.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;span class="lnt">31
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">math&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">haversine_distance&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">lat1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">lon1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">lat2&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">lon2&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;&amp;#34;&amp;#34;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> Calcule la distance du grand cercle entre deux points en utilisant la formule de la haversine.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> &amp;#34;&amp;#34;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Rayon moyen de la Terre (en kilomètres)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">R&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mf">6371.0&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Conversion de la latitude et de la longitude des degrés aux radians&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">phi1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">phi2&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">math&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">radians&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">lat1&lt;/span>&lt;span class="p">),&lt;/span> &lt;span class="n">math&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">radians&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">lat2&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">delta_phi&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">math&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">radians&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">lat2&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="n">lat1&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">delta_lambda&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">math&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">radians&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">lon2&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="n">lon1&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Calcul de la haversine&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">a&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">math&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">sin&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">delta_phi&lt;/span> &lt;span class="o">/&lt;/span> &lt;span class="mf">2.0&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="o">**&lt;/span>&lt;span class="mi">2&lt;/span> &lt;span class="o">+&lt;/span> \
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">math&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">cos&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">phi1&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">math&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">cos&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">phi2&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">*&lt;/span> \
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">math&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">sin&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">delta_lambda&lt;/span> &lt;span class="o">/&lt;/span> &lt;span class="mf">2.0&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="o">**&lt;/span>&lt;span class="mi">2&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">c&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">2&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">math&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">atan2&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">math&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">sqrt&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">a&lt;/span>&lt;span class="p">),&lt;/span> &lt;span class="n">math&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">sqrt&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">1&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="n">a&lt;/span>&lt;span class="p">))&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Calcul de la distance&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">distance&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">R&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">c&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">distance&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Distance entre la Tour de Tokyo (35.6586, 139.7454) et la Statue de la Liberté (40.6892, -74.0445)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">tokyo&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="mf">35.6586&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mf">139.7454&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">ny&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="mf">40.6892&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="o">-&lt;/span>&lt;span class="mf">74.0445&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">dist&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">haversine_distance&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">tokyo&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">],&lt;/span> &lt;span class="n">tokyo&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">],&lt;/span> &lt;span class="n">ny&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">],&lt;/span> &lt;span class="n">ny&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">])&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;Distance de la Tour de Tokyo à la Statue de la Liberté : environ &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">dist&lt;/span>&lt;span class="si">:&lt;/span>&lt;span class="s2">.2f&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2"> km&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>&lt;strong>Explication détaillée&lt;/strong> :
Il existe également une méthode utilisant la loi des cosinus de la trigonométrie sphérique, mais lorsque la distance entre deux points est très courte (par exemple de l&amp;rsquo;ordre de quelques mètres), une &amp;ldquo;annulation catastrophique&amp;rdquo; (Catastrophic cancellation) dans la précision des calculs en virgule flottante a tendance à se produire. L&amp;rsquo;avantage majeur de la formule de la haversine en programmation est qu&amp;rsquo;elle utilise &lt;code>sin^2&lt;/code>, ce qui permet d&amp;rsquo;obtenir des calculs numériquement stables même pour de très petites distances. Si une précision encore plus grande est requise, les formules de Vincenty (Vincenty&amp;rsquo;s formulae), qui traitent la Terre comme un ellipsoïde, sont utilisées.&lt;/p>
&lt;hr>
&lt;h2 id="7-méthode-de-newton-raphson-newton-raphson-method">7. Méthode de Newton-Raphson (Newton-Raphson Method)
&lt;/h2>&lt;h3 id="beauté-de-la-formule-et-aperçu-6">Beauté de la formule et aperçu
&lt;/h3>&lt;p>C&amp;rsquo;est un algorithme de recherche de racines très puissant qui trouve de manière itérative la solution (racine) de l&amp;rsquo;équation $f(x) = 0$ en utilisant des tangentes.&lt;/p>
$$ x_{n+1} = x_n - \frac{f(x_n)}{f'(x_n)} $$
&lt;p>À l&amp;rsquo;aide de la valeur de la fonction $f(x_n)$ et de sa pente (dérivée) $f'(x_n)$ à la position actuelle $x_n$, l&amp;rsquo;algorithme devine la position suivante, plus précise, $x_{n+1}$ à explorer.&lt;/p>
&lt;div class="mermaid">flowchart LR
Start["Début : Deviner le x0 initial"] --> Eval["Évaluer f(xn) et f'(xn)"]
Eval --> Check{"f(xn) ≈ 0 ?"}
Check -- "Oui" --> Done["Renvoyer xn comme racine"]
Check -- "Non" --> Update["xn+1 = xn - f(xn) / f'(xn)"]
Update --> Eval&lt;/div>
&lt;h3 id="applications-en-programmation-6">Applications en programmation
&lt;/h3>&lt;p>Elle est utilisée dans le rendu des moteurs graphiques, la détection des collisions dans les simulations physiques, les problèmes d&amp;rsquo;optimisation, etc. Fait remarquable, le célèbre &amp;ldquo;Fast Inverse Square Root&amp;rdquo; (calcul rapide de l&amp;rsquo;inverse de la racine carrée) intégré dans le code source du légendaire jeu FPS &amp;ldquo;Quake III Arena&amp;rdquo; était un hack qui appliquait la méthode de Newton une seule fois pour calculer $1/\sqrt{x}$ à une vitesse fulgurante, ce qui était essentiel pour la normalisation des vecteurs.&lt;/p>
&lt;h3 id="exemple-dimplémentation-c-1">Exemple d&amp;rsquo;implémentation (C++)
&lt;/h3>&lt;p>Voici un exemple clair qui calcule la racine carrée standard $\sqrt{N}$ (c&amp;rsquo;est-à-dire la solution de $x^2 - N = 0$) à l&amp;rsquo;aide de la méthode de Newton. Nous avons $f(x) = x^2 - N$ et $f'(x) = 2x$.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;iostream&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;cmath&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kt">double&lt;/span> &lt;span class="nf">newton_sqrt&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">double&lt;/span> &lt;span class="n">N&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="kt">double&lt;/span> &lt;span class="n">tolerance&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mf">1e-7&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">N&lt;/span> &lt;span class="o">&amp;lt;&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="k">return&lt;/span> &lt;span class="n">NAN&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="c1">// La racine carrée d&amp;#39;un nombre négatif est NaN
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">N&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="k">return&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Estimation initiale (on commence avec N lui-même)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="kt">double&lt;/span> &lt;span class="n">x&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">N&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">while&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nb">true&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Calcul de l&amp;#39;estimation suivante : x_new = x - (x^2 - N) / (2x) = (x + N/x) / 2
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="kt">double&lt;/span> &lt;span class="n">x_new&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mf">0.5&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">x&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="n">N&lt;/span> &lt;span class="o">/&lt;/span> &lt;span class="n">x&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Si le changement est inférieur à la marge d&amp;#39;erreur (tolerance), on considère qu&amp;#39;il a convergé
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">abs&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">x&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="n">x_new&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">&amp;lt;&lt;/span> &lt;span class="n">tolerance&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">break&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">x&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">x_new&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">x&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kt">int&lt;/span> &lt;span class="nf">main&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">double&lt;/span> &lt;span class="n">number&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mf">612.0&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;Square root of &amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">number&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34; is: &amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">newton_sqrt&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">number&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="s">&amp;#34;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>&lt;strong>Explication détaillée&lt;/strong> :
Le plus grand attrait de la méthode de Newton est que, si les conditions sont réunies, elle présente une &amp;ldquo;convergence quadratique&amp;rdquo; (Quadratic convergence). Cela signifie une vitesse de convergence phénoménale où le nombre de chiffres corrects double approximativement à chaque itération. Si l&amp;rsquo;on considère que la recherche binaire (dichotomie) a une convergence linéaire, on se rend compte de la puissance de l&amp;rsquo;utilisation de l&amp;rsquo;information de la dérivée (faible pente). Le hack de &amp;ldquo;Quake III&amp;rdquo; utilisait un nombre magique d&amp;rsquo;opérations bit à bit &lt;code>0x5f3759df&lt;/code> pour pirater la structure du nombre à virgule flottante IEEE 754 afin d&amp;rsquo;obtenir la valeur initiale de la méthode de Newton avec une précision stupéfiante.&lt;/p>
&lt;hr>
&lt;h2 id="8-courbes-de-bézier-bézier-curves">8. Courbes de Bézier (Bézier Curves)
&lt;/h2>&lt;h3 id="beauté-de-la-formule-et-aperçu-7">Beauté de la formule et aperçu
&lt;/h3>&lt;p>C&amp;rsquo;est une équation paramétrique qui définit une courbe lisse à l&amp;rsquo;aide de plusieurs points de contrôle (Control Points). La courbe de Bézier cubique (Cubic Bézier Curve) la plus couramment utilisée possède quatre points $P_0, P_1, P_2, P_3$ et détermine les coordonnées $B(t)$ sur la courbe en fonction du paramètre $t \ (0 \le t \le 1)$.&lt;/p>
$$ B(t) = (1-t)^3 P_0 + 3(1-t)^2 t P_1 + 3(1-t) t^2 P_2 + t^3 P_3 $$
&lt;h3 id="applications-en-programmation-7">Applications en programmation
&lt;/h3>&lt;p>Les courbes de Bézier sont le fondement de l&amp;rsquo;infographie. Elles sont utilisées chaque fois que vous souhaitez dessiner des &amp;ldquo;mouvements ou des formes lisses&amp;rdquo; par programme, comme dans les outils de dessin vectoriel comme Adobe Illustrator, le rendu de polices (TrueType ou OpenType), les fonctions d&amp;rsquo;assouplissement (easing) des transitions et animations CSS (&lt;code>cubic-bezier()&lt;/code>), et le contrôle de la trajectoire de la caméra dans les jeux.&lt;/p>
&lt;h3 id="exemple-dimplémentation-python-5">Exemple d&amp;rsquo;implémentation (Python)
&lt;/h3>&lt;p>Voici un code qui génère un groupe de points sur une courbe de Bézier cubique à partir de quatre points de contrôle.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;span class="lnt">31
&lt;/span>&lt;span class="lnt">32
&lt;/span>&lt;span class="lnt">33
&lt;/span>&lt;span class="lnt">34
&lt;/span>&lt;span class="lnt">35
&lt;/span>&lt;span class="lnt">36
&lt;/span>&lt;span class="lnt">37
&lt;/span>&lt;span class="lnt">38
&lt;/span>&lt;span class="lnt">39
&lt;/span>&lt;span class="lnt">40
&lt;/span>&lt;span class="lnt">41
&lt;/span>&lt;span class="lnt">42
&lt;/span>&lt;span class="lnt">43
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">cubic_bezier&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">p0&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">p1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">p2&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">p3&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">steps&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">10&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;&amp;#34;&amp;#34;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> Génère une liste de coordonnées sur une courbe de Bézier cubique.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> p0, p1, p2, p3 sont des tuples (x, y).
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> steps indique en combien de segments la courbe doit être divisée.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> &amp;#34;&amp;#34;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">curve_points&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">[]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="nb">range&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">steps&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Le paramètre t varie de 0.0 à 1.0&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">t&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="o">/&lt;/span> &lt;span class="n">steps&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Calcul des coefficients composant la formule&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">u&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">1&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="n">t&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">tt&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">t&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">t&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">uu&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">u&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">u&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">uuu&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">uu&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">u&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">ttt&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">tt&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">t&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Calcul des coordonnées x et y pour chaque point&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">x&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">uuu&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">p0&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">])&lt;/span> &lt;span class="o">+&lt;/span> \
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">(&lt;/span>&lt;span class="mi">3&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">uu&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">t&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">p1&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">])&lt;/span> &lt;span class="o">+&lt;/span> \
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">(&lt;/span>&lt;span class="mi">3&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">u&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">tt&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">p2&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">])&lt;/span> &lt;span class="o">+&lt;/span> \
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">(&lt;/span>&lt;span class="n">ttt&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">p3&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">])&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">y&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">uuu&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">p0&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">])&lt;/span> &lt;span class="o">+&lt;/span> \
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">(&lt;/span>&lt;span class="mi">3&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">uu&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">t&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">p1&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">])&lt;/span> &lt;span class="o">+&lt;/span> \
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">(&lt;/span>&lt;span class="mi">3&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">u&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">tt&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">p2&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">])&lt;/span> &lt;span class="o">+&lt;/span> \
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">(&lt;/span>&lt;span class="n">ttt&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">p3&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">])&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">curve_points&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">append&lt;/span>&lt;span class="p">((&lt;/span>&lt;span class="n">x&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">y&lt;/span>&lt;span class="p">))&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">curve_points&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Point de départ, point de contrôle 1, point de contrôle 2, point d&amp;#39;arrivée&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">p0&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">p1&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="mi">5&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">10&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">p2&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="mi">15&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">10&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">p3&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="mi">20&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">points&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">cubic_bezier&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">p0&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">p1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">p2&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">p3&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">steps&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">5&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">for&lt;/span> &lt;span class="n">i&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">pt&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="nb">enumerate&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">points&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;t=&lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="o">/&lt;/span>&lt;span class="mi">5&lt;/span>&lt;span class="si">:&lt;/span>&lt;span class="s2">.1f&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2"> -&amp;gt; Point(&lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">pt&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="si">:&lt;/span>&lt;span class="s2">.2f&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">, &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">pt&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="si">:&lt;/span>&lt;span class="s2">.2f&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">)&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>&lt;strong>Explication détaillée&lt;/strong> :
Cette formule est un développement de l&amp;rsquo;&amp;ldquo;algorithme de De Casteljau&amp;rdquo; (De Casteljau&amp;rsquo;s algorithm), qui applique récursivement l&amp;rsquo;interpolation linéaire (Lerp: Linear Interpolation). Elle calcule la solution directement à l&amp;rsquo;aide de polynômes (polynômes de Bernstein). En programmation, une courbe est dessinée approximativement comme un ensemble d&amp;rsquo;innombrables &amp;ldquo;lignes droites minuscules&amp;rdquo;. Par conséquent, en ajustant la résolution de $t$ (steps), on contrôle l&amp;rsquo;équilibre entre les performances et la qualité du rendu.&lt;/p>
&lt;hr>
&lt;h2 id="9-fonction-sigmoïde-sigmoid-function">9. Fonction sigmoïde (Sigmoid Function)
&lt;/h2>&lt;h3 id="beauté-de-la-formule-et-aperçu-8">Beauté de la formule et aperçu
&lt;/h3>&lt;p>C&amp;rsquo;est une fonction lisse en forme de S qui compresse toujours toute entrée de nombre réel $x \ ( -\infty &lt; x &lt; \infty )$ en une valeur comprise entre $0$ et $1$.&lt;/p>
$$ \sigma(x) = \frac{1}{1 + e^{-x}} $$
&lt;h3 id="applications-en-programmation-8">Applications en programmation
&lt;/h3>&lt;p>Elle a joué un rôle historiquement très important dans la régression logistique et comme &amp;ldquo;fonction d&amp;rsquo;activation&amp;rdquo; (Activation Function) dans les réseaux de neurones (Deep Learning). Son plus grand avantage est que la sortie est comprise entre 0 et 1, ce qui permet d&amp;rsquo;interpréter le résultat comme une &amp;ldquo;probabilité&amp;rdquo;.&lt;/p>
&lt;div class="mermaid">graph LR
X1["Entrée x1"] -->|Poids w1| Sum["Somme : Σ(wi*xi) + b"]
X2["Entrée x2"] -->|Poids w2| Sum
Sum --> Act["Fonction sigmoïde : σ(x)"]
Act --> Out["Probabilité de sortie (0 à 1)"]&lt;/div>
&lt;h3 id="exemple-dimplémentation-python-6">Exemple d&amp;rsquo;implémentation (Python)
&lt;/h3>&lt;p>Voici un code qui applique la fonction sigmoïde à un tableau (tenseur) en entrée.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">math&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">sigmoid&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">x&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;&amp;#34;&amp;#34;Calcul de la sigmoïde pour une seule valeur&amp;#34;&amp;#34;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># On limite souvent la valeur d&amp;#39;entrée pour éviter que math.exp(-x) ne produise un dépassement (overflow)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Implémentation standard simplifiée&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="n">x&lt;/span> &lt;span class="o">&amp;gt;=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="mf">1.0&lt;/span> &lt;span class="o">/&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="mf">1.0&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="n">math&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">exp&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="n">x&lt;/span>&lt;span class="p">))&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">else&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Mesure contre le dépassement lorsque x est une grande valeur négative&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">math&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">exp&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">x&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">/&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="mf">1.0&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="n">math&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">exp&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">x&lt;/span>&lt;span class="p">))&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">apply_sigmoid&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">array&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;&amp;#34;&amp;#34;Applique la fonction sigmoïde à tous les éléments d&amp;#39;un tableau&amp;#34;&amp;#34;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="n">sigmoid&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">x&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="k">for&lt;/span> &lt;span class="n">x&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="n">array&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Données brutes de la couche de sortie du réseau de neurones (logits)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">logits&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="mf">5.0&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="o">-&lt;/span>&lt;span class="mf">1.0&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mf">0.0&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mf">1.0&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mf">5.0&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">probabilities&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">apply_sigmoid&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">logits&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">for&lt;/span> &lt;span class="n">val&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">prob&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="nb">zip&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">logits&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">probabilities&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;Input: &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">val&lt;/span>&lt;span class="si">:&lt;/span>&lt;span class="s2">4.1f&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2"> -&amp;gt; Probability: &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">prob&lt;/span>&lt;span class="si">:&lt;/span>&lt;span class="s2">.4f&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>&lt;strong>Explication détaillée&lt;/strong> :
La ramification conditionnelle avec &lt;code>x &amp;gt;= 0&lt;/code> et le reste dans le code ci-dessus est pour éviter un problème spécifique à la programmation appelé &amp;ldquo;dépassement de capacité&amp;rdquo; (overflow). Si $x = -1000$ par exemple, c&amp;rsquo;est une technique de calcul numérique pour empêcher le programme de planter (ou de renvoyer Inf) en essayant de calculer $e^{1000}$. Actuellement, dans les couches intermédiaires du Deep Learning, ReLU ($f(x) = \max(0, x)$) est devenu dominant du point de vue de la vitesse de calcul et du problème de disparition du gradient, mais pour la couche de sortie de la classification binaire, la fonction sigmoïde conserve toujours une position inébranlable.&lt;/p>
&lt;hr>
&lt;h2 id="10-distance-euclidienne-et-théorème-de-pythagore-euclidean-distance--pythagorean-theorem">10. Distance euclidienne et théorème de Pythagore (Euclidean Distance &amp;amp; Pythagorean Theorem)
&lt;/h2>&lt;h3 id="beauté-de-la-formule-et-aperçu-9">Beauté de la formule et aperçu
&lt;/h3>&lt;p>C&amp;rsquo;est le fondement de la géométrie hérité de la Grèce antique, et une équation qui définit la distance en ligne droite entre deux points dans un espace à $n$ dimensions. Dans l&amp;rsquo;espace bidimensionnel, il s&amp;rsquo;agit du théorème de Pythagore ($a^2 + b^2 = c^2$) lui-même.&lt;/p>
&lt;p>La distance euclidienne $d$ entre un point $P(x_1, y_1, z_1)$ et $Q(x_2, y_2, z_2)$ dans un espace tridimensionnel s&amp;rsquo;exprime comme suit :&lt;/p>
$$ d = \sqrt{(x_2-x_1)^2 + (y_2-y_1)^2 + (z_2-z_1)^2} $$
&lt;h3 id="applications-en-programmation-9">Applications en programmation
&lt;/h3>&lt;p>C&amp;rsquo;est le calcul au cœur du développement de tous les jeux, des moteurs physiques et des algorithmes d&amp;rsquo;apprentissage automatique tels que la méthode des &amp;ldquo;K plus proches voisins&amp;rdquo; (K-Nearest Neighbors) ou le regroupement (K-Means). Dans les jeux, il est calculé des millions de fois à chaque image pour la détection de collisions entre personnages (Bounding Circle / Sphere Collision).&lt;/p>
&lt;h3 id="exemple-dimplémentation-c-2">Exemple d&amp;rsquo;implémentation (C++)
&lt;/h3>&lt;p>Voici un code optimisé pour déterminer si deux cercles (ou sphères) sont en collision.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;span class="lnt">31
&lt;/span>&lt;span class="lnt">32
&lt;/span>&lt;span class="lnt">33
&lt;/span>&lt;span class="lnt">34
&lt;/span>&lt;span class="lnt">35
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;iostream&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;cmath&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">struct&lt;/span> &lt;span class="nc">Circle&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">double&lt;/span> &lt;span class="n">x&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">y&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="c1">// Coordonnées du centre
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="kt">double&lt;/span> &lt;span class="n">radius&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="c1">// Rayon
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// Fonction pour déterminer si deux cercles entrent en collision
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="kt">bool&lt;/span> &lt;span class="nf">isColliding&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">const&lt;/span> &lt;span class="n">Circle&lt;/span>&lt;span class="o">&amp;amp;&lt;/span> &lt;span class="n">a&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="k">const&lt;/span> &lt;span class="n">Circle&lt;/span>&lt;span class="o">&amp;amp;&lt;/span> &lt;span class="n">b&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Différence des coordonnées x et y (delta)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="kt">double&lt;/span> &lt;span class="n">dx&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">b&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">x&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="n">a&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">x&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">double&lt;/span> &lt;span class="n">dy&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">b&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">y&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="n">a&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">y&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Calculer le &amp;#34;carré&amp;#34; de la distance
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="kt">double&lt;/span> &lt;span class="n">distanceSquared&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">dx&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">dx&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">dy&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">dy&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Calculer le &amp;#34;carré&amp;#34; de la somme des rayons
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="kt">double&lt;/span> &lt;span class="n">radiiSum&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">a&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">radius&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="n">b&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">radius&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">double&lt;/span> &lt;span class="n">radiiSumSquared&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">radiiSum&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">radiiSum&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Comparer le carré de la distance avec le carré de la somme des rayons
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">return&lt;/span> &lt;span class="n">distanceSquared&lt;/span> &lt;span class="o">&amp;lt;=&lt;/span> &lt;span class="n">radiiSumSquared&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kt">int&lt;/span> &lt;span class="nf">main&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">Circle&lt;/span> &lt;span class="n">player&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span>&lt;span class="mf">0.0&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mf">0.0&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mf">5.0&lt;/span>&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">Circle&lt;/span> &lt;span class="n">enemy1&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span>&lt;span class="mf">8.0&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mf">0.0&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mf">4.0&lt;/span>&lt;span class="p">};&lt;/span> &lt;span class="c1">// Distance de 8, somme des rayons de 9 -&amp;gt; Collision
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">Circle&lt;/span> &lt;span class="n">enemy2&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span>&lt;span class="mf">10.0&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mf">10.0&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mf">2.0&lt;/span>&lt;span class="p">};&lt;/span> &lt;span class="c1">// Distance d&amp;#39;environ 14.1, somme des rayons de 7 -&amp;gt; Pas de collision
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;Collision with enemy1: &amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">isColliding&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">player&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">enemy1&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">?&lt;/span> &lt;span class="s">&amp;#34;Yes&amp;#34;&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="s">&amp;#34;No&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="s">&amp;#34;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;Collision with enemy2: &amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">isColliding&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">player&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">enemy2&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">?&lt;/span> &lt;span class="s">&amp;#34;Yes&amp;#34;&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="s">&amp;#34;No&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="s">&amp;#34;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>&lt;strong>Explication détaillée&lt;/strong> :
Si vous calculez exactement selon la formule mathématique, vous devez prendre la racine carrée $\sqrt{\cdot}$ à la fin, mais en programmation, l&amp;rsquo;appel à la fonction &lt;code>sqrt()&lt;/code> est un processus très lourd pour le CPU (qui consomme de nombreux cycles d&amp;rsquo;horloge). Par conséquent, s&amp;rsquo;il s&amp;rsquo;agit uniquement de comparer des distances, &lt;strong>les comparer en gardant les deux côtés au carré&lt;/strong> (&lt;code>distanceSquared &amp;lt;= radiiSumSquared&lt;/code>) est une pratique courante dans la programmation de jeux. Ainsi, l&amp;rsquo;optimisation visant à réduire la charge de calcul en utilisant les propriétés des équations et des inégalités mathématiques est le véritable plaisir de la conception d&amp;rsquo;algorithmes.&lt;/p>
&lt;hr>
&lt;h2 id="conclusion">Conclusion
&lt;/h2>&lt;p>Qu&amp;rsquo;en pensez-vous ? De l&amp;rsquo;identité d&amp;rsquo;Euler au théorème de Pythagore, ces 10 formules ne sont pas simplement des concepts théoriques que l&amp;rsquo;on trouve dans les manuels. Elles battent comme le &amp;ldquo;cœur&amp;rdquo; derrière le code que nous écrivons habituellement, pour compresser des données, faire des prédictions à l&amp;rsquo;aide de modèles d&amp;rsquo;apprentissage automatique, dessiner des animations fluides et permettre des recherches rapides.&lt;/p>
&lt;p>Comprendre le contexte mathématique est essentiel pour passer du statut de codeur qui se contente d&amp;rsquo;appeler des bibliothèques existantes (&lt;code>math.sin&lt;/code> ou &lt;code>numpy.fft&lt;/code>) à celui d&amp;rsquo;ingénieur capable d&amp;rsquo;en comprendre la structure interne et d&amp;rsquo;en repousser les limites. La prochaine fois que vous écrirez du code, essayez d&amp;rsquo;imaginer un instant quelles magnifiques formules mathématiques opèrent en arrière-plan.&lt;/p>
&lt;p>&lt;strong>Happy Coding and Math!&lt;/strong>&lt;/p></description></item><item><title>Limites de la factorisation en nombres premiers et explication de la notation Grand O (O)</title><link>http://kenji.blog/fr/p/prime-factorization-limits-big-o-notation/</link><pubDate>Fri, 11 Sep 2026 23:00:00 +0900</pubDate><guid>http://kenji.blog/fr/p/prime-factorization-limits-big-o-notation/</guid><description>&lt;img src="http://kenji.blog/p/prime-factorization-limits-big-o-notation/img/eyecatch.jpg" alt="Featured image of post Limites de la factorisation en nombres premiers et explication de la notation Grand O (O)" />&lt;h1 id="introduction--pourquoi-la-factorisation-en-nombres-premiers-est-elle--difficile--">Introduction : Pourquoi la factorisation en nombres premiers est-elle « difficile » ?
&lt;/h1>&lt;p>Dans la société Internet moderne, si nous pouvons faire des achats en ligne en toute tranquillité et échanger des informations confidentielles, c&amp;rsquo;est grâce à l&amp;rsquo;existence de la « cryptographie ». Et la sécurité de cette cryptographie (en particulier le chiffrement RSA, largement utilisé) repose sur un fait mathématique : « la factorisation de très grands nombres entiers en nombres premiers est extrêmement difficile ».&lt;/p>
&lt;p>À première vue, la factorisation en nombres premiers peut sembler être une tâche simple consistant « juste à décomposer un nombre en produits de nombres premiers ». Cependant, lorsque le nombre de chiffres devient important, cela se transforme en un problème tellement complexe que même les superordinateurs les plus rapides du monde, fonctionnant pendant des décennies ou des siècles, ne pourraient le résoudre. La factorisation que nous apprenons à l&amp;rsquo;école est au mieux une tâche simple consistant à diviser par $2$, $3$ ou $5$, mais face au produit de deux nombres premiers inconnus de plusieurs centaines de chiffres, cette approche simpliste s&amp;rsquo;effondre complètement.&lt;/p>
&lt;p>Dans cet article, en partant du concept de « complexité algorithmique (notation Grand O : $\mathcal{O}$) », qui est la base de l&amp;rsquo;informatique, nous expliquerons en détail et mathématiquement combien de temps de calcul nécessitent divers algorithmes de factorisation (méthode des divisions successives, algorithme $\rho$ de Pollard, crible du corps de nombres généralisé, etc.). Ensuite, nous analyserons pourquoi la factorisation de nombres géants est pratiquement impossible sur des ordinateurs classiques, comment cela protège nos informations et notre vie privée, et enfin, comment les ordinateurs quantiques pourraient bouleverser ce paradigme.&lt;/p>
&lt;hr>
&lt;h1 id="définition-rigoureuse-de-la-complexité-algorithmique-et-de-la-notation-grand-o-mathcalo">Définition rigoureuse de la complexité algorithmique et de la notation Grand O ($\mathcal{O}$)
&lt;/h1>&lt;p>Lors de l&amp;rsquo;évaluation des performances ou de l&amp;rsquo;efficacité d&amp;rsquo;un algorithme, il ne suffit pas de mesurer simplement le « temps d&amp;rsquo;exécution (en secondes) » du programme. En effet, le temps d&amp;rsquo;exécution dépend fortement des performances de l&amp;rsquo;ordinateur utilisé (fréquence d&amp;rsquo;horloge du processeur, vitesse de la mémoire, etc.), du langage de programmation et des optimisations du compilateur.&lt;/p>
&lt;p>Par conséquent, l&amp;rsquo;indicateur d&amp;rsquo;évaluation universel indépendant du matériel et de l&amp;rsquo;environnement est la &lt;strong>complexité temporelle (Time Complexity)&lt;/strong>, et la notation utilisée pour l&amp;rsquo;exprimer est la &lt;strong>notation Grand O (Big-O Notation)&lt;/strong>. La notation Grand O est une écriture mathématique qui décrit comment le temps d&amp;rsquo;exécution (ou le nombre d&amp;rsquo;étapes d&amp;rsquo;exécution) d&amp;rsquo;un algorithme augmente par rapport à la taille des données d&amp;rsquo;entrée $N$ lorsque celle-ci devient très grande (taux de croissance asymptotique).&lt;/p>
&lt;h2 id="définition-mathématique-de-la-notation-asymptotique">Définition mathématique de la notation asymptotique
&lt;/h2>&lt;p>En informatique, pour les fonctions $f(n)$ et $g(n)$, l&amp;rsquo;expression $f(n) = \mathcal{O}(g(n))$ est définie mathématiquement comme suit :&lt;/p>
$$ \exists c > 0, \exists n_0 > 0 \text{ s.t. } \forall n \ge n_0, 0 \le f(n) \le c \cdot g(n) $$
&lt;p>Cela signifie que « lorsque la taille de l&amp;rsquo;entrée $n$ est suffisamment grande ($n \ge n_0$), la croissance de la fonction $f(n)$ est bornée supérieurement par $g(n)$ multipliée par une constante ». En d&amp;rsquo;autres termes, cela indique une « borne supérieure (Upper Bound) », garantissant que même dans le pire des cas, le temps de traitement de l&amp;rsquo;algorithme restera dans une constante multipliée par $g(n)$.&lt;/p>
&lt;p>De même, il existe la notation $\Omega$ (Grand Oméga) pour indiquer une borne inférieure, et $\Theta$ (Grand Thêta) lorsque les bornes supérieure et inférieure coïncident. Cependant, la notation $\mathcal{O}$ est la plus fréquemment utilisée pour discuter de la complexité dans le pire des cas d&amp;rsquo;un algorithme.&lt;/p>
&lt;h2 id="classes-de-complexité-représentatives">Classes de complexité représentatives
&lt;/h2>&lt;p>Il existe plusieurs classes représentatives de complexité algorithmique. Examinons-les dans l&amp;rsquo;ordre, du temps d&amp;rsquo;exécution le plus court (le plus efficace) au plus long.&lt;/p>
&lt;ol>
&lt;li>
&lt;p>&lt;strong>$\mathcal{O}(1)$ : Temps constant (Constant time)&lt;/strong>
Un algorithme dont le temps d&amp;rsquo;exécution ne change pas, quelle que soit la taille de l&amp;rsquo;entrée $N$. Par exemple, l&amp;rsquo;accès à une valeur en spécifiant l&amp;rsquo;index d&amp;rsquo;un tableau, ou la recherche dans une table de hachage (dans le cas idéal).&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>$\mathcal{O}(\log N)$ : Temps logarithmique (Logarithmic time)&lt;/strong>
Un algorithme très efficace où même si la taille de l&amp;rsquo;entrée double, le temps d&amp;rsquo;exécution n&amp;rsquo;augmente que d&amp;rsquo;une constante. La « recherche dichotomique (Binary Search) », qui recherche une valeur cible dans un tableau trié, en est un exemple typique. Même avec un milliard de données, il suffit d&amp;rsquo;environ 30 comparaisons pour trouver la donnée souhaitée.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>$\mathcal{O}(N)$ : Temps linéaire (Linear time)&lt;/strong>
Le temps d&amp;rsquo;exécution augmente proportionnellement à la taille de l&amp;rsquo;entrée. Si les données sont multipliées par 10, le temps sera également multiplié par 10. La « recherche linéaire », qui vérifie tous les éléments d&amp;rsquo;un tableau dans l&amp;rsquo;ordre, correspond à ce cas.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>$\mathcal{O}(N \log N)$ : Temps quasi-linéaire (Linearithmic time)&lt;/strong>
Un peu plus lent que $\mathcal{O}(N)$, mais toujours considéré comme efficace. De nombreux algorithmes de tri rapide pratiques, tels que le tri fusion (Merge Sort) et le tri rapide (Quick Sort, complexité moyenne), ont cette complexité.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>$\mathcal{O}(N^2)$ : Temps polynomial / Temps quadratique (Quadratic time)&lt;/strong>
Lorsque la taille de l&amp;rsquo;entrée double, le temps d&amp;rsquo;exécution quadruple ; si elle est multipliée par 10, il est multiplié par 100. Les traitements simples utilisant des boucles imbriquées, le tri à bulles ou le tri par insertion en font partie. Si la quantité de données dépasse plusieurs dizaines de milliers, le traitement commence à prendre beaucoup de temps. Ces complexités exprimées sous la forme $\mathcal{O}(N^k)$ sont collectivement appelées &lt;strong>temps polynomial (Polynomial time)&lt;/strong>.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>$\mathcal{O}(2^N)$ : Temps exponentiel (Exponential time)&lt;/strong>
Il suffit que la taille de l&amp;rsquo;entrée augmente de 1 pour que le temps d&amp;rsquo;exécution double. C&amp;rsquo;est extrêmement inefficace : dès que $N$ atteint 40 ou 50, même les ordinateurs de pointe ne peuvent plus terminer le calcul dans un temps réaliste. La recherche exhaustive du problème du sac à dos, ou la solution naïve du problème du voyageur de commerce en sont des exemples.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>$\mathcal{O}(N!)$ : Temps factoriel (Factorial time)&lt;/strong>
Il augmente encore plus rapidement que $\mathcal{O}(2^N)$. C&amp;rsquo;est le cas d&amp;rsquo;un algorithme qui testerait toutes les permutations possibles pour le problème du voyageur de commerce.&lt;/p>
&lt;/li>
&lt;/ol>
&lt;p>Le diagramme Mermaid ci-dessous est une comparaison schématique du taux d&amp;rsquo;augmentation du temps d&amp;rsquo;exécution (nombre d&amp;rsquo;étapes) pour chaque classe de complexité par rapport à l&amp;rsquo;augmentation de $N$.&lt;/p>
&lt;div class="mermaid">graph TD
classDef poly fill:#a8e6cf,stroke:#333,stroke-width:2px;
classDef subexp fill:#ffd3b6,stroke:#333,stroke-width:2px;
classDef exp fill:#ffaaa5,stroke:#333,stroke-width:2px;
Poly["Temps Polynomial O(n^k)"]:::poly
SubExp["Temps Sous-exponentiel L_n"]:::subexp
Exp["Temps Exponentiel O(2^n)"]:::exp
GNFS["Crible du Corps de Nombres Généralisé (GNFS)"]:::subexp
Pollard["Algorithme rho de Pollard"]:::exp
Trial["Méthode des Divisions Successives"]:::exp
Easy["Réalisable (Faisable)"]:::poly
Hard["Intraitable (Difficile)"]:::exp
Poly --- Easy
Exp --- Hard
Trial --> Exp
Pollard --> Exp
GNFS --> SubExp
Poly -.-> SubExp
SubExp -.-> Exp&lt;/div>
&lt;p>Vous comprenez désormais à quel point la différence de complexité est cruciale dans le choix d&amp;rsquo;un algorithme. En cryptographie, la sécurité est garantie en utilisant intentionnellement des problèmes qui nécessitent un « temps exponentiel » ou une « complexité proche » (c&amp;rsquo;est-à-dire des problèmes qui ne peuvent pas être résolus facilement).&lt;/p>
&lt;hr>
&lt;h1 id="mécanisme-du-chiffrement-rsa-et-le-problème-de-la-factorisation-en-nombres-premiers">Mécanisme du chiffrement RSA et le problème de la factorisation en nombres premiers
&lt;/h1>&lt;p>Pour comprendre pourquoi la factorisation en nombres premiers est importante, rappelons brièvement le fonctionnement du chiffrement RSA. Le chiffrement RSA est un système de cryptographie à clé publique développé en 1977 par Ronald Rivest, Adi Shamir et Leonard Adleman.&lt;/p>
&lt;h3 id="étapes-de-génération-des-clés">Étapes de génération des clés
&lt;/h3>&lt;ol>
&lt;li>Deux très grands nombres premiers $p$ et $q$ sont choisis au hasard (par exemple, chacun d&amp;rsquo;une longueur de 1024 bits).&lt;/li>
&lt;li>Ils sont multipliés pour calculer $N = p \times q$. Ce $N$ est publié dans le monde entier comme faisant partie de la clé publique (il aura une longueur de 2048 bits).&lt;/li>
&lt;li>L&amp;rsquo;indicatrice d&amp;rsquo;Euler $\phi(N) = (p-1)(q-1)$ est calculée.&lt;/li>
&lt;li>Un entier $e$ premier avec $\phi(N)$ est choisi et devient également une partie de la clé publique.&lt;/li>
&lt;li>Une clé privée $d$ est calculée de sorte que $e \times d \equiv 1 \pmod{\phi(N)}$.&lt;/li>
&lt;/ol>
&lt;p>Le point crucial ici est le fait que &lt;strong>« pour déchiffrer le message, la clé privée $d$ est nécessaire ; pour calculer $d$, $\phi(N)$ est nécessaire ; et pour calculer $\phi(N)$, il faut factoriser $N$ en $p$ et $q$ »&lt;/strong>.&lt;/p>
&lt;p>La multiplication de très grands nombres premiers $p \times q$ se fait en un instant, mais retrouver les $p$ et $q$ d&amp;rsquo;origine à partir du résultat $N$ (factorisation en nombres premiers) est désespérément difficile. Cette nature de « fonction à sens unique (One-way function) » est le cœur même du chiffrement RSA.&lt;/p>
&lt;p>Il y a un point très important à noter ici. La « taille de l&amp;rsquo;entrée $n$ » dans le problème de la factorisation n&amp;rsquo;est pas la grandeur du nombre $N$ lui-même, mais le « nombre de bits nécessaires pour représenter le nombre $N$ ».
Si $n$ est le nombre de chiffres lors de la représentation de l&amp;rsquo;entier $N$ en binaire, alors $n \approx \log_2 N$. En d&amp;rsquo;autres termes, la complexité de l&amp;rsquo;algorithme doit être évaluée par rapport à $n = \log_2 N$ (ou $\ln N$), et non à $N$.&lt;/p>
&lt;hr>
&lt;h1 id="histoire-des-algorithmes-de-factorisation-en-nombres-premiers-et-leur-complexité">Histoire des algorithmes de factorisation en nombres premiers et leur complexité
&lt;/h1>&lt;p>À partir d&amp;rsquo;ici, nous expliquerons en détail le fonctionnement et la complexité des divers algorithmes utilisés pour décomposer un nombre composé donné $N$ en produit de nombres premiers. C&amp;rsquo;est aussi l&amp;rsquo;histoire de la façon dont l&amp;rsquo;humanité a défié les limites de la factorisation.&lt;/p>
&lt;h2 id="1-méthode-des-divisions-successives-trial-division">1. Méthode des divisions successives (Trial Division)
&lt;/h2>&lt;p>L&amp;rsquo;algorithme le plus intuitif et primitif est la « méthode des divisions successives ». Il consiste à essayer de diviser $N$ par des nombres premiers dans l&amp;rsquo;ordre, à partir de $2$.&lt;/p>
&lt;h3 id="aperçu-de-lalgorithme">Aperçu de l&amp;rsquo;algorithme
&lt;/h3>&lt;p>Il tire parti de la propriété selon laquelle les facteurs premiers de $N$ ne dépasseront jamais $\sqrt{N}$ (puisque $\sqrt{N} \times \sqrt{N} = N$, s&amp;rsquo;il existait un facteur premier plus grand, il serait nécessairement associé à un facteur premier inférieur ou égal à $\sqrt{N}$).
Par conséquent, on vérifie si $N$ est divisible par tous les nombres (ou nombres premiers) jusqu&amp;rsquo;à $\lfloor\sqrt{N}\rfloor$ : $2, 3, 5, 7, \dots$.&lt;/p>
&lt;h3 id="évaluation-de-la-complexité">Évaluation de la complexité
&lt;/h3>&lt;p>Dans le pire des cas (par exemple, si $N$ est le produit de deux très grands nombres premiers), il faut effectuer des divisions jusqu&amp;rsquo;à $\sqrt{N}$.
Comme mentionné précédemment, la taille de l&amp;rsquo;entrée $n$ est $n = \log_2 N$, on peut donc exprimer $N = 2^n$.
Ainsi, le nombre maximal d&amp;rsquo;étapes de calcul est proportionnel à :&lt;/p>
$$ \sqrt{N} = \sqrt{2^n} = (2^n)^{1/2} = 2^{n/2} $$
&lt;p>Cela signifie que pour une longueur de bit $n$, la complexité est &lt;strong>$\mathcal{O}(2^{n/2})$&lt;/strong>. Autrement dit, la méthode des divisions successives est un algorithme à &lt;strong>« temps exponentiel pur (Exponential time) »&lt;/strong> par rapport à $n$.
Chaque fois que le nombre de bits augmente de 1 (le nombre double), le temps de calcul est multiplié par environ $\sqrt{2} \approx 1,414$. Si $N$ est un nombre dépassant 1024 bits (environ 300 chiffres en décimal), même en y consacrant un temps égal à l&amp;rsquo;âge de l&amp;rsquo;univers, le calcul ne s&amp;rsquo;achèverait pas.&lt;/p>
&lt;h2 id="2-méthode-de-factorisation-de-fermat-fermats-factorization-method">2. Méthode de factorisation de Fermat (Fermat&amp;rsquo;s Factorization Method)
&lt;/h2>&lt;p>Il s&amp;rsquo;agit d&amp;rsquo;une méthode inventée par le mathématicien du 17ème siècle, Pierre de Fermat. Étant donné un nombre composé impair $N$, on tente de représenter $N$ comme la différence de deux carrés.&lt;/p>
$$ N = x^2 - y^2 = (x - y)(x + y) $$
&lt;p>Si l&amp;rsquo;on trouve de tels $x$ et $y$, alors $a = x - y$ et $b = x + y$ seront les facteurs de $N$.
Dans l&amp;rsquo;algorithme, on augmente $x$ progressivement à partir de $\lceil \sqrt{N} \rceil$ et on vérifie si $x^2 - N$ est un carré parfait (le carré d&amp;rsquo;un entier $y$).
Cette méthode fonctionne de manière extrêmement rapide lorsque les deux facteurs premiers $p$ et $q$ sont très proches en valeur. Cependant, dans le cas général (où $p$ et $q$ ont des valeurs aléatoirement distantes), elle nécessite finalement un temps exponentiel similaire à celui de la méthode des divisions successives.&lt;/p>
&lt;h2 id="3-algorithme-rho-de-pollard-pollards-rho-algorithm">3. Algorithme $\rho$ de Pollard (Pollard&amp;rsquo;s rho algorithm)
&lt;/h2>&lt;p>L&amp;rsquo;un des algorithmes conçus pour dépasser les limites de la méthode des divisions successives est « l&amp;rsquo;algorithme $\rho$ (rho) de Pollard », publié par John Pollard en 1975.&lt;/p>
&lt;h3 id="aperçu-de-lalgorithme-1">Aperçu de l&amp;rsquo;algorithme
&lt;/h3>&lt;p>Cette méthode applique un concept probabiliste appelé « paradoxe des anniversaires (Birthday Paradox) » et la périodicité des suites pseudo-aléatoires (qui ressemble à la forme de la lettre grecque $\rho$, d&amp;rsquo;où son nom).&lt;/p>
&lt;p>En utilisant une certaine fonction génératrice de nombres pseudo-aléatoires $f(x) = (x^2 + 1) \pmod N$, on génère une suite et on cherche deux valeurs dans la suite telles que $x_i \equiv x_j \pmod p$ (où $p$ est un facteur premier inconnu de $N$).
À ce stade, comme $x_i - x_j$ est un multiple de $p$, on peut extraire $p$ (c&amp;rsquo;est-à-dire un facteur premier de $N$) avec une forte probabilité en calculant le plus grand commun diviseur $\gcd(|x_i - x_j|, N)$. En combinant cela avec l&amp;rsquo;algorithme de détection de cycle de Robert Floyd (algorithme du lièvre et de la tortue), le calcul se fait efficacement tout en maintenant l&amp;rsquo;utilisation de la mémoire à $\mathcal{O}(1)$.&lt;/p>
&lt;h3 id="évaluation-de-la-complexité-1">Évaluation de la complexité
&lt;/h3>&lt;p>Il est connu que le nombre d&amp;rsquo;étapes nécessaires pour que l&amp;rsquo;algorithme $\rho$ de Pollard trouve un facteur premier $p$ est d&amp;rsquo;environ $\mathcal{O}(\sqrt{p})$.
Dans le pire des cas (lorsque $N$ est le produit de deux nombres premiers $p, q$ de même taille, tel que $p \approx \sqrt{N}$), la complexité est de $\mathcal{O}(N^{1/4})$.&lt;/p>
&lt;p>Exprimé avec la taille d&amp;rsquo;entrée $n = \log_2 N$ :&lt;/p>
$$ N^{1/4} = (2^n)^{1/4} = 2^{n/4} $$
&lt;p>Par conséquent, la complexité est &lt;strong>$\mathcal{O}(2^{n/4})$&lt;/strong>.
Par rapport au $\mathcal{O}(2^{n/2})$ de la méthode des divisions successives, l&amp;rsquo;accélération est spectaculaire, et elle est très puissante en pratique pour factoriser des nombres de taille moyenne (plusieurs dizaines de chiffres). Cependant, elle ne parvient toujours pas à franchir la barrière du « temps exponentiel » par rapport à la longueur de bit $n$, la rendant impuissante face aux nombres gigantesques de 2048 bits (environ 600 chiffres décimaux) utilisés dans le chiffrement RSA.&lt;/p>
&lt;h2 id="4-crible-quadratique-à-polys-multiples-mpqs-multiple-polynomial-quadratic-sieve">4. Crible Quadratique à Polys Multiples (MPQS: Multiple Polynomial Quadratic Sieve)
&lt;/h2>&lt;p>Au début des années 1980, Carl Pomerance a inventé le « crible quadratique (Quadratic Sieve : QS) ». C&amp;rsquo;est une extension du concept de la « différence de carrés » de Fermat.
Alors que la méthode de Fermat cherchait directement $x^2 - y^2 = N$, le crible quadratique recherche une condition beaucoup plus souple.&lt;/p>
$$ x^2 \equiv y^2 \pmod N $$
&lt;p>
et
&lt;/p>
$$ x \not\equiv \pm y \pmod N $$
&lt;p>Si l&amp;rsquo;on peut trouver une telle paire $x, y$, alors $x^2 - y^2 = (x - y)(x + y)$ est un multiple de $N$. Par conséquent, en calculant $\gcd(x - y, N)$ ou $\gcd(x + y, N)$, on peut obtenir un facteur premier non trivial de $N$.&lt;/p>
&lt;p>Dans le crible quadratique, on trouve un grand nombre de $x$ tels que $x^2 \pmod N$ donne un « nombre n&amp;rsquo;ayant que de petits facteurs premiers (ce qu&amp;rsquo;on appelle un nombre $B$-friable) », et on dispose le résultat de leurs factorisations sous forme de matrice (un système d&amp;rsquo;équations linéaires sur le corps fini $\mathbb{F}_2$). Ensuite, on utilise l&amp;rsquo;élimination de Gauss ou des méthodes similaires pour multiplier plusieurs relations entre elles, afin d&amp;rsquo;ajuster le côté droit pour qu&amp;rsquo;il devienne un carré parfait (les exposants de chaque facteur premier deviennent pairs), construisant ainsi $x^2 \equiv y^2 \pmod N$.&lt;/p>
&lt;p>Le crible quadratique fut l&amp;rsquo;algorithme le plus rapide au monde jusqu&amp;rsquo;à l&amp;rsquo;apparition du crible du corps de nombres généralisé, et il est toujours considéré comme le plus rapide pour factoriser des nombres de moins de 100 chiffres.&lt;/p>
&lt;h2 id="5-examen-approfondi-du-crible-du-corps-de-nombres-généralisé-general-number-field-sieve--gnfs">5. Examen approfondi du Crible du Corps de Nombres Généralisé (General Number Field Sieve : GNFS)
&lt;/h2>&lt;p>Actuellement, l&amp;rsquo;algorithme réputé « le plus rapide au monde » pour la factorisation de nombres entiers géants dépassant 100 chiffres est le &lt;strong>crible du corps de nombres généralisé (GNFS)&lt;/strong>. Conçu à la fin des années 1980, il s&amp;rsquo;agit d&amp;rsquo;un algorithme très sophistiqué qui prolonge le crible quadratique en utilisant des résultats profonds de la théorie algébrique des nombres (corps de nombres).&lt;/p>
&lt;p>Dans les attaques contre le chiffrement RSA (factorisation à partir de la clé publique), c&amp;rsquo;est toujours ce GNFS qui bat les records mondiaux. En 2020, on a signalé le succès de la factorisation d&amp;rsquo;un nombre composé de 829 bits (250 chiffres) (RSA-250), mais cela a nécessité l&amp;rsquo;exécution en parallèle de milliers d&amp;rsquo;ordinateurs sur une longue période.&lt;/p>
&lt;h3 id="structure-mathématique-de-lalgorithme">Structure mathématique de l&amp;rsquo;algorithme
&lt;/h3>&lt;p>Le GNFS est extrêmement complexe, mais il se déroule grossièrement selon les étapes suivantes.&lt;/p>
&lt;ol>
&lt;li>
&lt;p>&lt;strong>Sélection du polynôme (Polynomial Selection):&lt;/strong>
Pour $N$, on choisit un entier $m$ et un polynôme irréductible $f(X)$ avec de petits coefficients tel que $f(m) \equiv 0 \pmod N$. Cela définit l&amp;rsquo;anneau des entiers $\mathbb{Z}[\alpha]$ du corps algébrique (corps de nombres) obtenu en ajoutant la racine $\alpha$ de $f(X)$.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>Criblage (Sieving):&lt;/strong>
On recherche des nombres friables (Smooth) simultanément dans « deux mondes différents » : l&amp;rsquo;anneau des entiers rationnels $\mathbb{Z}$ et l&amp;rsquo;anneau des entiers algébriques $\mathbb{Z}[\alpha]$. Concrètement, on trouve un grand nombre de paires $(a, b)$ telles que la norme de l&amp;rsquo;entier rationnel $a - bm$ et de l&amp;rsquo;entier algébrique $a - b\alpha$ se factorisent complètement sur un ensemble de petits nombres premiers prédéfini (la base de facteurs : Factor Base).&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>Réduction de matrice (Matrix Reduction):&lt;/strong>
On représente l&amp;rsquo;énorme quantité de paires friables trouvées sous forme de matrice (une gigantesque matrice creuse). On recherche l&amp;rsquo;espace des solutions sur le corps fini $\mathbb{F}_2$ à l&amp;rsquo;aide de l&amp;rsquo;algorithme de Lanczos (comme la méthode de Lanczos par blocs). Il n&amp;rsquo;est pas rare que cette matrice atteigne des millions de lignes sur des millions de colonnes.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>Calcul de la racine carrée (Square Root):&lt;/strong>
À partir de la solution de la matrice, on crée un carré parfait géant dans chacun des « deux mondes différents », pour finalement dériver la relation $X^2 \equiv Y^2 \pmod N$. Ensuite, on calcule $\gcd(X-Y, N)$ pour obtenir les facteurs premiers.&lt;/p>
&lt;/li>
&lt;/ol>
&lt;h3 id="complexité-du-crible-du-corps-de-nombres-généralisé--temps-sous-exponentiel-sub-exponential-time">Complexité du crible du corps de nombres généralisé : Temps sous-exponentiel (Sub-exponential time)
&lt;/h3>&lt;p>La plus grande réalisation du GNFS est d&amp;rsquo;avoir réduit la complexité de la factorisation du « temps exponentiel pur » au &lt;strong>« temps sous-exponentiel (Sub-exponential time) »&lt;/strong>.
La complexité temporelle asymptotique du GNFS s&amp;rsquo;exprime à l&amp;rsquo;aide d&amp;rsquo;une notation spéciale appelée notation L (L-notation) :&lt;/p>
$$ L_N[\gamma, c] = \exp\left( (c + o(1)) (\ln N)^\gamma (\ln \ln N)^{1-\gamma} \right) $$
&lt;p>Où $N$ est le nombre à factoriser et $\ln$ est le logarithme népérien.
$\gamma$ est un paramètre compris entre $0 \le \gamma \le 1$ qui indique le « degré » de complexité de l&amp;rsquo;algorithme.&lt;/p>
&lt;ul>
&lt;li>Lorsque $\gamma = 0$, $L_N[0, c]$ devient $(\ln N)^c$, ce qui signifie un temps polynomial $\mathcal{O}(n^c)$. (Efficace)&lt;/li>
&lt;li>Lorsque $\gamma = 1$, $L_N[1, c]$ devient $e^{c \ln N} = N^c$, ce qui signifie un temps exponentiel $\mathcal{O}(2^{cn})$. (Inefficace)&lt;/li>
&lt;/ul>
&lt;p>Dans le cas du GNFS, ce paramètre est le suivant :&lt;/p>
$$ L_N\left[\frac{1}{3}, \left(\frac{64}{9}\right)^{1/3}\right] = e^{\left(\sqrt[3]{\frac{64}{9}} + o(1)\right) (\ln N)^{1/3} (\ln \ln N)^{2/3}} $$
&lt;p>Dans cette équation, la constante $c = (64/9)^{1/3} \approx 1,923$.
Si on la réécrit avec la taille de l&amp;rsquo;entrée $n \approx \ln N$ (proportionnelle à la longueur des bits), la complexité se comporte approximativement comme suit :&lt;/p>
$$ \mathcal{O}\left( \exp\left( 1,923 \cdot n^{1/3} (\ln n)^{2/3} \right) \right) $$
&lt;p>On constate que la partie exponentielle ne dépend pas de $n$ à la puissance 1, mais de $n^{1/3}$ (la racine cubique de $n$).
Alors que l&amp;rsquo;algorithme $\rho$ de Pollard était en $\mathcal{O}(2^{n/4})$, c&amp;rsquo;est-à-dire $\mathcal{O}(\exp(c \cdot n^1))$, le GNFS a fait chuter le degré de $n$ à $1/3$.
Cela signifie que bien qu&amp;rsquo;on n&amp;rsquo;atteigne pas le temps polynomial ($\gamma=0$), la complexité croît beaucoup plus lentement que pour un temps exponentiel pur ($\gamma=1$). C&amp;rsquo;est la raison pour laquelle on l&amp;rsquo;appelle « temps sous-exponentiel ».&lt;/p>
&lt;hr>
&lt;h1 id="limites-de-la-cryptographie-moderne-et-ordinateurs-quantiques">Limites de la cryptographie moderne et ordinateurs quantiques
&lt;/h1>&lt;p>Comme nous l&amp;rsquo;avons vu, l&amp;rsquo;humanité a mobilisé la sagesse mathématique pour repousser les limites de la factorisation en faisant évoluer les algorithmes, de la méthode des divisions successives au GNFS. Cependant, même avec le GNFS, la factorisation n&amp;rsquo;a toujours pas pu être résolue en « temps polynomial » sur des ordinateurs classiques.&lt;/p>
&lt;h2 id="le-problème-p-vs-np-et-la-position-de-la-factorisation-en-nombres-premiers">Le problème P vs NP et la position de la factorisation en nombres premiers
&lt;/h2>&lt;p>L&amp;rsquo;un des plus grands problèmes non résolus de l&amp;rsquo;informatique est la « conjecture P = NP ».
Le problème de la factorisation appartient à NP (la classe des problèmes dont la solution, si elle est donnée, peut être vérifiée en temps polynomial), mais il n&amp;rsquo;a pas été prouvé qu&amp;rsquo;il soit NP-complet (la classe des problèmes les plus difficiles dans NP).
De plus, il n&amp;rsquo;est pas encore prouvé s&amp;rsquo;il appartient à P (la classe des problèmes solvables en temps polynomial), c&amp;rsquo;est-à-dire s&amp;rsquo;il existe un algorithme en temps polynomial pour le résoudre.&lt;/p>
&lt;p>De nombreux chercheurs supposent que la factorisation appartient à une classe intermédiaire entre P et NP-complet (NP-intermédiaire). Si un algorithme résolvant la factorisation en temps polynomial sur un ordinateur classique (par exemple, $\mathcal{O}(n^3)$) venait à être découvert, ce serait un événement majeur qui ferait s&amp;rsquo;effondrer les systèmes cryptographiques du monde entier ; cependant, jusqu&amp;rsquo;à présent, aucun algorithme de ce type n&amp;rsquo;a été trouvé. Il est estimé que le déchiffrement d&amp;rsquo;une clé RSA de 2048 bits prendrait plus de temps que la durée de vie de l&amp;rsquo;univers, même si les performances des ordinateurs classiques continuaient à s&amp;rsquo;améliorer selon la loi de Moore.&lt;/p>
&lt;h2 id="lordinateur-quantique-un--changeur-de-donne-game-changer---lalgorithme-de-shor">L&amp;rsquo;ordinateur quantique, un « changeur de donne (Game Changer) » : l&amp;rsquo;algorithme de Shor
&lt;/h2>&lt;p>Alors que le chiffrement RSA est robuste face aux ordinateurs classiques, la situation changera radicalement avec la mise en pratique des « ordinateurs quantiques », qui fonctionnent sur des principes totalement différents.
Publié en 1994 par Peter Shor, l&amp;rsquo;&lt;strong>« algorithme de Shor (Shor&amp;rsquo;s algorithm) »&lt;/strong> est un algorithme capable de résoudre la factorisation en nombres premiers en &lt;strong>temps polynomial $\mathcal{O}(n^3)$&lt;/strong> (ou plus précisément, environ $\mathcal{O}(n^2 \log n \log \log n)$ en termes de portes quantiques), de manière stupéfiante, grâce à la transformée de Fourier quantique.&lt;/p>
&lt;p>Voyons la différence de complexité entre les algorithmes classiques et quantiques dans le diagramme Mermaid suivant.&lt;/p>
&lt;div class="mermaid">graph LR
classDef classical fill:#f9f871,stroke:#333,stroke-width:2px;
classDef quantum fill:#00c9a7,stroke:#333,stroke-width:2px;
subgraph "Ordinateurs Classiques"
C1["Divisions Successives : O(2^(n/2))"]:::classical
C2["GNFS : Sous-exponentiel L_n(1/3)"]:::classical
end
subgraph "Ordinateurs Quantiques"
Q1["Algorithme de Shor : O(n^3) Polynomial"]:::quantum
end
C1 --> C2
C2 -. "Limite de la Physique Classique" .-> Q1&lt;/div>
&lt;p>Dans l&amp;rsquo;algorithme de Shor, le processus de « recherche de période », qui constituait un goulot d&amp;rsquo;étranglement dans les algorithmes classiques, est calculé en parallèle et en un instant grâce à l&amp;rsquo;intrication et à la superposition quantiques utilisant la « transformée de Fourier quantique (QFT) ».
S&amp;rsquo;il devient possible de l&amp;rsquo;exécuter sur un ordinateur quantique de taille pratique (avec peu de bruit et un nombre suffisant de qubits logiques), la clé RSA de 2048 bits, actuellement considérée comme sûre, pourrait être complètement déchiffrée en quelques heures à quelques jours.&lt;/p>
&lt;p>Pour se prémunir contre cette menace, les cryptographes du monde entier et le NIST (Institut national des normes et de la technologie aux États-Unis) accélèrent actuellement les travaux de normalisation pour la transition vers la « Cryptographie post-quantique (Post-Quantum Cryptography : PQC) », qui reste difficile à déchiffrer même pour les ordinateurs quantiques. La cryptographie fondée sur les réseaux euclidiens (Lattice-based cryptography) en est un exemple représentatif, sa sécurité reposant sur une difficulté mathématique totalement différente de celle de la factorisation (par exemple, le problème du vecteur le plus court).&lt;/p>
&lt;hr>
&lt;h1 id="conclusion">Conclusion
&lt;/h1>&lt;p>Dans cet article, en partant des bases de la complexité algorithmique (notation Grand O), nous avons exploré en profondeur l&amp;rsquo;évolution des algorithmes de factorisation et leurs limites mathématiques.&lt;/p>
&lt;ul>
&lt;li>La &lt;strong>notation Grand O ($\mathcal{O}$)&lt;/strong> est un indicateur clé montrant le taux de croissance du nombre d&amp;rsquo;étapes de calcul par rapport à l&amp;rsquo;augmentation de la taille d&amp;rsquo;entrée $n$, et il existe un fossé infranchissable en pratique entre le temps polynomial et le temps exponentiel.&lt;/li>
&lt;li>La &lt;strong>méthode des divisions successives&lt;/strong> et l&amp;rsquo;&lt;strong>algorithme $\rho$ de Pollard&lt;/strong> sont de purs algorithmes en « temps exponentiel », impuissants face aux nombres gigantesques.&lt;/li>
&lt;li>Le &lt;strong>crible du corps de nombres généralisé (GNFS)&lt;/strong>, actuellement le plus rapide des algorithmes classiques, a atteint un temps « sous-exponentiel » en exploitant une théorie algébrique des nombres avancée, mais n&amp;rsquo;atteint toujours pas un temps polynomial, et la factorisation de nombres énormes prendrait un temps astronomique.&lt;/li>
&lt;li>Le fait &lt;strong>« qu&amp;rsquo;il n&amp;rsquo;existe pas (ou qu&amp;rsquo;on suppose fortement qu&amp;rsquo;il n&amp;rsquo;existe pas) d&amp;rsquo;algorithme classique résolvant ce problème en temps polynomial »&lt;/strong> est exactement ce qui garantit la sécurité du chiffrement RSA et soutient notre société numérique moderne.&lt;/li>
&lt;li>Cependant, avec l&amp;rsquo;avènement de &lt;strong>l&amp;rsquo;ordinateur quantique et de l&amp;rsquo;algorithme de Shor&lt;/strong>, la factorisation en temps polynomial devient théoriquement possible, et la technologie cryptographique s&amp;rsquo;apprête à entrer dans une nouvelle ère (la cryptographie post-quantique).&lt;/li>
&lt;/ul>
&lt;p>Le fait qu&amp;rsquo;un concept aussi abstrait que la complexité d&amp;rsquo;un algorithme soit directement lié à la sécurité de notre quotidien est l&amp;rsquo;un des aspects les plus fascinants et palpitants de l&amp;rsquo;informatique et des mathématiques. Nous vous invitons à rester attentifs aux futurs développements technologiques, en particulier à l&amp;rsquo;évolution des ordinateurs quantiques et aux transitions de la technologie cryptographique.&lt;/p></description></item></channel></rss>