<?xml version="1.0" encoding="ISO-8859-1"?>

<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
	<channel>
		<title>Forum du club des développeurs et IT Pro - Blogs - User</title>
		<link>https://www.developpez.net/forums/blogs/44027-user/</link>
		<description>Developpez.com, le Club des Développeurs et IT Pro</description>
		<language>fr</language>
		<lastBuildDate>Sun, 31 May 2026 05:27:34 GMT</lastBuildDate>
		<generator>vBulletin</generator>
		<ttl>15</ttl>
		<image>
			<url>https://forum.developpez.be/images/misc/rss.jpg</url>
			<title>Forum du club des développeurs et IT Pro - Blogs - User</title>
			<link>https://www.developpez.net/forums/blogs/44027-user/</link>
		</image>
		<item>
			<title><![CDATA[Les polynômes de Lagrange vus comme les vecteurs d'une base orthonormée]]></title>
			<link>https://www.developpez.net/forums/blogs/44027-user/b10637/polynomes-lagrange-vus-vecteurs-d-base-orthonormee/</link>
			<pubDate>Wed, 30 Oct 2024 10:14:15 GMT</pubDate>
			<description>*I. Introduction* 
 
Après...</description>
			<content:encoded><![CDATA[<blockquote class="blogcontent restore"><font size="2"><b>I. Introduction</b><br />
<br />
Après <a href="https://www.developpez.net/forums/blogs/44027-user/b10590/calcul-formel-python-polynomes-dinterpolation-lagrange-vus-vecteurs" target="_blank">les polynômes d'interpolation de Lagrange vus comme des vecteurs</a>, on s'intéresse maintenant aux polynômes de Lagrange vus comme les vecteurs d'une <a href="https://fr.wikipedia.org/wiki/Base_orthonorm%C3%A9e" target="_blank">base orthonormée</a>.<br />
<br />
On va d'abord montrer que la famille de polynômes de Lagrange <b>(l<sub>0</sub>, l<sub>1</sub>, …, l<sub>n</sub>)</b> forme une base orthonormée d'un espace vectoriel.<br />
<br />
Ensuite, on va reprendre notre classe Polynome_lagrange crée précédemment pour y ajouter des méthodes afin notamment d'évaluer le produit scalaire et le coefficient de corrélation portant sur ces vecteurs.<br />
<br />
Enfin, on va tester ces nouvelles fonctions dans l'environnement Python.<br />
<br />
<br />
<b>II. Base orthonormée</b><br />
<br />
D'après Wikipedia, en géométrie vectorielle, une base orthonormale ou base orthonormée d'un espace euclidien ou hermitien est une base de cet espace vectoriel constituée de vecteurs de norme <b>1</b> et orthogonaux deux à deux. Dans une telle base, les coordonnées d'un vecteur quelconque de l'espace sont égales aux produits scalaires respectifs de ce vecteur par chacun des vecteurs de base, et le produit scalaire de deux vecteurs quelconques a une expression canonique en fonction de leurs coordonnées. <br />
<br />
<br />
<b>II-A. Repère orthonormé</b><br />
<br />
Soit <b>A<sub>n</sub></b> un espace affine euclidien associé à l'espace vectoriel euclidien <b>E<sub>n</sub></b> et <b>O</b> un point quelconque de <b>A<sub>n</sub></b>, alors un repère affine :<br />
<br />
<b>R = (O, e<sub>1</sub>, e<sub>2</sub>, ..., e<sub>n</sub>)</b><br />
<br />
est dit orthonormal (ou orthonormé) si sa base associée <b>B = (e<sub>1</sub>, e<sub>2</sub>, ..., e<sub>n</sub>)</b> est elle-même orthonormale. <br />
<br />
<br />
<b>II-B. Produit scalaire canonique</b><br />
<br />
Dans un espace <b>R<sup>n</sup></b>, espace euclidien de dimension <b>n</b>, on appelle <a href="https://fr.wikipedia.org/wiki/Produit_scalaire_canonique" target="_blank">produit scalaire canonique</a> de <b>R<sup>n</sup></b> l'application qui, aux vecteurs <b>y = (y<sub>1</sub>, y<sub>2</sub>, …, y<sub>n</sub>)</b> et <b>z = (z<sub>1</sub>, z<sub>2</sub>, …, z<sub>n</sub>)</b> de <b>R<sup>n</sup></b> associe la quantité : <br />
<br />
<img src="https://www.developpez.net/forums/attachments/p660749d1729328304/autres-langages/general-visual-basic-6-vbscript/vb-6-anterieur/vb6-winsock-envoi-donn-es/produit_scalaire_canonique.png/" border="0" alt="Nom : produit_scalaire_canonique.png
Affichages : 12815
Taille : 1,9 Ko"  style="float: CONFIG" /><br />
<br />
On sait aussi que si deux vecteurs sont orthogonaux leur produit scalaire est nul.<br />
<br />
<span class="highlight">Le produit scalaire peut être utilisé pour déterminer le travail d'une force lors d'un déplacement : le travail de la force <b>F</b> selon le trajet <b>u</b> est le produit scalaire de ces deux vecteurs. Si maintenant <b>F</b> et <b>u</b> sont orthogonaux, la force <b>F</b> n'est pas &quot;efficace&quot; sur le déplacement <b>u</b> et le produit scalaire correspondant au travail de la force <b>F</b> selon le trajet <b>u</b> est nul.</span><br />
<br />
<br />
<b>II-C. Norme</b><br />
<br />
Dans un espace <b>R<sup>n</sup></b>, la <a href="https://fr.wikipedia.org/wiki/Norme_(math%C3%A9matiques)" target="_blank">norme d'un vecteur</a> <b>y = (y<sub>1</sub>, y<sub>2</sub>, …, y<sub>n</sub>)</b> est donnée par : <br />
<br />
<img src="https://www.developpez.net/forums/attachments/p660757d1729346269/autres-langages/general-visual-basic-6-vbscript/vb-6-anterieur/vb6-winsock-envoi-donn-es/norme.png/" border="0" alt="Nom : norme.png
Affichages : 3893
Taille : 2,9 Ko"  style="float: CONFIG" /><br />
<br />
<br />
<b>II-D. Coefficient de corrélation</b><br />
<br />
Les deux séries de valeurs <b>Y(y<sub>1</sub>, …, y<sub>n</sub>)</b> et <b>Z(z<sub>1</sub>, …, z<sub>n</sub>)</b> peuvent être considérées comme des vecteurs dans un espace à <b>n</b> dimensions. Remplaçons-les par des vecteurs centrés : <b>Y'(y<sub>1</sub> &#8722; m<sub>y</sub>, …, y<sub>n</sub> &#8722; m<sub>y</sub>)</b> et <b>Z'(z<sub>1</sub> &#8722; m<sub>z</sub>, …, z<sub>n</sub> &#8722; m<sub>z</sub>)</b> où <b>m<sub>y</sub></b> et <b>m<sub>z</sub></b> représentent respectivement les moyennes des <b>y</b> et des <b>z</b>.<br />
<br />
Le produit scalaire entre ces vecteurs est donné par la formule suivante (produit scalaire normé) : <br />
<br />
<span class="highlight">Y'&#8729;Z' = &#8214;Y'&#8214;&#8729;&#8214;Z'&#8214;&#8729;cos(&#945;) = cov(Y, Z)</span> où cov(Y, Z) représente la <a href="https://fr.wikipedia.org/wiki/Covariance" target="_blank">covariance</a> de Y et Z. <br />
<br />
Le cosinus de l'angle <b>&#945;</b> entre ces vecteurs est alors tel que :<br />
<br />
<span class="highlight">cos(&#945;) = Y'&#8729;Z' / (&#8214;Y'&#8214;&#8729;&#8214;Z'&#8214;) = cov(Y, Z) / (&#8214;Y'&#8214;&#8729;&#8214;Z'&#8214;) </span><br />
<br />
Il s'agit du <a href="https://fr.wikipedia.org/wiki/Corr%C3%A9lation_(statistiques)" target="_blank">coefficient de corrélation</a> compris entre <b>-1</b> et <b>+1</b> qui donne une indication sur le degré de corrélation linéaire entre deux variables. <br />
<br />
Si le coefficient est proche de -1 ou +1 les variables sont très fortement corrélées, s'il est proche de 0 elles sont très peu liées.<br />
<br />
Bien sûr, du point de vue géométrique, on ne parle pas de « corrélation linéaire » : le coefficient de corrélation a toujours un sens, quelle que soit sa valeur entre –1 et 1. Il nous renseigne de façon précise, non pas tant sur le degré de dépendance entre les variables, que sur leur distance angulaire dans un espace à n dimensions : si le coefficient vaut -1 ou +1 les deux vecteurs sont colinéaires et s'il est égal à 0 les vecteurs sont orthogonaux.<br />
<br />
<br />
<b>III. Polynômes d'interpolation de Lagrange</b><br />
<br />
Soit <b>n + 1</b> points <b>(x<sub>0</sub>, y<sub>0</sub>), …, (x<sub>n</sub>, y<sub>n</sub>)</b> (avec les <b>x<sub>i</sub></b> des réels distincts deux à deux). <br />
<br />
Le <a href="https://fr.wikipedia.org/wiki/Interpolation_lagrangienne" target="_blank">polynôme d'interpolation de Lagrange</a> de degré au plus <b>n</b> qui passe par ces points est défini par :<br />
<br />
<img src="https://www.developpez.net/forums/attachments/p660177d1728228510/autres-langages/general-visual-basic-6-vbscript/vb-6-anterieur/vb6-winsock-envoi-donn-es/polynome_interpolation_lagrange.png/" border="0" alt="Nom : polynome_interpolation_lagrange.png
Affichages : 4440
Taille : 9,3 Ko"  style="float: CONFIG" /><br />
<br />
<br />
<b>III-A. Espace des polynômes</b><br />
<br />
<b>L</b> étant une <a href="https://fr.wikipedia.org/wiki/Combinaison_lin%C3%A9aire" target="_blank">combinaison linéaire</a> de polynômes de degré <b>n</b>, il est de degré au plus <b>n</b> et appartient donc à l'ensemble <b>&#8477;<sub>n</sub>[X]</b>. <br />
<br />
Étant donné <b>n + 1</b> réels distincts <b>x<sub>0</sub>, …, x<sub>n</sub></b>, l'ensemble des polynômes que l'on peut construire avec la <a href="https://fr.wikipedia.org/wiki/Famille_(math%C3%A9matiques)" target="_blank">famille</a> de polynômes <b>(l<sub>0</sub>, l<sub>1</sub>, …, l<sub>n</sub>)</b> constitue un espace vectoriel muni de deux lois :<br />
<br />
<ul><li style="">une loi de composition interne « + », appelée addition ou somme vectorielle ;</li><li style="">une loi de composition externe à gauche « • », appelée multiplication par un scalaire.</li></ul><br />
<br />
<b>III-B. Base des polynômes</b><br />
<br />
On se donne à nouveau <b>n + 1</b> réels distincts <b>x<sub>0</sub>, …, x<sub>n</sub></b>. Pour tout polynôme <b>P</b> appartenant à un espace <b>&#8477;<sub>n</sub>[X]</b> des polynômes, si on pose <span class="highlight">y<sub>i</sub> = P(x<sub>i</sub>)</span>, <b>P</b> étant le polynôme d'interpolation correspondant aux points, il est égal au polynôme <b>L</b> défini précédemment. <br />
<br />
On a alors :<br />
<br />
<img src="https://www.developpez.net/forums/attachments/p660085d1728026961/autres-langages/general-visual-basic-6-vbscript/vb-6-anterieur/vb6-winsock-envoi-donn-es/polynome_interpolation_lagrange2.png/" border="0" alt="Nom : polynome_interpolation_lagrange2.png
Affichages : 3907
Taille : 2,1 Ko"  style="float: CONFIG" /><br />
<br />
Et donc <b>(l<sub>0</sub>, l<sub>1</sub>, …, l<sub>n</sub>)</b> forme une famille génératrice de <b>&#8477;<sub>n</sub>[X]</b> et son cardinal (égal à <b>n + 1</b>) est égal à la dimension de l'espace. <br />
<br />
Par exemple, en choisissant <b>P = 1</b> ou <b>P = X</b>, on obtient :<br />
<br />
<img src="https://www.developpez.net/forums/attachments/p660086d1728026984/autres-langages/general-visual-basic-6-vbscript/vb-6-anterieur/vb6-winsock-envoi-donn-es/egalites_polynomes.png/" border="0" alt="Nom : egalites_polynomes.png
Affichages : 3919
Taille : 2,7 Ko"  style="float: CONFIG" /><br />
<br />
On peut remarquer également que le polynôme nul <span class="highlight">P = 0</span> est tel que :<br />
<br />
<img src="https://www.developpez.net/forums/attachments/p660087d1728027047/autres-langages/general-visual-basic-6-vbscript/vb-6-anterieur/vb6-winsock-envoi-donn-es/polynome_nul.png/" border="0" alt="Nom : polynome_nul.png
Affichages : 3914
Taille : 2,3 Ko"  style="float: CONFIG" /><br />
<br />
Cela implique nécessairement que :<br />
<br />
<img src="https://www.developpez.net/forums/attachments/p660088d1728027064/autres-langages/general-visual-basic-6-vbscript/vb-6-anterieur/vb6-winsock-envoi-donn-es/coefficients_nuls.png/" border="0" alt="Nom : coefficients_nuls.png
Affichages : 3912
Taille : 1,8 Ko"  style="float: CONFIG" /><br />
<br />
On en déduit que cette famille génératrice <b>(l<sub>0</sub>, l<sub>1</sub>, …, l<sub>n</sub>)</b> est également <a href="https://fr.wikipedia.org/wiki/Ind%C3%A9pendance_lin%C3%A9aire" target="_blank">libre</a>, et par conséquent c'est une base de l'espace des polynômes qu'elle engendre.<br />
<br />
De plus, les polynômes de Lagrange notés <b>l<sub>j</sub>(x)</b> et définis précédemment sont tels que :<br />
<br />
<img src="https://www.developpez.net/forums/attachments/p660089d1728028102/autres-langages/general-visual-basic-6-vbscript/vb-6-anterieur/vb6-winsock-envoi-donn-es/lj-xi-.png/" border="0" alt="Nom : Lj(xi).png
Affichages : 3892
Taille : 1,8 Ko"  style="float: CONFIG" /><br />
<br />
Si maintenant on se donne <b>3</b> réels distincts <b>x<sub>0</sub>, x<sub>1</sub></b> et <b>x<sub>2</sub></b>, dans l'espace <b>&#8477;<sub>2</sub>[X]</b> engendré par la famille <b>(l<sub>0</sub>, l<sub>1</sub>, l<sub>2</sub>)</b>, on obtient :<br />
<br />
<img src="https://www.developpez.net/forums/attachments/p660130d1728119661/autres-langages/general-visual-basic-6-vbscript/vb-6-anterieur/vb6-winsock-envoi-donn-es/vecteurs_base.png/" border="0" alt="Nom : vecteurs_base.png
Affichages : 3891
Taille : 2,7 Ko"  style="float: CONFIG" /><br />
<br />
Par conséquent, cette famille forme une base dont les vecteurs de norme <b>1</b> sont orthogonaux deux à deux (leur produit scalaire est nul), et elle constitue donc une base orthonormée de <b>&#8477;<sub>2</sub>[X]</b>. Plus généralement, la famille génératrice <b>(l<sub>0</sub>, l<sub>1</sub>, …, l<sub>n</sub>)</b> forme une base orthonormée de <b>&#8477;<sub>n</sub>[X]</b>.<br />
<br />
Si vous souhaitez avoir plus d'information sur le sujet je vous invite à consulter la page Wikipedia <a href="https://fr.wikipedia.org/wiki/Interpolation_lagrangienne" target="_blank">Interpolation lagrangienne</a>.<br />
<br />
<br />
<b>III-C. Produit scalaire</b><br />
<br />
Considérons maintenant le produit scalaire des polynômes <b>P</b> et <b>Q</b> appartenant au même espace <b>R<sub>n</sub></b> de dimension <b>n+1</b> et défini par : <br />
<br />
<img src="https://www.developpez.net/forums/attachments/p660109d1728051442/autres-langages/general-visual-basic-6-vbscript/vb-6-anterieur/vb6-winsock-envoi-donn-es/produit_scalaire.png/" border="0" alt="Nom : produit_scalaire.png
Affichages : 3897
Taille : 3,4 Ko"  style="float: CONFIG" /><br />
<br />
<br />
<b>III-D. Norme</b><br />
<br />
Dans un espace de dimension <b>n+1</b>, la norme du polynôme <b>P</b> est donnée par : <br />
<br />
<img src="https://www.developpez.net/forums/attachments/p660176d1728227778/autres-langages/general-visual-basic-6-vbscript/vb-6-anterieur/vb6-winsock-envoi-donn-es/norme2.png/" border="0" alt="Nom : norme2.png
Affichages : 3903
Taille : 3,3 Ko"  style="float: CONFIG" /><br />
<br />
<br />
<b>III-E. Coefficient de corrélation</b><br />
<br />
Les deux séries de valeurs <b>Y(y<sub>0</sub>, …, y<sub>n</sub>)</b> et <b>Z(z<sub>0</sub>, …, z<sub>n</sub>)</b> peuvent être considérées comme des vecteurs dans un espace à <b>n+1</b> dimensions. Remplaçons-les par des vecteurs centrés : <b>Y'(y<sub>0</sub> &#8722; m<sub>y</sub>, …, y<sub>n</sub> &#8722; m<sub>y</sub>)</b> et <b>Z'(z<sub>0</sub> &#8722; m<sub>z</sub>, …, z<sub>n</sub> &#8722; m<sub>z</sub>)</b>.<br />
<br />
Le produit scalaire entre ces vecteurs est donné par la formule suivante (produit scalaire normé) : <br />
<br />
<span class="highlight">Y'&#8729;Z' = &#8214;Y'&#8214;&#8729;&#8214;Z'&#8214;&#8729;cos(&#945;) = cov(Y, Z)</span><br />
<br />
Il vient donc :<br />
<br />
<span class="highlight">cos(&#945;) = Y'&#8729;Z' / (&#8214;Y'&#8214;&#8729;&#8214;Z'&#8214;) = cov(Y, Z) / (&#8214;Y'&#8214;&#8729;&#8214;Z'&#8214;)</span><br />
<br />
Il s'agit à nouveau du <a href="https://fr.wikipedia.org/wiki/Corr%C3%A9lation_(statistiques)" target="_blank">coefficient de corrélation</a> compris entre <b>-1</b> et <b>+1</b> qui donne une indication sur le degré de corrélation linéaire entre Y et Z, ou du point de vue géométrique, sur l'écart angulaire entre ces deux vecteurs. <br />
<br />
<br />
<br />
<b>IV. Implémentation en Python</b><br />
<br />
Comme on a pu le montrer dans un précédent billet, ces polynômes d'interpolation peuvent donc être vus comme des vecteurs sur lesquels on peut réaliser les opérations d'addition et de multiplication par un scalaire.<br />
<br />
Ils peuvent être définis en Python à l'aide d'une classe permettant ensuite de créer ces objets mathématiques et de réaliser des opérations entre eux. On va d'ailleurs ajouter aux opérations d'addition et de multiplication par un scalaire, des méthodes permettant d'évaluer la norme d'un vecteur, mais aussi le produit scalaire et le coefficient de corrélation entre deux vecteurs :<br />
<br />
<img src="https://www.developpez.net/forums/attachments/p660748d1729328217/autres-langages/general-visual-basic-6-vbscript/vb-6-anterieur/vb6-winsock-envoi-donn-es/classe_polynome_lagrange.png/" border="0" alt="Nom : classe_polynome_lagrange.png
Affichages : 3920
Taille : 11,5 Ko"  style="float: CONFIG" /><br />
<br />
<br />
<b>IV-A. Produit scalaire</b><br />
<br />
Pour réaliser le produit scalaire entre <b>2</b> polynômes appartenant au même espace, nous devons ajouter une méthode <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">__matmul__()</span> à notre classe qui va permettre de  <a href="hhttps://docs.python.org/fr/3/library/operator.html" target="_blank">surcharger l'opérateur</a> « <b>@</b> » :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">import</span> numpy <span style="color: #0000ff;">as</span> np
&nbsp;
<span style="color: #0000ff;">class</span> Polynome_lagrange:
    ... 
    <span style="color: #0000ff;">def</span> <span style="color: #0080ff;">__matmul__</span><span class="br0">&#40;</span>self, other<span class="br0">&#41;</span>:
        <span style="color: #808080;"># m&eacute;thode permettant de r&eacute;aliser le produit scalaire entre les polyn&ocirc;mes self et other</span>
        <span style="color: #808080;"># (y0, ..., yn)&sdot;(z0, ..., zn)  = y0&sdot;z0 + ... + yn&sdot;zn</span>
&nbsp;
        <span style="color: #808080;"># si other est un objet de la classe Polynome_lagrange</span>
        <span style="color: #0000ff;">if</span> isinstance<span class="br0">&#40;</span>other, Polynome_lagrange<span class="br0">&#41;</span>:
&nbsp;
            <span style="color: #808080;"># si les 2 vecteurs self et other sont d&eacute;finis dans la m&ecirc;me base (l0, l1, ..., ln)</span>
            <span style="color: #0000ff;">if</span> self.x==other.x:
&nbsp;
                <span style="color: #808080;"># calcul du produit scalaire des vecteurs self.y et other.y</span>
                ps = self.y @ other.y
&nbsp;
                <span style="color: #808080;"># renvoie la valeur du produit scalaire</span>
                <span style="color: #0000ff;">return</span> ps
&nbsp;
            <span style="color: #0000ff;">else</span>: <span style="color: #808080;"># sinon</span>
&nbsp;
                <span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Les deux vecteurs ne sont pas d&eacute;finis dans la m&ecirc;me base !&quot;</span><span class="br0">&#41;</span>
&nbsp;
        <span style="color: #0000ff;">else</span>: <span style="color: #808080;"># sinon</span>
&nbsp;
            <span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Le produit scalaire doit porter sur deux objets de la classe Polynome_lagrange !&quot;</span><span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
Python dispose depuis sa version <b>3.5</b> d'un opérateur <b>@</b> permettant d'évaluer le produit scalaire de deux vecteurs numpy.<br />
<br />
Pour tester notre opérateur « <b>@</b> » portant sur <b>2</b> objets de la classe Polynome_lagrange, nous ajoutons ces lignes de code :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #808080;"># cr&eacute;ation du 1er objet de la classe Polynome_lagrange</span>
p1 = Polynome_lagrange<span class="br0">&#40;</span>x=<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span>, <span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">2</span><span class="br0">&#93;</span>, y=<span class="br0">&#91;</span><span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">2</span>, <span style="color: #cc66cc;">1</span><span class="br0">&#93;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># cr&eacute;ation du 2e objet de la classe Polynome_lagrange</span>
p2 = Polynome_lagrange<span class="br0">&#40;</span>x=<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span>, <span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">2</span><span class="br0">&#93;</span>, y=<span class="br0">&#91;</span>-<span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">1</span>, -<span style="color: #cc66cc;">1</span><span class="br0">&#93;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche les expressions des polyn&ocirc;mes p1 et p2</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;p1 =&quot;</span>, p1<span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;p2 =&quot;</span>, p2<span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche l'appartenance de p1 et p2 &agrave; leur espace vectoriel : R2[X], Base = [L0, L1, L2], x = [0, 1, 2]</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;p1 &isin; &quot;</span> + p1.espace<span class="br0">&#40;</span><span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot;, Base = &quot;</span> + p1.base<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;p2 &isin; &quot;</span> + p2.espace<span class="br0">&#40;</span><span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot;, Base = &quot;</span> + p2.base<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># calcul du produit scalaire de p1 et p2</span>
ps = <span class="br0">&#40;</span>p1 @ p2<span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche la valeur du produit scalaire de p1 et p2</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;p1&sdot;p2 = {0}&quot;</span>.format<span class="br0">&#40;</span>ps<span class="br0">&#41;</span><span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
Le code affiche :<br />
<br />
<span class="highlight"><font color="#000000">p1 = 1&#8729;L0(X) + 2&#8729;L1(X) + 1&#8729;L2(X)<br />
p2 = -1&#8729;L0(X) + 1&#8729;L1(X) + -1&#8729;L2(X)<br />
<br />
p1 &#8712; &#8477;2[X], Base = (L0, L1, L2), x = [0, 1, 2]<br />
p2 &#8712; &#8477;2[X], Base = (L0, L1, L2), x = [0, 1, 2]<br />
<br />
p1&#8901;p2 = 0</font></span><br />
<br />
<br />
<b>IV-B. Norme</b><br />
<br />
Le calcul de la norme d'un polynôme d'interpolation de Lagrange défini dans une base <b>(l<sub>0</sub>, l<sub>1</sub>, ..., l<sub>n</sub>)</b> se fait grâce à cette nouvelle méthode :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:192px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">import</span> numpy <span style="color: #0000ff;">as</span> np
&nbsp;
<span style="color: #0000ff;">class</span> Polynome_lagrange:
    ... 
    <span style="color: #0000ff;">def</span> norme<span class="br0">&#40;</span>self<span class="br0">&#41;</span>:
        <span style="color: #808080;"># m&eacute;thode permettant d'&eacute;valuer la norme du vecteur self d&eacute;fini dans la base (l0, l1, ..., ln)</span>
        <span style="color: #808080;"># norme((y0, ..., yn)) = (y0*y0 + ... + yn*yn)^0.5</span>
&nbsp;
        <span style="color: #808080;"># calcul de la norme du vecteur self.y</span>
        n = np.linalg.norm<span class="br0">&#40;</span>self.y<span class="br0">&#41;</span>
&nbsp;
        <span style="color: #808080;"># renvoie la valeur de la norme du vecteur</span>
        <span style="color: #0000ff;">return</span> n</pre></td></tr></table></pre>
</div><br />
La fonction <a href="https://numpy.org/doc/stable/reference/generated/numpy.linalg.norm.html" target="_blank">norm</a> du sous-module <a href="https://numpy.org/doc/stable/reference/routines.linalg.html" target="_blank">numpy.linalg</a> permet de calculer la norme d'un vecteur selon la formule définie précédemment.<br />
<br />
Pour tester notre méthode portant sur un objet de la classe Polynome_lagrange, nous ajoutons ces lignes de code :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #808080;"># cr&eacute;ation de l'objet de la classe Polynome_lagrange</span>
p = Polynome_lagrange<span class="br0">&#40;</span>x=<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span>, <span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">2</span><span class="br0">&#93;</span>, y=<span class="br0">&#91;</span><span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">1</span><span class="br0">&#93;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche l'expression du polyn&ocirc;me p</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;p =&quot;</span>, p<span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche l'appartenance de p &agrave; leur espace vectoriel : R2[X], Base = [L0, L1, L2], x = [0, 1, 2]</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;p &isin; &quot;</span> + p.espace<span class="br0">&#40;</span><span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot;, Base = &quot;</span> + p.base<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># calcul la norme de p</span>
n = p.norme<span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche la valeur de la norme de p</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;norme(p) = {0}&quot;</span>.format<span class="br0">&#40;</span>n<span class="br0">&#41;</span><span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
L'exécution du code affiche :<br />
<br />
<span class="highlight"><font color="#000000">p = 1&#8729;L0(X) + 1&#8729;L1(X) + 1&#8729;L2(X)<br />
<br />
p &#8712; &#8477;2[X], Base = (L0, L1, L2), x = [0, 1, 2]<br />
<br />
norme(p) = 1.7320508075688772</font></span><br />
<br />
<br />
<b>IV-C. Coefficient de corrélation</b><br />
<br />
Le calcul du coefficient de corrélation entre deux vecteurs appartenant au même espace vectoriel s'effectue avec cette méthode :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">import</span> numpy <span style="color: #0000ff;">as</span> np
&nbsp;
<span style="color: #0000ff;">class</span> Polynome_lagrange:
    ... 
    <span style="color: #0000ff;">def</span> coef_corr<span class="br0">&#40;</span>self, other<span class="br0">&#41;</span>:
        <span style="color: #808080;"># m&eacute;thode permettant d'&eacute;valuer le coefficient de corr&eacute;lation entre self et other</span>
&nbsp;
        <span style="color: #808080;"># si other est un objet de la classe Polynome_lagrange</span>
        <span style="color: #0000ff;">if</span> isinstance<span class="br0">&#40;</span>other, Polynome_lagrange<span class="br0">&#41;</span>:
&nbsp;
            <span style="color: #808080;"># si les 2 vecteurs self et other sont d&eacute;finis dans la m&ecirc;me base (l0, l1, ..., ln)</span>
            <span style="color: #0000ff;">if</span> self.x==other.x:
&nbsp;
                <span style="color: #808080;"># calcul du coefficient de corr&eacute;lation entre self.y et other.y</span>
                r = round<span class="br0">&#40;</span>np.corrcoef<span class="br0">&#40;</span>self.y, other.y<span class="br0">&#41;</span><span class="br0">&#91;</span><span style="color: #cc66cc;">0</span>, <span style="color: #cc66cc;">1</span><span class="br0">&#93;</span>, <span style="color: #cc66cc;">12</span><span class="br0">&#41;</span>
&nbsp;
                <span style="color: #808080;"># renvoi du coefficient de corr&eacute;lation</span>
                <span style="color: #0000ff;">return</span> r
&nbsp;
            <span style="color: #0000ff;">else</span>: <span style="color: #808080;"># sinon</span>
&nbsp;
                <span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Les deux vecteurs ne sont pas d&eacute;finis dans la m&ecirc;me base !&quot;</span><span class="br0">&#41;</span>
&nbsp;
        <span style="color: #0000ff;">else</span>: <span style="color: #808080;"># sinon</span>
&nbsp;
            <span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Le coefficient de corr&eacute;lation doit porter sur deux objets de la classe Polynome_lagrange !&quot;</span><span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
La fonction <a href="https://numpy.org/doc/2.0/reference/generated/numpy.corrcoef.html" target="_blank">corrcoef</a> du module numpy permet de calculer le coefficient de corrélation de deux vecteurs suivant la formule présentée plus haut. Ce coefficient donne notamment une indication sur l'écart angulaire entre les deux vecteurs. <br />
<br />
Testons maintenant notre méthode :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #808080;"># cr&eacute;ation du 1er objet de la classe Polynome_lagrange</span>
p1 = Polynome_lagrange<span class="br0">&#40;</span>x=<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span>, <span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">2</span><span class="br0">&#93;</span>, y=<span class="br0">&#91;</span><span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">2</span>, <span style="color: #cc66cc;">5</span><span class="br0">&#93;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># cr&eacute;ation du 2e objet de la classe Polynome_lagrange</span>
p2 = Polynome_lagrange<span class="br0">&#40;</span>x=<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span>, <span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">2</span><span class="br0">&#93;</span>, y=<span class="br0">&#91;</span><span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">3</span>, <span style="color: #cc66cc;">9</span><span class="br0">&#93;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche les expressions des polyn&ocirc;mes p1 et p2</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;p1 =&quot;</span>, p1<span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;p2 =&quot;</span>, p2<span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche l'appartenance de p1 et p2 &agrave; leur espace vectoriel : R2[X], Base = (L0, L1, L2), x = [0, 1, 2]</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;p1 &isin; &quot;</span> + p1.espace<span class="br0">&#40;</span><span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot;, Base = &quot;</span> + p1.base<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;p2 &isin; &quot;</span> + p2.espace<span class="br0">&#40;</span><span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot;, Base = &quot;</span> + p2.base<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># calcul du coefficient de corr&eacute;lation entre p1 et p2</span>
r = p1.coef_corr<span class="br0">&#40;</span>p2<span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche la valeur du coefficient de corr&eacute;lation</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;coef_corr(p1,&sdot;p2) = {0}&quot;</span>.format<span class="br0">&#40;</span>r<span class="br0">&#41;</span><span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
L'exécution du code affiche :<br />
<br />
<span class="highlight"><font color="#000000">p1 = 1&#8729;L0(X) + 2&#8729;L1(X) + 5&#8729;L2(X)<br />
p2 = 1&#8729;L0(X) + 3&#8729;L1(X) + 9&#8729;L2(X)<br />
<br />
p1 &#8712; &#8477;2[X], Base = (L0, L1, L2), x = [0, 1, 2]<br />
p2 &#8712; &#8477;2[X], Base = (L0, L1, L2), x = [0, 1, 2]<br />
<br />
coef_corr(p1,&#8901;p2) = 1.0</font></span><br />
<br />
Dans ce test le polynôme  <span class="highlight">p1</span> correspond en fait à la fonction polynomiale <span class="highlight">y(x) = 1 + x<sup>2</sup></span> définie sur l'intervalle [0, 2] et  <span class="highlight">p2</span> à la fonction <span class="highlight">z(x) = 1 + 2x<sup>2</sup></span> définie sur ce même intervalle. Le résultat donne donc un coefficient de corrélation entre Y et Z égal à 1 indiquant que ces deux variables sont linéairement corrélées. En effet, à partir des fonctions polynomiales on peut facilement obtenir la relation linéaire <span class="highlight">Z = 2Y - 1</span>.<br />
<br />
Du point de vue géométrique, ce coefficient égal à 1 indique que les deux vecteurs sont colinéaires.<br />
<br />
<br />
<b>IV-D. Module</b><br />
<br />
On présente pour finir le module complet pour effectuer les différents tests :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="40"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br />50<br />51<br />52<br />53<br />54<br />55<br />56<br />57<br />58<br />59<br />60<br />61<br />62<br />63<br />64<br />65<br />66<br />67<br />68<br />69<br />70<br />71<br />72<br />73<br />74<br />75<br />76<br />77<br />78<br />79<br />80<br />81<br />82<br />83<br />84<br />85<br />86<br />87<br />88<br />89<br />90<br />91<br />92<br />93<br />94<br />95<br />96<br />97<br />98<br />99<br />100<br />101<br />102<br />103<br />104<br />105<br />106<br />107<br />108<br />109<br />110<br />111<br />112<br />113<br />114<br />115<br />116<br />117<br />118<br />119<br />120<br />121<br />122<br />123<br />124<br />125<br />126<br />127<br />128<br />129<br />130<br />131<br />132<br />133<br />134<br />135<br />136<br />137<br />138<br />139<br />140<br />141<br />142<br />143<br />144<br />145<br />146<br />147<br />148<br />149<br />150<br />151<br />152<br />153<br />154<br />155<br />156<br />157<br />158<br />159<br />160<br />161<br />162<br />163<br />164<br />165<br />166<br />167<br />168<br />169<br />170<br />171<br />172<br />173<br />174<br />175<br />176<br />177<br />178<br />179<br />180<br />181<br />182<br />183<br />184<br />185<br />186<br />187<br />188<br />189<br />190<br />191<br />192<br />193<br />194<br />195<br />196<br />197<br />198<br />199<br />200<br />201<br />202<br />203<br />204<br />205<br />206<br />207<br />208<br />209<br />210<br />211<br />212<br />213<br />214<br />215<br />216<br />217<br />218<br />219<br />220<br />221<br />222<br />223<br />224<br />225<br />226<br />227<br />228<br />229<br />230<br />231<br />232<br />233<br />234<br />235<br />236<br />237<br />238<br />239<br />240<br />241<br />242<br />243<br />244<br />245<br />246<br />247<br />248<br />249<br />250<br />251<br />252<br />253<br />254<br />255<br />256<br />257<br />258<br />259<br />260<br />261<br />262<br />263<br />264<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">import</span> numpy <span style="color: #0000ff;">as</span> np
&nbsp;
<span style="color: #0000ff;">class</span> Polynome_lagrange<span class="br0">&#40;</span><span class="br0">&#41;</span>:
&nbsp;
    <span style="color: #0000ff;">def</span> <span style="color: #0080ff;">__init__</span><span class="br0">&#40;</span>self, x, y<span class="br0">&#41;</span>:
        <span style="color: #808080;"># m&eacute;thode constructeur de la classe</span>
&nbsp;
        <span style="color: #808080;"># si les deux listes ont la  m&ecirc;me taille</span>
        <span style="color: #0000ff;">if</span> len<span class="br0">&#40;</span>x<span class="br0">&#41;</span>==len<span class="br0">&#40;</span>y<span class="br0">&#41;</span>:
&nbsp;
            <span style="color: #808080;"># on d&eacute;finit la liste de valeurs en x permettant d'obtenir la famille de polyn&ocirc;mes (l0, l1, ..., ln) repr&eacute;sentant une base dans &#8477;n[X]</span>
            self.x = x
&nbsp;
            <span style="color: #808080;"># on d&eacute;finit le tableau de valeurs en y repr&eacute;sentant les coordonn&eacute;es du vecteur (tableau numpy)</span>
            self.y = np.array<span class="br0">&#40;</span>y<span class="br0">&#41;</span>
&nbsp;
        <span style="color: #0000ff;">else</span>: <span style="color: #808080;"># sinon</span>
&nbsp;
            <span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Les deux listes de valeurs x et y doivent avoir la m&ecirc;me dimension !&quot;</span><span class="br0">&#41;</span>
&nbsp;
&nbsp;
    <span style="color: #0000ff;">def</span> __str__<span class="br0">&#40;</span>self<span class="br0">&#41;</span>:
        <span style="color: #808080;"># permet d'afficher le polyn&ocirc;me sous la forme y0*L0(X) + ... + yn*Ln(X)</span>
&nbsp;
        Lx = <span style="color: #FF0000;">''</span>
        <span style="color: #808080;"># parcours des y</span>
        <span style="color: #0000ff;">for</span> j <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span>len<span class="br0">&#40;</span>self.y<span class="br0">&#41;</span><span class="br0">&#41;</span>:
            Lx +=  str<span class="br0">&#40;</span>self.y<span class="br0">&#91;</span>j<span class="br0">&#93;</span><span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot;&#8729;L&quot;</span> + str<span class="br0">&#40;</span>j<span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot;(X)&quot;</span> + <span style="color: #FF0000;">&quot; + &quot;</span>
&nbsp;
        <span style="color: #0000ff;">return</span> Lx<span class="br0">&#91;</span>:-<span style="color: #cc66cc;">3</span><span class="br0">&#93;</span>    
&nbsp;
    <span style="color: #0000ff;">def</span> espace<span class="br0">&#40;</span>self<span class="br0">&#41;</span>:
        <span style="color: #808080;"># retourne l'espace vectoriel du polyn&ocirc;me self : R2[X]</span>
&nbsp;
        n = len<span class="br0">&#40;</span>self.x<span class="br0">&#41;</span>-<span style="color: #cc66cc;">1</span>
&nbsp;
        <span style="color: #808080;"># retourne l'espace vectoriel du polyn&ocirc;me d'interpolation de Lagrange</span>
        <span style="color: #0000ff;">return</span> <span style="color: #FF0000;">&quot;&#8477;{0}[X]&quot;</span>.format<span class="br0">&#40;</span>n<span class="br0">&#41;</span>
&nbsp;
&nbsp;
    <span style="color: #0000ff;">def</span> base<span class="br0">&#40;</span>self<span class="br0">&#41;</span>:
        <span style="color: #808080;"># retourne la base de polyn&ocirc;mes de self : (L0, L1, L2), x = [0, 1, 2]</span>
&nbsp;
        n = len<span class="br0">&#40;</span>self.x<span class="br0">&#41;</span>-<span style="color: #cc66cc;">1</span>
        base = <span style="color: #FF0000;">&quot;&quot;</span> 
&nbsp;
        <span style="color: #808080;"># parcours des indices des polyn&ocirc;mes de lagrange Li</span>
        <span style="color: #0000ff;">for</span> i <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span>n+<span style="color: #cc66cc;">1</span><span class="br0">&#41;</span>:
            base += <span style="color: #FF0000;">&quot;L&quot;</span> + str<span class="br0">&#40;</span>i<span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot;, &quot;</span>
&nbsp;
        <span style="color: #808080;"># cr&eacute;ation de la famille : (L0, L1, L2)</span>
        base = <span style="color: #FF0000;">&quot;(&quot;</span> + base<span class="br0">&#91;</span>:-<span style="color: #cc66cc;">2</span><span class="br0">&#93;</span> + <span style="color: #FF0000;">&quot;)&quot;</span>
&nbsp;
        <span style="color: #808080;"># retourne la base du polyn&ocirc;me d'interpolation de Lagrange</span>
        <span style="color: #0000ff;">return</span> <span style="color: #FF0000;">&quot;{0}, x = {1}&quot;</span>.format<span class="br0">&#40;</span>base, self.x<span class="br0">&#41;</span>
&nbsp;
&nbsp;
&nbsp;
    <span style="color: #0000ff;">def</span> <span style="color: #0080ff;">__add__</span><span class="br0">&#40;</span>self, other<span class="br0">&#41;</span>:
        <span style="color: #808080;"># m&eacute;thode permettant de red&eacute;finir l'op&eacute;rateur &laquo; + &raquo; pour 2 polyn&ocirc;mes d'interpolation de Lagrange ou 2 vecteurs :</span>
        <span style="color: #808080;"># (y0, ..., yn) + (z0, ..., zn) = (y0 + z0, ..., yn + zn)</span>
&nbsp;
        <span style="color: #808080;"># si other est un objet de la classe Polynome_lagrange</span>
        <span style="color: #0000ff;">if</span> isinstance<span class="br0">&#40;</span>other, Polynome_lagrange<span class="br0">&#41;</span>:
&nbsp;
            <span style="color: #808080;"># si les 2 vecteurs self et other sont d&eacute;finis dans la m&ecirc;me base (l0, l1, ..., ln)</span>
            <span style="color: #0000ff;">if</span> self.x==other.x:
&nbsp;
                <span style="color: #808080;"># addition des 2 vecteurs self.y et other.y (2 tableaux numpy)</span>
                y = self.y + other.y
&nbsp;
                <span style="color: #808080;"># renvoie le polyn&ocirc;mes r&eacute;sultat de l'addition des 2 polyn&ocirc;mes self et other</span>
                <span style="color: #0000ff;">return</span> Polynome_lagrange<span class="br0">&#40;</span>self.x, y<span class="br0">&#41;</span>
&nbsp;
            <span style="color: #0000ff;">else</span>: <span style="color: #808080;"># sinon</span>
&nbsp;
                <span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Les deux vecteurs ne sont pas d&eacute;finis dans la m&ecirc;me base !&quot;</span><span class="br0">&#41;</span>
&nbsp;
        <span style="color: #0000ff;">else</span>: <span style="color: #808080;"># sinon</span>
&nbsp;
            <span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Le produit scalaire doit porter sur deux objets de la classe Polynome_lagrange !&quot;</span><span class="br0">&#41;</span>
&nbsp;
&nbsp;
    <span style="color: #0000ff;">def</span> <span style="color: #0080ff;">__mul__</span><span class="br0">&#40;</span>self, s<span class="br0">&#41;</span>:
        <span style="color: #808080;"># m&eacute;thode permettant de multiplier other par un scalaire s.</span>
        <span style="color: #808080;"># s*(y0, ..., yn) = (s*y0, ..., s*yn)</span>
&nbsp;
        <span style="color: #808080;"># multiplication du vecteur self.y par le scalaire s</span>
        y = s*self.y
&nbsp;
        <span style="color: #808080;"># renvoie le polyn&ocirc;me d'interpolation de Lagrange r&eacute;sultat de la multiplication de self par le scalaire s</span>
        <span style="color: #0000ff;">return</span> Polynome_lagrange<span class="br0">&#40;</span>self.x, y<span class="br0">&#41;</span> 
&nbsp;
&nbsp;
    <span style="color: #0000ff;">def</span> <span style="color: #0080ff;">__matmul__</span><span class="br0">&#40;</span>self, other<span class="br0">&#41;</span>:
        <span style="color: #808080;"># m&eacute;thode permettant de r&eacute;aliser le produit scalaire entre les polyn&ocirc;mes self et other</span>
        <span style="color: #808080;"># (y0, ..., yn)&sdot;(z0, ..., zn)  = y0&sdot;z0 + ... + yn&sdot;zn</span>
&nbsp;
        <span style="color: #808080;"># si other est un objet de la classe Polynome_lagrange</span>
        <span style="color: #0000ff;">if</span> isinstance<span class="br0">&#40;</span>other, Polynome_lagrange<span class="br0">&#41;</span>:
&nbsp;
            <span style="color: #808080;"># si les 2 vecteurs self et other sont d&eacute;finis dans la m&ecirc;me base (l0, l1, ..., ln)</span>
            <span style="color: #0000ff;">if</span> self.x==other.x:
&nbsp;
                <span style="color: #808080;"># calcul du produit scalaire des vecteurs self.y et other.y</span>
                ps = self.y @ other.y
&nbsp;
                <span style="color: #808080;"># renvoie la valeur du produit scalaire</span>
                <span style="color: #0000ff;">return</span> ps
&nbsp;
            <span style="color: #0000ff;">else</span>: <span style="color: #808080;"># sinon</span>
&nbsp;
                <span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Les deux vecteurs ne sont pas d&eacute;finis dans la m&ecirc;me base !&quot;</span><span class="br0">&#41;</span>
&nbsp;
        <span style="color: #0000ff;">else</span>: <span style="color: #808080;"># sinon</span>
&nbsp;
            <span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Le produit scalaire doit porter sur deux objets de la classe Polynome_lagrange !&quot;</span><span class="br0">&#41;</span>
&nbsp;
&nbsp;
    <span style="color: #0000ff;">def</span> norme<span class="br0">&#40;</span>self<span class="br0">&#41;</span>:
        <span style="color: #808080;"># m&eacute;thode permettant d'&eacute;valuer la norme du vecteur self d&eacute;fini dans la base (l0, l1, ..., ln)</span>
        <span style="color: #808080;"># norme((y0, ..., yn)) = (y0*y0 + ... + yn*yn)^0.5</span>
&nbsp;
        <span style="color: #808080;"># calcul de la norme du vecteur self.y</span>
        n = np.linalg.norm<span class="br0">&#40;</span>self.y<span class="br0">&#41;</span>
&nbsp;
        <span style="color: #808080;"># renvoie la valeur de la norme du vecteur</span>
        <span style="color: #0000ff;">return</span> n
&nbsp;
&nbsp;
    <span style="color: #0000ff;">def</span> coef_corr<span class="br0">&#40;</span>self, other<span class="br0">&#41;</span>:
        <span style="color: #808080;"># m&eacute;thode permettant d'&eacute;valuer le coefficient de corr&eacute;lation entre self et other</span>
&nbsp;
        <span style="color: #808080;"># si other est un objet de la classe Polynome_lagrange</span>
        <span style="color: #0000ff;">if</span> isinstance<span class="br0">&#40;</span>other, Polynome_lagrange<span class="br0">&#41;</span>:
&nbsp;
            <span style="color: #808080;"># si les 2 vecteurs self et other sont d&eacute;finis dans la m&ecirc;me base (l0, l1, ..., ln)</span>
            <span style="color: #0000ff;">if</span> self.x==other.x:
&nbsp;
                <span style="color: #808080;"># calcul du coefficient de corr&eacute;lation entre self.y et other.y</span>
                r = round<span class="br0">&#40;</span>np.corrcoef<span class="br0">&#40;</span>self.y, other.y<span class="br0">&#41;</span><span class="br0">&#91;</span><span style="color: #cc66cc;">0</span>, <span style="color: #cc66cc;">1</span><span class="br0">&#93;</span>, <span style="color: #cc66cc;">12</span><span class="br0">&#41;</span>
&nbsp;
                <span style="color: #808080;"># renvoi du coefficient de corr&eacute;lation</span>
                <span style="color: #0000ff;">return</span> r
&nbsp;
            <span style="color: #0000ff;">else</span>: <span style="color: #808080;"># sinon</span>
&nbsp;
                <span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Les deux vecteurs ne sont pas d&eacute;finis dans la m&ecirc;me base !&quot;</span><span class="br0">&#41;</span>
&nbsp;
        <span style="color: #0000ff;">else</span>: <span style="color: #808080;"># sinon</span>
&nbsp;
            <span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Le coefficient de corr&eacute;lation doit porter sur deux objets de la classe Polynome_lagrange !&quot;</span><span class="br0">&#41;</span>
&nbsp;
&nbsp;
    <span style="color: #0000ff;">def</span> <span style="color: #0080ff;">__eq__</span><span class="br0">&#40;</span>self, other<span class="br0">&#41;</span>:
        <span style="color: #808080;"># m&eacute;thode permettant de red&eacute;finir l'op&eacute;rateur &laquo; == &raquo; pour 2 polyn&ocirc;mes d'interpolation de Lagrange</span>
&nbsp;
        <span style="color: #808080;"># renvoie True si les bases et les listes de coordonn&eacute;es des vecteurs sont identiques</span>
        <span style="color: #0000ff;">return</span> <span class="br0">&#40;</span>self.x==other.x<span class="br0">&#41;</span> <span style="color: #0000ff;">and</span> np.array_equal<span class="br0">&#40;</span>self.y,other.y<span class="br0">&#41;</span>
&nbsp;
&nbsp;
    <span style="color: #0000ff;">def</span> <span style="color: #0080ff;">__call__</span><span class="br0">&#40;</span>self, X<span class="br0">&#41;</span>:
        <span style="color: #808080;"># permet d'&eacute;valuer le polyn&ocirc;me d'interpolation de Lagrange en fonction de X et des valeurs de x et y</span>
&nbsp;
        <span style="color: #808080;"># initialisation de la variable Lx</span>
        Lx = <span style="color: #cc66cc;">0</span>
&nbsp;
        <span style="color: #808080;"># parcours des y</span>
        <span style="color: #0000ff;">for</span> j <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span>len<span class="br0">&#40;</span>self.y<span class="br0">&#41;</span><span class="br0">&#41;</span>:
            lj = <span style="color: #cc66cc;">1</span>
            <span style="color: #808080;"># parcours des x</span>
            <span style="color: #0000ff;">for</span> i <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span>len<span class="br0">&#40;</span>self.x<span class="br0">&#41;</span><span class="br0">&#41;</span>:
                <span style="color: #0000ff;">if</span> i!=j:
                    lj *= <span class="br0">&#40;</span>X - self.x<span class="br0">&#91;</span>i<span class="br0">&#93;</span><span class="br0">&#41;</span>/<span class="br0">&#40;</span>self.x<span class="br0">&#91;</span>j<span class="br0">&#93;</span> - self.x<span class="br0">&#91;</span>i<span class="br0">&#93;</span><span class="br0">&#41;</span>
            <span style="color: #808080;"># ajour de la valeur de lj*y[j] &agrave; Lx</span>
            Lx +=self.y<span class="br0">&#91;</span>j<span class="br0">&#93;</span>*lj
&nbsp;
        <span style="color: #808080;"># renvoie la valeur de Lx</span>
        <span style="color: #0000ff;">return</span> Lx
&nbsp;
&nbsp;
<span style="color: #808080;"># fonction lambda permettant de changer le type d'appel pour &eacute;valuer le coefficient de corr&eacute;lation</span>
<span style="color: #808080;"># r = p1.coef_corr(p2) -&gt; r = coef_corr(p1, p2)</span>
coef_corr = <span style="color: #0000ff;">lambda</span> p1,p2 : p1.coef_corr<span class="br0">&#40;</span>p2<span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;IV-A. &Eacute;valuation du produit scalaire de deux polyn&ocirc;mes<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># cr&eacute;ation du 1er objet de la classe Polynome_lagrange</span>
p1 = Polynome_lagrange<span class="br0">&#40;</span>x=<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span>, <span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">2</span><span class="br0">&#93;</span>, y=<span class="br0">&#91;</span><span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">2</span>, <span style="color: #cc66cc;">1</span><span class="br0">&#93;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># cr&eacute;ation du 2e objet de la classe Polynome_lagrange</span>
p2 = Polynome_lagrange<span class="br0">&#40;</span>x=<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span>, <span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">2</span><span class="br0">&#93;</span>, y=<span class="br0">&#91;</span>-<span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">1</span>, -<span style="color: #cc66cc;">1</span><span class="br0">&#93;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche les expressions des polyn&ocirc;mes p1 et p2</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;p1 =&quot;</span>, p1<span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;p2 =&quot;</span>, p2<span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche l'appartenance de p1 et p2 &agrave; leur espace vectoriel : R2[X], Base = (L0, L1, L2), x = [0, 1, 2]</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;p1 &isin; &quot;</span> + p1.espace<span class="br0">&#40;</span><span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot;, Base = &quot;</span> + p1.base<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;p2 &isin; &quot;</span> + p2.espace<span class="br0">&#40;</span><span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot;, Base = &quot;</span> + p2.base<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># calcul du produit scalaire de p1 et p2</span>
ps = <span class="br0">&#40;</span>p1 @ p2<span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche la valeur du produit scalaire de p1 et p2</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;p1&sdot;p2 = {0}&quot;</span>.format<span class="br0">&#40;</span>ps<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;IV-B. &Eacute;valuation de la norme d'un polyn&ocirc;me<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># cr&eacute;ation de l'objet de la classe Polynome_lagrange</span>
p = Polynome_lagrange<span class="br0">&#40;</span>x=<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span>, <span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">2</span><span class="br0">&#93;</span>, y=<span class="br0">&#91;</span><span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">1</span><span class="br0">&#93;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche l'expression du polyn&ocirc;me p</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;p =&quot;</span>, p<span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche l'appartenance de p &agrave; leur espace vectoriel : R2[X], Base = (L0, L1, L2), x = [0, 1, 2]</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;p &isin; &quot;</span> + p.espace<span class="br0">&#40;</span><span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot;, Base = &quot;</span> + p.base<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># calcul la norme de p</span>
n = p.norme<span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche la valeur de la norme de p</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;norme(p) = {0}&quot;</span>.format<span class="br0">&#40;</span>n<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;IV-C. &Eacute;valuation du coefficient de corr&eacute;lation entre deux vecteurs<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># cr&eacute;ation du 1er objet de la classe Polynome_lagrange</span>
p1 = Polynome_lagrange<span class="br0">&#40;</span>x=<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span>, <span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">2</span><span class="br0">&#93;</span>, y=<span class="br0">&#91;</span><span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">2</span>, <span style="color: #cc66cc;">5</span><span class="br0">&#93;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># cr&eacute;ation du 2e objet de la classe Polynome_lagrange</span>
p2 = Polynome_lagrange<span class="br0">&#40;</span>x=<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span>, <span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">2</span><span class="br0">&#93;</span>, y=<span class="br0">&#91;</span><span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">3</span>, <span style="color: #cc66cc;">9</span><span class="br0">&#93;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche les expressions des polyn&ocirc;mes p1 et p2</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;p1 =&quot;</span>, p1<span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;p2 =&quot;</span>, p2<span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche l'appartenance de p1 et p2 &agrave; leur espace vectoriel : R2[X], Base = (L0, L1, L2), x = [0, 1, 2]</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;p1 &isin; &quot;</span> + p1.espace<span class="br0">&#40;</span><span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot;, Base = &quot;</span> + p1.base<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;p2 &isin; &quot;</span> + p2.espace<span class="br0">&#40;</span><span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot;, Base = &quot;</span> + p2.base<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># calcul du coefficient de corr&eacute;lation entre p1 et p2</span>
<span style="color: #808080;">#r = p1.coef_corr(p2)</span>
r = coef_corr<span class="br0">&#40;</span>p1, p2<span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche la valeur du coefficient de corr&eacute;lation</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;coef_corr(p1,&sdot;p2) = {0}&quot;</span>.format<span class="br0">&#40;</span>r<span class="br0">&#41;</span><span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
<br />
<b>V. Conclusion</b><br />
<br />
Après avoir montré que la famille des polynômes de Lagrange <b>(l<sub>0</sub>, l<sub>1</sub>, …, l<sub>n</sub>)</b> constitue une base orthonormée de l'espace des polynômes <b>&#8477;<sub>n</sub>[X]</b>, on a pu expliquer comment évaluer le produit scalaire et le coefficient de corrélation entre ces vecteurs.<br />
<br />
Ensuite, on a pu également ajouter ces nouvelles opérations à notre classe Polynome_Lagrange pour enfin les tester dans l'environnement Python. <br />
<br />
<br />
<b>Sources : </b><br />
<br />
<a href="https://fr.wikipedia.org/wiki/Base_orthonorm%C3%A9e" target="_blank">https://fr.wikipedia.org/wiki/Base_orthonorm%C3%A9e</a><br />
<a href="https://fr.wikipedia.org/wiki/Base_canonique" target="_blank">https://fr.wikipedia.org/wiki/Base_canonique</a><br />
<a href="https://fr.wikipedia.org/wiki/Produit_scalaire" target="_blank">https://fr.wikipedia.org/wiki/Produit_scalaire</a><br />
<a href="https://fr.wikipedia.org/wiki/Produit_scalaire_canonique" target="_blank">https://fr.wikipedia.org/wiki/Produi...aire_canonique</a><br />
<a href="https://fr.wikipedia.org/wiki/Corr%C3%A9lation_(statistiques)" target="_blank">https://fr.wikipedia.org/wiki/Corr%C...(statistiques)</a><br />
<a href="https://fr.wikipedia.org/wiki/Covariance" target="_blank">https://fr.wikipedia.org/wiki/Covariance</a><br />
<a href="https://fr.wikipedia.org/wiki/Interpolation_lagrangienne" target="_blank">https://fr.wikipedia.org/wiki/Interp...n_lagrangienne</a><br />
<a href="https://docs.python.org/fr/3/library/operator.html" target="_blank">https://docs.python.org/fr/3/library/operator.html</a></font></blockquote>

]]></content:encoded>
			<dc:creator>User</dc:creator>
			<guid isPermaLink="true">https://www.developpez.net/forums/blogs/44027-user/b10637/polynomes-lagrange-vus-vecteurs-d-base-orthonormee/</guid>
		</item>
		<item>
			<title>Programmation en Python : algorithme des k-moyennes</title>
			<link>https://www.developpez.net/forums/blogs/44027-user/b10625/programmation-python-algorithme-k-moyennes/</link>
			<pubDate>Sun, 25 Aug 2024 19:10:44 GMT</pubDate>
			<description><![CDATA[*I. Introduction* 
 
D'après...]]></description>
			<content:encoded><![CDATA[<blockquote class="blogcontent restore"><font size="2"><br />
<b>I. Introduction</b><br />
<br />
D'après Wikipédia, le partitionnement en <a href="https://fr.wikipedia.org/wiki/K-moyennes" target="_blank">k-moyennes</a> (ou k-means en anglais) est une méthode de partitionnement de données et un problème d'optimisation combinatoire. Étant donnés des points et un entier <b>k</b>, le problème est de diviser les points en k groupes, souvent appelés clusters, de façon à minimiser une certaine fonction. On considère la distance d'un point à la moyenne des points de son cluster ; la fonction à minimiser est la somme des carrés de ces distances. <br />
<br />
L'algorithme des k-moyennes peut être utilisé par exemple pour réduire le nombre de couleurs d'une image sans que cela ne nuise trop à sa qualité. Cela peut être utile à des fins de compression ou pour permettre l'affichage optimal d'une image sur un écran ou une imprimante n'offrant pas une grande variété de couleurs. Les k-moyennes sont également employées en <a href="https://fr.wikipedia.org/wiki/Apprentissage_non_supervis%C3%A9" target="_blank">apprentissage non supervisé</a>  où l'on divise des observations en k groupes.  <br />
<br />
L'objectif de ce billet est d'implémenter en Python l'algorithme classique des <b>k-moyennes</b> en créant sa propre fonction de partitionnement. En complément, on va également ajouter différentes instructions <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">print()</span> dans le code de la fonction afin d'afficher le contenu de certaines variables durant l'exécution du code et ainsi de mieux suivre son déroulement.<br />
<br />
Cet algorithme est également décrit dans le tutoriel <a href="https://khayyam.developpez.com/articles/data-science/clustering/k-means/" target="_blank">Partitionnement des données : algorithme des k-moyennes</a> de <a href="https://www.developpez.net/forums/u29897/khayyam90/" target="_blank">Pierre Schwartz</a>.<br />
<br />
<br />
<b>II. Définition</b><br />
<br />
Étant donné un ensemble de points (<b>x<sub>1</sub>, x<sub>2</sub>, …, x<sub>n</sub></b>), on cherche à partitionner les n points en <b>k</b> ensembles <b>S = {S<sub>1</sub>, S<sub>2</sub>, …, S<sub>k</sub>} (k &#8804; n)</b> en minimisant la distance entre les points à l'intérieur de chaque groupe :<br />
<img src="https://www.developpez.net/forums/attachments/p657882d1722786931/c-cpp/outils-c-cpp/autres-editeurs/editer-sources/somme_distances.png/" border="0" alt="Nom : somme_distances.png
Affichages : 11866
Taille : 4,9 Ko"  style="float: CONFIG" /><br />
<br />
où <b>&#956;<sub>i</sub></b> est le barycentre ou le centroïde des points dans <b>S<sub>i</sub></b>. <br />
<br />
<br />
<br />
<b>III. Algorithme des k-moyennes</b><br />
<br />
L'algorithme classique pour le problème, parfois appelé méthode des k-moyennes, est très utilisé en pratique. Il peut être décrit de la façon suivante :<br />
<br />
<b>1.</b> Choisir <b>k</b> points qui représentent les positions moyennes initiales <b>m<sub>1</sub><sup>(1)</sup>, …, m<sub>k</sub><sup>(1)</sup></b> (au hasard par exemple) ;<br />
<br />
<b>2.</b> Répéter les étapes suivantes jusqu'à ce qu'il y ait convergence, c'est à dire que les k moyennes ne changent pas après leur mise à jour :<br />
	<br />
<ul><li style="">Initialiser à vide les <b>k</b> clusters <b>c<sub>1</sub>, ..., c<sub>k</sub></b> ;</li><li style="">Placer chaque point <b>x<sub>j</sub></b> de l'ensemble de départ dans le cluster <b>c<sub>i</sub></b> dont la dernière moyenne est la plus proche de <b>x<sub>j</sub></b> ;</li><li style="">Mettre à jour les <b>k</b> moyennes des <b>k</b> clusters ainsi obtenus.</li></ul><br />
<b>3.</b> Les derniers clusters obtenus représentent la solution donnée par l'algorithme.<br />
<br />
Simulation de la convergence des k-means (issue de la page <a href="https://en.wikipedia.org/wiki/K-means_clustering" target="_blank">k-means clustering</a>) :<br />
<br />
<img src="https://www.developpez.net/forums/attachments/p658035d1723048985/c-cpp/outils-c-cpp/autres-editeurs/editer-sources/k-means_convergence.gif/" border="0" alt="Nom : K-means_convergence.gif
Affichages : 3670
Taille : 222,4 Ko"  style="float: CONFIG" /><br />
<br />
<br />
Cette méthode, le plus souvent efficace, ne donne cependant pas toujours un résultat optimal. En tirant au hasard les k moyennes initiales et en réitérant l'algorithme de partitionnement plusieurs fois, on peut ainsi augmenter les chances d'obtenir les bonnes valeurs initiales et donc d'aboutir à une solution optimale.<br />
<br />
<br />
<br />
<b>IV. Implémentation en Python</b><br />
<br />
<br />
<b>IV-A. Partitionnement en k moyennes</b><br />
<br />
La fonction de partitionnement d'un ensemble de points basée sur l'algorithme des <b>k-moyennes</b> :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">def</span> partitionnement_k_means<span class="br0">&#40;</span>points, k, k_means=<span style="color: #339933;">None</span><span class="br0">&#41;</span>:
    <span style="color: #808080;"># fonction de partitionnement en k-moyennes</span>
    <span style="color: #808080;"># sources : https://en.wikipedia.org/wiki/K-means_clustering#Standard_algorithm_(naive_k-means)</span>
&nbsp;
    <span style="color: #808080;"># arguments :</span>
    <span style="color: #808080;"># points : liste des points ;</span>
    <span style="color: #808080;"># k : nombre de groupes dans le r&eacute;sultat du d&eacute;coupage ;</span>
    <span style="color: #808080;"># k_means : k moyennes initiales, argument optionnel.</span>
&nbsp;
    <span style="color: #0000ff;">if</span> <span style="color: #0000ff;">not</span> k_means: <span style="color: #808080;"># si l'argument k_means est ommis</span>
        <span style="color: #808080;"># tirage au hasard des k points repr&eacute;sentant les moyennes initiales</span>
        k_means = random.sample<span class="br0">&#40;</span>points, k<span class="br0">&#41;</span>
&nbsp;
    <span style="color: #808080;"># convergence &agrave; False au d&eacute;but</span>
    convergence = <span style="color: #339933;">False</span>
&nbsp;
    <span style="color: #808080;"># tant qu'il n'y a pas convergence (que les k moyennes ont chang&eacute;)</span>
    <span style="color: #0000ff;">while</span> <span style="color: #0000ff;">not</span> convergence:
&nbsp;
        <span style="color: #808080;"># initialisation de la liste des clusters</span>
        clusters = <span class="br0">&#91;</span><span class="br0">&#91;</span><span class="br0">&#93;</span> <span style="color: #0000ff;">for</span> _ <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span>k<span class="br0">&#41;</span><span class="br0">&#93;</span> 
&nbsp;
        <span style="color: #808080;"># parcours des points</span>
        <span style="color: #0000ff;">for</span> xj <span style="color: #0000ff;">in</span> points:
&nbsp;
            <span style="color: #808080;"># g&eacute;n&eacute;ration de la liste des distances du point xj aux moyennes des clusters</span>
            distances2_k_means = <span class="br0">&#91;</span>distance2<span class="br0">&#40;</span>xj, mi<span class="br0">&#41;</span> <span style="color: #0000ff;">for</span> mi <span style="color: #0000ff;">in</span> k_means<span class="br0">&#93;</span>
&nbsp;
            <span style="color: #808080;"># indice du cluster dont la moyenne est la plus proche de xj</span>
            indice_cluster = np.argmin<span class="br0">&#40;</span>distances2_k_means<span class="br0">&#41;</span>
&nbsp;
            <span style="color: #808080;"># ajout de xj au cluster rep&eacute;r&eacute; par indice_cluster</span>
            clusters<span class="br0">&#91;</span>indice_cluster<span class="br0">&#93;</span>.append<span class="br0">&#40;</span>xj<span class="br0">&#41;</span>
&nbsp;
&nbsp;
        <span style="color: #808080;"># la liste des moyennes devient la liste des moyennes pr&eacute;c&eacute;dentes</span>
        prev_k_means = k_means
&nbsp;
        <span style="color: #808080;"># g&eacute;n&eacute;ration de la liste des nouvelles moyennes</span>
        k_means = <span class="br0">&#91;</span>centroide<span class="br0">&#40;</span>ci<span class="br0">&#41;</span> <span style="color: #0000ff;">for</span> ci <span style="color: #0000ff;">in</span> clusters<span class="br0">&#93;</span>
&nbsp;
        convergence = <span class="br0">&#40;</span>k_means==prev_k_means<span class="br0">&#41;</span>
&nbsp;
    <span style="color: #0000ff;">return</span> clusters</pre></td></tr></table></pre>
</div><br />
La fonction <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">argmin</span> de la bibliothèque numpy va donc renvoyer l'indice de l'élément ayant la valeur minimale dans un tableau.<br />
<br />
si plusieurs occurrences de la valeur minimale existent, la première occurrence sera renvoyée comme indice :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:72px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="26"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br /></div></td><td valign="top"><pre style="margin: 0">&gt;&gt;&gt; <span style="color: #0000ff;">import</span> numpy <span style="color: #0000ff;">as</span> np
&gt;&gt;&gt; np.argmin<span class="br0">&#40;</span><span class="br0">&#91;</span><span style="color: #cc66cc;">3</span>, <span style="color: #cc66cc;">2</span>, <span style="color: #cc66cc;">4</span>, <span style="color: #cc66cc;">2</span>, <span style="color: #cc66cc;">5</span><span class="br0">&#93;</span><span class="br0">&#41;</span>
<span style="color: #cc66cc;">1</span></pre></td></tr></table></pre>
</div><br />
En ajoutant maintenant différentes instructions <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">print()</span> dans le code de la fonction, instructions permettant d'afficher le contenu de certaines variables durant l'exécution du code, on peut ainsi mieux suivre son déroulement :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br />50<br />51<br />52<br />53<br />54<br />55<br />56<br />57<br />58<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">def</span> partitionnement_k_means<span class="br0">&#40;</span>points, k, k_means=<span style="color: #339933;">None</span><span class="br0">&#41;</span>:
    <span style="color: #808080;"># fonction de partitionnement en k-moyennes</span>
    <span style="color: #808080;"># sources : https://en.wikipedia.org/wiki/K-means_clustering#Standard_algorithm_(naive_k-means)</span>
&nbsp;
    <span style="color: #808080;"># arguments :</span>
    <span style="color: #808080;"># points : liste des points ;</span>
    <span style="color: #808080;"># k : nombre de groupes dans le r&eacute;sultat du d&eacute;coupage ;</span>
    <span style="color: #808080;"># k_means : k moyennes initiales, argument optionnel.</span>
&nbsp;
    <span style="color: #0000ff;">if</span> <span style="color: #0000ff;">not</span> k_means: <span style="color: #808080;"># si l'argument k_means est ommis</span>
        <span style="color: #808080;"># tirage au hasard des k points repr&eacute;sentant les moyennes initiales</span>
        k_means = random.sample<span class="br0">&#40;</span>points, k<span class="br0">&#41;</span>
&nbsp;
    <span style="color: #808080;"># convergence &agrave; False au d&eacute;but</span>
    convergence = <span style="color: #339933;">False</span> 
&nbsp;
    no_iteration = <span style="color: #cc66cc;">1</span>
&nbsp;
    <span style="color: #808080;"># tant qu'il n'y a pas convergence (que les k moyennes ont chang&eacute;)</span>
    <span style="color: #0000ff;">while</span> <span style="color: #0000ff;">not</span> convergence:
&nbsp;
        <span style="color: #0000ff;">print</span><span class="br0">&#40;</span>f<span style="color: #FF0000;">&quot;It&eacute;ration n&deg;{no_iteration}<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
        <span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;k-means =&quot;</span>, k_means<span class="br0">&#41;</span>
&nbsp;
        affectations = <span style="color: #FF0000;">&quot;&quot;</span>
&nbsp;
        <span style="color: #808080;"># initialisation de la liste des clusters</span>
        clusters = <span class="br0">&#91;</span><span class="br0">&#91;</span><span class="br0">&#93;</span> <span style="color: #0000ff;">for</span> _ <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span>k<span class="br0">&#41;</span><span class="br0">&#93;</span>
&nbsp;
        <span style="color: #808080;"># parcours des points</span>
        <span style="color: #0000ff;">for</span> xj <span style="color: #0000ff;">in</span> points:
&nbsp;
            <span style="color: #808080;"># g&eacute;n&eacute;ration de la liste des distances du point xj aux moyennes des clusters</span>
            distances2_k_means = <span class="br0">&#91;</span>distance2<span class="br0">&#40;</span>xj, mi<span class="br0">&#41;</span> <span style="color: #0000ff;">for</span> mi <span style="color: #0000ff;">in</span> k_means<span class="br0">&#93;</span>
&nbsp;
            <span style="color: #808080;"># indice du cluster dont la moyenne est la plus proche de xj</span>
            indice_cluster = np.argmin<span class="br0">&#40;</span>distances2_k_means<span class="br0">&#41;</span>
&nbsp;
            <span style="color: #808080;"># ajout de xj au cluster rep&eacute;r&eacute; par indice_cluster</span>
            clusters<span class="br0">&#91;</span>indice_cluster<span class="br0">&#93;</span>.append<span class="br0">&#40;</span>xj<span class="br0">&#41;</span>
&nbsp;
            affectations += str<span class="br0">&#40;</span>xj<span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot; &rarr; clusters[{0}]; &quot;</span>.format<span class="br0">&#40;</span>indice_cluster<span class="br0">&#41;</span>
&nbsp;
        <span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;affectations :&quot;</span>, affectations<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span>:-<span style="color: #cc66cc;">2</span><span class="br0">&#93;</span><span class="br0">&#41;</span>        
        <span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;clusters =&quot;</span>, clusters<span class="br0">&#41;</span>
        <span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;somme_carr&eacute;s_distances =&quot;</span>, somme_distances2_k_means<span class="br0">&#40;</span>clusters<span class="br0">&#41;</span><span class="br0">&#41;</span>; <span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
        <span style="color: #808080;"># la liste des moyennes devient la liste pr&eacute;c&eacute;dente</span>
        prev_k_means = k_means
&nbsp;
        <span style="color: #808080;"># g&eacute;n&eacute;ration de la liste des nouvelles moyennes</span>
        k_means = <span class="br0">&#91;</span>centroide<span class="br0">&#40;</span>ci<span class="br0">&#41;</span> <span style="color: #0000ff;">for</span> ci <span style="color: #0000ff;">in</span> clusters<span class="br0">&#93;</span>
&nbsp;
        convergence = <span class="br0">&#40;</span>k_means==prev_k_means<span class="br0">&#41;</span>
&nbsp;
        no_iteration+=<span style="color: #cc66cc;">1</span>
&nbsp;
    <span style="color: #0000ff;">return</span> clusters</pre></td></tr></table></pre>
</div><br />
<b>IV-B. Tests de la fonction</b><br />
<br />
Testons donc notre fonction en choisissant k moyennes initiales :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #808080;"># liste des points </span>
points = <span class="br0">&#91;</span><span class="br0">&#40;</span><span style="color: #cc66cc;">2</span>,<span style="color: #cc66cc;">10</span><span class="br0">&#41;</span>,<span class="br0">&#40;</span><span style="color: #cc66cc;">2</span>,<span style="color: #cc66cc;">5</span><span class="br0">&#41;</span>,<span class="br0">&#40;</span><span style="color: #cc66cc;">8</span>,<span style="color: #cc66cc;">4</span><span class="br0">&#41;</span>,<span class="br0">&#40;</span><span style="color: #cc66cc;">5</span>,<span style="color: #cc66cc;">8</span><span class="br0">&#41;</span>,<span class="br0">&#40;</span><span style="color: #cc66cc;">7</span>,<span style="color: #cc66cc;">5</span><span class="br0">&#41;</span>,<span class="br0">&#40;</span><span style="color: #cc66cc;">6</span>,<span style="color: #cc66cc;">4</span><span class="br0">&#41;</span>,<span class="br0">&#40;</span><span style="color: #cc66cc;">1</span>,<span style="color: #cc66cc;">2</span><span class="br0">&#41;</span>,<span class="br0">&#40;</span><span style="color: #cc66cc;">4</span>,<span style="color: #cc66cc;">9</span><span class="br0">&#41;</span><span class="br0">&#93;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Liste des points :&quot;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span>points<span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># nombre de groupes</span>
k = <span style="color: #cc66cc;">3</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;k =&quot;</span>, k<span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># moyennes initiales</span>
k_means = <span class="br0">&#91;</span><span class="br0">&#40;</span><span style="color: #cc66cc;">8</span>,<span style="color: #cc66cc;">4</span><span class="br0">&#41;</span>,<span class="br0">&#40;</span><span style="color: #cc66cc;">5</span>,<span style="color: #cc66cc;">8</span><span class="br0">&#41;</span>,<span class="br0">&#40;</span><span style="color: #cc66cc;">7</span>,<span style="color: #cc66cc;">5</span><span class="br0">&#41;</span><span class="br0">&#93;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;k moyennes initiales :&quot;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span>k_means<span class="br0">&#41;</span>; <span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span> 
&nbsp;
<span style="color: #808080;"># partitionnement des n points en k groupes : algorithme des k-means</span>
resultat_k_means = partitionnement_k_means<span class="br0">&#40;</span>points, k, k_means<span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;R&eacute;sultat :&quot;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span>resultat_k_means<span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
Déroulement de l'exécution du code :<br />
<br />
<font color="#000080">Liste des points :<br />
[(2, 10), (2, 5), (8, 4), (5, 8), (7, 5), (6, 4), (1, 2), (4, 9)]<br />
<br />
k = 3<br />
<br />
k moyennes initiales :<br />
[(8, 4), (5, 8), (7, 5)]<br />
<br />
Itération n°1<br />
<br />
k-means = [(8, 4), (5, 8), (7, 5)]<br />
affectations : (2, 10) &#8594; clusters[1]; (2, 5) &#8594; clusters[1]; (8, 4) &#8594; clusters[0]; (5, 8) &#8594; clusters[1]; (7, 5) &#8594; clusters[2]; (6, 4) &#8594; clusters[2]; (1, 2) &#8594; clusters[2]; (4, 9) &#8594; clusters[1]<br />
clusters = [[(8, 4)], [(2, 10), (2, 5), (5, 8), (4, 9)], [(7, 5), (6, 4), (1, 2)]]<br />
somme_carrés_distances = 46.083333333333336<br />
<br />
Itération n°2<br />
<br />
k-means = [(8.0, 4.0), (3.25, 8.0), (4.666666666666667, 3.6666666666666665)]<br />
affectations : (2, 10) &#8594; clusters[1]; (2, 5) &#8594; clusters[2]; (8, 4) &#8594; clusters[0]; (5, 8) &#8594; clusters[1]; (7, 5) &#8594; clusters[0]; (6, 4) &#8594; clusters[2]; (1, 2) &#8594; clusters[2]; (4, 9) &#8594; clusters[1]<br />
clusters = [[(8, 4), (7, 5)], [(2, 10), (5, 8), (4, 9)], [(2, 5), (6, 4), (1, 2)]]<br />
somme_carrés_distances = 26.333333333333336<br />
<br />
Itération n°3<br />
<br />
k-means = [(7.5, 4.5), (3.6666666666666665, 9.0), (3.0, 3.6666666666666665)]<br />
affectations : (2, 10) &#8594; clusters[1]; (2, 5) &#8594; clusters[2]; (8, 4) &#8594; clusters[0]; (5, 8) &#8594; clusters[1]; (7, 5) &#8594; clusters[0]; (6, 4) &#8594; clusters[0]; (1, 2) &#8594; clusters[2]; (4, 9) &#8594; clusters[1]<br />
clusters = [[(8, 4), (7, 5), (6, 4)], [(2, 10), (5, 8), (4, 9)], [(2, 5), (1, 2)]]<br />
somme_carrés_distances = 14.333333333333334<br />
<br />
Itération n°4<br />
<br />
k-means = [(7.0, 4.333333333333333), (3.6666666666666665, 9.0), (1.5, 3.5)]<br />
affectations : (2, 10) &#8594; clusters[1]; (2, 5) &#8594; clusters[2]; (8, 4) &#8594; clusters[0]; (5, 8) &#8594; clusters[1]; (7, 5) &#8594; clusters[0]; (6, 4) &#8594; clusters[0]; (1, 2) &#8594; clusters[2]; (4, 9) &#8594; clusters[1]<br />
clusters = [[(8, 4), (7, 5), (6, 4)], [(2, 10), (5, 8), (4, 9)], [(2, 5), (1, 2)]]<br />
somme_carrés_distances = 14.333333333333334<br />
<br />
<br />
Résultat :<br />
[[(8, 4), (7, 5), (6, 4)], [(2, 10), (5, 8), (4, 9)], [(2, 5), (1, 2)]]</font><br />
<br />
En considérant la distance d'un point à la moyenne des points de son cluster, on constate que la somme des carrés de ces distances diminue après chaque itération jusqu'à atteindre la convergence.<br />
<br />
Dans un second test, les k moyennes initiales sont tirées au hasard, ainsi en réitérant la procédure on augmente les chances d'obtenir les bonnes valeurs initiales et donc d'aboutir à une solution optimale. On cherche en fait à minimiser la somme des carrés des distances :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br />50<br />51<br />52<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #808080;"># liste des points </span>
points = <span class="br0">&#91;</span><span class="br0">&#40;</span><span style="color: #cc66cc;">2</span>,<span style="color: #cc66cc;">10</span><span class="br0">&#41;</span>,<span class="br0">&#40;</span><span style="color: #cc66cc;">5</span>,<span style="color: #cc66cc;">0</span><span class="br0">&#41;</span>,<span class="br0">&#40;</span><span style="color: #cc66cc;">8</span>,<span style="color: #cc66cc;">4</span><span class="br0">&#41;</span>,<span class="br0">&#40;</span><span style="color: #cc66cc;">5</span>,<span style="color: #cc66cc;">8</span><span class="br0">&#41;</span>,<span class="br0">&#40;</span><span style="color: #cc66cc;">7</span>,<span style="color: #cc66cc;">5</span><span class="br0">&#41;</span>,<span class="br0">&#40;</span><span style="color: #cc66cc;">6</span>,<span style="color: #cc66cc;">4</span><span class="br0">&#41;</span>,<span class="br0">&#40;</span><span style="color: #cc66cc;">1</span>,<span style="color: #cc66cc;">2</span><span class="br0">&#41;</span>,<span class="br0">&#40;</span><span style="color: #cc66cc;">4</span>,<span style="color: #cc66cc;">9</span><span class="br0">&#41;</span><span class="br0">&#93;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Liste des points :&quot;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span>points<span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># nombre de groupes</span>
k = <span style="color: #cc66cc;">3</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;k =&quot;</span>, k<span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># variable repr&eacute;sentant la somme des distances des points &agrave; la moyenne de leur cluster</span>
somme_distances2_mini = <span style="color: #cc66cc;">10e10</span>
&nbsp;
<span style="color: #808080;"># nombre de tirages al&eacute;atoires des k moyennes initiales : nombre d'ex&eacute;cutions de la fonction de partitionnement</span>
nb_tirages = <span style="color: #cc66cc;">5</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;nombre de tirages =&quot;</span>, nb_tirages<span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># initialisation du g&eacute;n&eacute;rateur de nombres al&eacute;atoires</span>
random.seed<span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># on r&eacute;it&egrave;re le partitionnement pour minimiser la somme des distances des points &agrave; la moyenne de leur cluster</span>
<span style="color: #0000ff;">for</span> no_tirage <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span><span style="color: #cc66cc;">1</span>, nb_tirages+<span style="color: #cc66cc;">1</span><span class="br0">&#41;</span>:
&nbsp;
    <span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;<span style="color: #800000;">\n</span>---- Tirage n&deg;{0} ----<span style="color: #800000;">\n</span>&quot;</span>.format<span class="br0">&#40;</span>no_tirage<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
    <span style="color: #808080;"># partitionnement des n points en k groupes : algorithme des k-means</span>
    clusters = partitionnement_k_means<span class="br0">&#40;</span>points, k<span class="br0">&#41;</span>
&nbsp;
    <span style="color: #808080;"># calcul de la somme des carr&eacute;s des distances de chacun des points &agrave; la moyenne de leur cluster</span>
    somme_distances2 = somme_distances2_k_means<span class="br0">&#40;</span>clusters<span class="br0">&#41;</span>
&nbsp;
    <span style="color: #808080;"># si la somme des distances obtenue est inf&eacute;rieure &agrave; somme_distances2_mini</span>
    <span style="color: #0000ff;">if</span> somme_distances2&lt;somme_distances2_mini:
        <span style="color: #808080;"># m&eacute;morisation des clusters et de la somme minimum des carr&eacute;s des distances</span>
        resultat_k_means, somme_distances2_mini = clusters, somme_distances2
        <span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;&lt;&lt;&lt;-- R&eacute;sultat retenu --&gt;&gt;&gt;<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;R&eacute;sultat :&quot;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span>resultat_k_means<span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Somme des carr&eacute;s des distances :&quot;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span>somme_distances2_mini<span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
Extrait du déroulement du test :<br />
<br />
<font color="#000080">Liste des points :<br />
[(2, 10), (5, 0), (8, 4), (5, 8), (7, 5), (6, 4), (1, 2), (4, 9)]<br />
<br />
k = 3<br />
<br />
nombre de tirages = 5<br />
<br />
<br />
---- Tirage n°1 ----<br />
<br />
Itération n°1<br />
<br />
k-means = [(5, 8), (4, 9), (8, 4)]<br />
affectations : (2, 10) &#8594; clusters[1]; (5, 0) &#8594; clusters[2]; (8, 4) &#8594; clusters[2]; (5, 8) &#8594; clusters[0]; (7, 5) &#8594; clusters[2]; (6, 4) &#8594; clusters[2]; (1, 2) &#8594; clusters[0]; (4, 9) &#8594; clusters[1]<br />
clusters = [[(5, 8), (1, 2)], [(2, 10), (4, 9)], [(5, 0), (8, 4), (7, 5), (6, 4)]]<br />
somme_carrés_distances = 48.25<br />
<br />
Itération n°2<br />
<br />
k-means = [(3.0, 5.0), (3.0, 9.5), (6.5, 3.25)]<br />
affectations : (2, 10) &#8594; clusters[1]; (5, 0) &#8594; clusters[2]; (8, 4) &#8594; clusters[2]; (5, 8) &#8594; clusters[1]; (7, 5) &#8594; clusters[2]; (6, 4) &#8594; clusters[2]; (1, 2) &#8594; clusters[0]; (4, 9) &#8594; clusters[1]<br />
clusters = [[(1, 2)], [(2, 10), (5, 8), (4, 9)], [(5, 0), (8, 4), (7, 5), (6, 4)]]<br />
somme_carrés_distances = 26.416666666666668<br />
<br />
Itération n°3<br />
<br />
k-means = [(1.0, 2.0), (3.6666666666666665, 9.0), (6.5, 3.25)]<br />
affectations : (2, 10) &#8594; clusters[1]; (5, 0) &#8594; clusters[2]; (8, 4) &#8594; clusters[2]; (5, 8) &#8594; clusters[1]; (7, 5) &#8594; clusters[2]; (6, 4) &#8594; clusters[2]; (1, 2) &#8594; clusters[0]; (4, 9) &#8594; clusters[1]<br />
clusters = [[(1, 2)], [(2, 10), (5, 8), (4, 9)], [(5, 0), (8, 4), (7, 5), (6, 4)]]<br />
somme_carrés_distances = 26.416666666666668<br />
<br />
&lt;&lt;&lt;-- Résultat retenu --&gt;&gt;&gt;<br />
<br />
<br />
---- Tirage n°2 ----<br />
<br />
Itération n°1<br />
<br />
k-means = [(2, 10), (8, 4), (1, 2)]<br />
affectations : (2, 10) &#8594; clusters[0]; (5, 0) &#8594; clusters[2]; (8, 4) &#8594; clusters[1]; (5, 8) &#8594; clusters[0]; (7, 5) &#8594; clusters[1]; (6, 4) &#8594; clusters[1]; (1, 2) &#8594; clusters[2]; (4, 9) &#8594; clusters[0]<br />
clusters = [[(2, 10), (5, 8), (4, 9)], [(8, 4), (7, 5), (6, 4)], [(5, 0), (1, 2)]]<br />
somme_carrés_distances = 19.333333333333336<br />
<br />
Itération n°2<br />
<br />
k-means = [(3.6666666666666665, 9.0), (7.0, 4.333333333333333), (3.0, 1.0)]<br />
affectations : (2, 10) &#8594; clusters[0]; (5, 0) &#8594; clusters[2]; (8, 4) &#8594; clusters[1]; (5, 8) &#8594; clusters[0]; (7, 5) &#8594; clusters[1]; (6, 4) &#8594; clusters[1]; (1, 2) &#8594; clusters[2]; (4, 9) &#8594; clusters[0]<br />
clusters = [[(2, 10), (5, 8), (4, 9)], [(8, 4), (7, 5), (6, 4)], [(5, 0), (1, 2)]]<br />
somme_carrés_distances = 19.333333333333336<br />
<br />
&lt;&lt;&lt;-- Résultat retenu --&gt;&gt;&gt;<br />
<br />
<br />
---- Résultats des tirages n°3, 4 et 5 non retenus ---- <br />
<br />
<br />
Résultat :<br />
[[(2, 10), (5, 8), (4, 9)], [(8, 4), (7, 5), (6, 4)], [(5, 0), (1, 2)]]<br />
<br />
Somme des carrés des distances :<br />
19.333333333333336</font><br />
<br />
Chacun pourra aussi vérifier que plus k augmente, plus la somme des carrés des distances diminue.<br />
<br />
La librairie sklearn.cluster permet également de mettre en œuvre l'algorithme des k-means en Python.<br />
<br />
<br />
<b>IV-C. Module complet</b><br />
<br />
Voici le code complet du module pour effectuer les différents tests :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="40"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br />50<br />51<br />52<br />53<br />54<br />55<br />56<br />57<br />58<br />59<br />60<br />61<br />62<br />63<br />64<br />65<br />66<br />67<br />68<br />69<br />70<br />71<br />72<br />73<br />74<br />75<br />76<br />77<br />78<br />79<br />80<br />81<br />82<br />83<br />84<br />85<br />86<br />87<br />88<br />89<br />90<br />91<br />92<br />93<br />94<br />95<br />96<br />97<br />98<br />99<br />100<br />101<br />102<br />103<br />104<br />105<br />106<br />107<br />108<br />109<br />110<br />111<br />112<br />113<br />114<br />115<br />116<br />117<br />118<br />119<br />120<br />121<br />122<br />123<br />124<br />125<br />126<br />127<br />128<br />129<br />130<br />131<br />132<br />133<br />134<br />135<br />136<br />137<br />138<br />139<br />140<br />141<br />142<br />143<br />144<br />145<br />146<br />147<br />148<br />149<br />150<br />151<br />152<br />153<br />154<br />155<br />156<br />157<br />158<br />159<br />160<br />161<br />162<br />163<br />164<br />165<br />166<br />167<br />168<br />169<br />170<br />171<br />172<br />173<br />174<br />175<br />176<br />177<br />178<br />179<br />180<br />181<br />182<br />183<br />184<br />185<br />186<br />187<br />188<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">import</span> random
<span style="color: #0000ff;">import</span> numpy <span style="color: #0000ff;">as</span> np
&nbsp;
<span style="color: #0000ff;">def</span> centroide<span class="br0">&#40;</span>points<span class="br0">&#41;</span>:
    <span style="color: #808080;"># renvoie le centro&iuml;de des points</span>
&nbsp;
    x = <span class="br0">&#91;</span>p<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span><span class="br0">&#93;</span> <span style="color: #0000ff;">for</span> p <span style="color: #0000ff;">in</span> points<span class="br0">&#93;</span>
    y = <span class="br0">&#91;</span>p<span class="br0">&#91;</span><span style="color: #cc66cc;">1</span><span class="br0">&#93;</span> <span style="color: #0000ff;">for</span> p <span style="color: #0000ff;">in</span> points<span class="br0">&#93;</span>
&nbsp;
    <span style="color: #0000ff;">return</span> <span class="br0">&#40;</span>sum<span class="br0">&#40;</span>x<span class="br0">&#41;</span>/len<span class="br0">&#40;</span>x<span class="br0">&#41;</span>, sum<span class="br0">&#40;</span>y<span class="br0">&#41;</span>/len<span class="br0">&#40;</span>y<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
&nbsp;
<span style="color: #0000ff;">def</span> distance2<span class="br0">&#40;</span>x1, x2<span class="br0">&#41;</span>:
    <span style="color: #808080;"># calcul du carr&eacute; de la distance entre x1 et x2</span>
&nbsp;
    <span style="color: #0000ff;">return</span> pow<span class="br0">&#40;</span><span class="br0">&#40;</span>x1<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span><span class="br0">&#93;</span> - x2<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span><span class="br0">&#93;</span><span class="br0">&#41;</span>,<span style="color: #cc66cc;">2</span><span class="br0">&#41;</span> + pow<span class="br0">&#40;</span><span class="br0">&#40;</span>x1<span class="br0">&#91;</span><span style="color: #cc66cc;">1</span><span class="br0">&#93;</span> - x2<span class="br0">&#91;</span><span style="color: #cc66cc;">1</span><span class="br0">&#93;</span><span class="br0">&#41;</span>,<span style="color: #cc66cc;">2</span><span class="br0">&#41;</span>
&nbsp;
&nbsp;
<span style="color: #0000ff;">def</span> somme_distances2_k_means<span class="br0">&#40;</span>clusters<span class="br0">&#41;</span>:
    <span style="color: #808080;"># somme des carr&eacute;s des distances des points &agrave; la moyenne de leur cluster</span>
    <span style="color: #808080;"># fonction &agrave; minimiser</span>
&nbsp;
    <span style="color: #808080;"># initialisation de la somme des distances</span>
    somme_distances2 = <span style="color: #cc66cc;">0</span>
&nbsp;
    <span style="color: #808080;"># parcours des clusters</span>
    <span style="color: #0000ff;">for</span> ci <span style="color: #0000ff;">in</span> clusters:
        <span style="color: #808080;"># calcul du centro&iuml;de de ci</span>
        mi = centroide<span class="br0">&#40;</span>ci<span class="br0">&#41;</span>
&nbsp;
        <span style="color: #808080;"># ajout de la somme des carr&eacute;s des distances de chaque point &agrave; la moyenne de son cluster </span>
        somme_distances2 +=  sum<span class="br0">&#40;</span><span class="br0">&#91;</span>distance2<span class="br0">&#40;</span>xj, mi<span class="br0">&#41;</span> <span style="color: #0000ff;">for</span> xj <span style="color: #0000ff;">in</span> ci<span class="br0">&#93;</span><span class="br0">&#41;</span>
&nbsp;
    <span style="color: #808080;"># retourne la somme des carr&eacute;s des distances        </span>
    <span style="color: #0000ff;">return</span> somme_distances2
&nbsp;
&nbsp;
<span style="color: #0000ff;">def</span> partitionnement_k_means<span class="br0">&#40;</span>points, k, k_means=<span style="color: #339933;">None</span><span class="br0">&#41;</span>:
    <span style="color: #808080;"># fonction de partitionnement en k-moyennes</span>
    <span style="color: #808080;"># sources : https://en.wikipedia.org/wiki/K-means_clustering#Standard_algorithm_(naive_k-means)</span>
&nbsp;
    <span style="color: #808080;"># arguments :</span>
    <span style="color: #808080;"># points : liste des points ;</span>
    <span style="color: #808080;"># k : nombre de groupes dans le r&eacute;sultat du d&eacute;coupage ;</span>
    <span style="color: #808080;"># k_means : k moyennes initiales, argument optionnel.</span>
&nbsp;
    <span style="color: #0000ff;">if</span> <span style="color: #0000ff;">not</span> k_means: <span style="color: #808080;"># si l'argument k_means est ommis</span>
        <span style="color: #808080;"># tirage au hasard des k points repr&eacute;sentant les moyennes initiales</span>
        k_means = random.sample<span class="br0">&#40;</span>points, k<span class="br0">&#41;</span>
&nbsp;
    <span style="color: #808080;"># convergence &agrave; False au d&eacute;but</span>
    convergence = <span style="color: #339933;">False</span>
&nbsp;
    no_iteration = <span style="color: #cc66cc;">1</span>
&nbsp;
    <span style="color: #808080;"># tant qu'il n'y a pas convergence (que les k moyennes ont chang&eacute;)</span>
    <span style="color: #0000ff;">while</span> <span style="color: #0000ff;">not</span> convergence:
&nbsp;
        <span style="color: #0000ff;">print</span><span class="br0">&#40;</span>f<span style="color: #FF0000;">&quot;It&eacute;ration n&deg;{no_iteration}<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
        <span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;k-means =&quot;</span>, k_means<span class="br0">&#41;</span>
&nbsp;
        affectations = <span style="color: #FF0000;">&quot;&quot;</span>
&nbsp;
        <span style="color: #808080;"># initialisation de la liste des clusters</span>
        clusters = <span class="br0">&#91;</span><span class="br0">&#91;</span><span class="br0">&#93;</span> <span style="color: #0000ff;">for</span> _ <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span>k<span class="br0">&#41;</span><span class="br0">&#93;</span>
&nbsp;
        <span style="color: #808080;"># parcours des points</span>
        <span style="color: #0000ff;">for</span> xj <span style="color: #0000ff;">in</span> points:
&nbsp;
            <span style="color: #808080;"># g&eacute;n&eacute;ration de la liste des distances du point xj aux moyennes des clusters</span>
            distances2_k_means = <span class="br0">&#91;</span>distance2<span class="br0">&#40;</span>xj, mi<span class="br0">&#41;</span> <span style="color: #0000ff;">for</span> mi <span style="color: #0000ff;">in</span> k_means<span class="br0">&#93;</span>
&nbsp;
            <span style="color: #808080;"># indice du cluster dont la moyenne est la plus proche de xj</span>
            indice_cluster = np.argmin<span class="br0">&#40;</span>distances2_k_means<span class="br0">&#41;</span>
&nbsp;
            <span style="color: #808080;"># ajout de xj au cluster rep&eacute;r&eacute; par indice_cluster</span>
            clusters<span class="br0">&#91;</span>indice_cluster<span class="br0">&#93;</span>.append<span class="br0">&#40;</span>xj<span class="br0">&#41;</span>
&nbsp;
            affectations += str<span class="br0">&#40;</span>xj<span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot; &rarr; clusters[{0}]; &quot;</span>.format<span class="br0">&#40;</span>indice_cluster<span class="br0">&#41;</span>
&nbsp;
        <span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;affectations :&quot;</span>, affectations<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span>:-<span style="color: #cc66cc;">2</span><span class="br0">&#93;</span><span class="br0">&#41;</span>        
        <span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;clusters =&quot;</span>, clusters<span class="br0">&#41;</span>
        <span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;somme_carr&eacute;s_distances =&quot;</span>, somme_distances2_k_means<span class="br0">&#40;</span>clusters<span class="br0">&#41;</span><span class="br0">&#41;</span>; <span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
        <span style="color: #808080;"># la liste des moyennes devient la liste pr&eacute;c&eacute;dente</span>
        prev_k_means = k_means
&nbsp;
        <span style="color: #808080;"># g&eacute;n&eacute;ration de la liste des nouvelles moyennes</span>
        k_means = <span class="br0">&#91;</span>centroide<span class="br0">&#40;</span>ci<span class="br0">&#41;</span> <span style="color: #0000ff;">for</span> ci <span style="color: #0000ff;">in</span> clusters<span class="br0">&#93;</span>
&nbsp;
        convergence = <span class="br0">&#40;</span>k_means==prev_k_means<span class="br0">&#41;</span>
&nbsp;
        no_iteration+=<span style="color: #cc66cc;">1</span>
&nbsp;
    <span style="color: #0000ff;">return</span> clusters 
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;--- Algorithme des k-moyennes ---<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;I. Partitionnement en k-moyennes : choix de k moyennes initiales :<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># liste des points </span>
points = <span class="br0">&#91;</span><span class="br0">&#40;</span><span style="color: #cc66cc;">2</span>,<span style="color: #cc66cc;">10</span><span class="br0">&#41;</span>,<span class="br0">&#40;</span><span style="color: #cc66cc;">2</span>,<span style="color: #cc66cc;">5</span><span class="br0">&#41;</span>,<span class="br0">&#40;</span><span style="color: #cc66cc;">8</span>,<span style="color: #cc66cc;">4</span><span class="br0">&#41;</span>,<span class="br0">&#40;</span><span style="color: #cc66cc;">5</span>,<span style="color: #cc66cc;">8</span><span class="br0">&#41;</span>,<span class="br0">&#40;</span><span style="color: #cc66cc;">7</span>,<span style="color: #cc66cc;">5</span><span class="br0">&#41;</span>,<span class="br0">&#40;</span><span style="color: #cc66cc;">6</span>,<span style="color: #cc66cc;">4</span><span class="br0">&#41;</span>,<span class="br0">&#40;</span><span style="color: #cc66cc;">1</span>,<span style="color: #cc66cc;">2</span><span class="br0">&#41;</span>,<span class="br0">&#40;</span><span style="color: #cc66cc;">4</span>,<span style="color: #cc66cc;">9</span><span class="br0">&#41;</span><span class="br0">&#93;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Liste des points :&quot;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span>points<span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># nombre de groupes</span>
k = <span style="color: #cc66cc;">3</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;k =&quot;</span>, k<span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># moyennes initiales</span>
k_means = <span class="br0">&#91;</span><span class="br0">&#40;</span><span style="color: #cc66cc;">8</span>,<span style="color: #cc66cc;">4</span><span class="br0">&#41;</span>,<span class="br0">&#40;</span><span style="color: #cc66cc;">5</span>,<span style="color: #cc66cc;">8</span><span class="br0">&#41;</span>,<span class="br0">&#40;</span><span style="color: #cc66cc;">7</span>,<span style="color: #cc66cc;">5</span><span class="br0">&#41;</span><span class="br0">&#93;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;k moyennes initiales :&quot;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span>k_means<span class="br0">&#41;</span>; <span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span> 
&nbsp;
<span style="color: #808080;"># partitionnement des n points en k groupes : algorithme des k-means</span>
resultat_k_means = partitionnement_k_means<span class="br0">&#40;</span>points, k, k_means<span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;R&eacute;sultat :&quot;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span>resultat_k_means<span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
wait = input<span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Appuyer su la touche Entr&eacute;e pour continuer..&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;II. Partitionnement en k-moyennes : tirage au hasard des k moyennes initiales :<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># liste des points </span>
points = <span class="br0">&#91;</span><span class="br0">&#40;</span><span style="color: #cc66cc;">2</span>,<span style="color: #cc66cc;">10</span><span class="br0">&#41;</span>,<span class="br0">&#40;</span><span style="color: #cc66cc;">5</span>,<span style="color: #cc66cc;">0</span><span class="br0">&#41;</span>,<span class="br0">&#40;</span><span style="color: #cc66cc;">8</span>,<span style="color: #cc66cc;">4</span><span class="br0">&#41;</span>,<span class="br0">&#40;</span><span style="color: #cc66cc;">5</span>,<span style="color: #cc66cc;">8</span><span class="br0">&#41;</span>,<span class="br0">&#40;</span><span style="color: #cc66cc;">7</span>,<span style="color: #cc66cc;">5</span><span class="br0">&#41;</span>,<span class="br0">&#40;</span><span style="color: #cc66cc;">6</span>,<span style="color: #cc66cc;">4</span><span class="br0">&#41;</span>,<span class="br0">&#40;</span><span style="color: #cc66cc;">1</span>,<span style="color: #cc66cc;">2</span><span class="br0">&#41;</span>,<span class="br0">&#40;</span><span style="color: #cc66cc;">4</span>,<span style="color: #cc66cc;">9</span><span class="br0">&#41;</span><span class="br0">&#93;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Liste des points :&quot;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span>points<span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># nombre de groupes</span>
k = <span style="color: #cc66cc;">3</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;k =&quot;</span>, k<span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># variable repr&eacute;sentant la somme des distances des points &agrave; la moyenne de leur cluster</span>
somme_distances2_mini = <span style="color: #cc66cc;">10e10</span>
&nbsp;
<span style="color: #808080;"># nombre de tirages al&eacute;atoires des k moyennes initiales : nombre d'ex&eacute;cutions de la fonction de partitionnement</span>
nb_tirages = <span style="color: #cc66cc;">5</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;nombre de tirages =&quot;</span>, nb_tirages<span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># initialisation du g&eacute;n&eacute;rateur de nombres al&eacute;atoires</span>
random.seed<span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># on r&eacute;it&egrave;re le partitionnement pour minimiser la somme des distances des points &agrave; la moyenne de leur cluster</span>
<span style="color: #0000ff;">for</span> no_tirage <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span><span style="color: #cc66cc;">1</span>, nb_tirages+<span style="color: #cc66cc;">1</span><span class="br0">&#41;</span>:
&nbsp;
    <span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;<span style="color: #800000;">\n</span>---- Tirage n&deg;{0} ----<span style="color: #800000;">\n</span>&quot;</span>.format<span class="br0">&#40;</span>no_tirage<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
    <span style="color: #808080;"># partitionnement des n points en k groupes : algorithme des k-means</span>
    clusters = partitionnement_k_means<span class="br0">&#40;</span>points, k<span class="br0">&#41;</span>
&nbsp;
    <span style="color: #808080;"># calcul de la somme des carr&eacute;s des distances de chacun des points &agrave; la moyenne de leur cluster</span>
    somme_distances2 = somme_distances2_k_means<span class="br0">&#40;</span>clusters<span class="br0">&#41;</span>
&nbsp;
    <span style="color: #808080;"># si la somme des distances obtenue est inf&eacute;rieure &agrave; somme_distances2_mini</span>
    <span style="color: #0000ff;">if</span> somme_distances2&lt;somme_distances2_mini:
        <span style="color: #808080;"># m&eacute;morisation des clusters et de la somme minimum des carr&eacute;s des distances</span>
        resultat_k_means, somme_distances2_mini = clusters, somme_distances2
        <span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;&lt;&lt;&lt;-- R&eacute;sultat retenu --&gt;&gt;&gt;<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;R&eacute;sultat :&quot;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span>resultat_k_means<span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Somme des carr&eacute;s des distances :&quot;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span>somme_distances2_mini<span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
Si vous souhaitez avoir plus d'information sur le sujet, je vous invite à consulter les pages <a href="https://fr.wikipedia.org/wiki/K-moyennes" target="_blank">k-moyennes</a> et <a href="https://khayyam.developpez.com/articles/data-science/clustering/k-means/" target="_blank">Partitionnement des données : algorithme des k-moyennes</a>.<br />
<br />
<br />
<b>V. Conclusion</b><br />
<br />
Après avoir décrit l'algorithme des k-moyennes, on a donc pu l'implémenter en Python en créant sa propre fonction de partitionnement. Ensuite, en plaçant différents instructions <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">print()</span> dans le code de la fonction, on a pu aussi mieux visualiser le déroulement de son exécution.<br />
<br />
Enfin, en remarquant que la qualité du résultat de l'algorithme dépendait des k moyennes initiales, on a proposé une méthode permettant d'optimiser notre fonction.<br />
<br />
<br />
<b>Sources :</b><br />
<br />
<a href="https://fr.wikipedia.org/wiki/K-moyennes" target="_blank">https://fr.wikipedia.org/wiki/K-moyennes</a><br />
<a href="https://en.wikipedia.org/wiki/K-means_clustering" target="_blank">https://en.wikipedia.org/wiki/K-means_clustering</a><br />
<a href="https://khayyam.developpez.com/articles/data-science/clustering/k-means/" target="_blank">https://khayyam.developpez.com/artic...ering/k-means/</a><br />
<a href="https://fr.wikipedia.org/wiki/Apprentissage_non_supervis%C3%A9" target="_blank">https://fr.wikipedia.org/wiki/Appren...supervis%C3%A9</a><br />
</font></blockquote>

]]></content:encoded>
			<dc:creator>User</dc:creator>
			<guid isPermaLink="true">https://www.developpez.net/forums/blogs/44027-user/b10625/programmation-python-algorithme-k-moyennes/</guid>
		</item>
		<item>
			<title>Méthode de Monte-Carlo et répartition des nombres premiers</title>
			<link>https://www.developpez.net/forums/blogs/44027-user/b10611/methode-monte-carlo-repartition-nombres-premiers/</link>
			<pubDate>Mon, 10 Jun 2024 08:11:54 GMT</pubDate>
			<description>*I. Introduction* 
 
On...</description>
			<content:encoded><![CDATA[<blockquote class="blogcontent restore"><font size="3"><br />
<b>I. Introduction</b><br />
<br />
On souhaite évaluer au mieux la quantité de nombres premiers compris dans un intervalle d'entiers suffisamment grand de sorte qu'il n'est pas possible de tester dans un temps acceptable tous les nombres entiers de cet intervalle.<br />
<br />
En supposant à priori que les nombres premiers sont répartis de façon aléatoire, on va d'abord montrer comment effectuer ce test sur un nombre restreint d'entiers choisis au hasard, mais quand même suffisamment grand pour évaluer au mieux la quantité de nombres premiers compris dans cet intervalle.<br />
<br />
Ensuite, nous allons implémenter cette méthode de Monte-Carlo en Python afin notamment de vérifier que globalement plus le nombre de valeurs choisies dans l'intervalle est important, plus le résultat est précis et proche de celui obtenu avec une certaine fonction <b>Li(x)</b>.<br />
<br />
Enfin, nous allons créer une interface paramétrable Tkinter intégrant un graphique et permettant de tracer les courbes représentatives des deux fonctions.<br />
<br />
<br />
<b>II. Méthode de Monte-Carlo</b><br />
<br />
D'après Wikipedia, une <a href="https://fr.wikipedia.org/wiki/M%C3%A9thode_de_Monte-Carlo" target="_blank">méthode de Monte-Carlo</a>, ou méthode Monte-Carlo, est une méthode algorithmique visant à calculer une valeur numérique approchée en utilisant des procédés aléatoires, c'est-à-dire des techniques probabilistes.<br />
<br />
Les méthodes de Monte-Carlo sont particulièrement utilisées pour calculer des intégrales en dimensions plus grandes que <b>1</b> (en particulier, pour calculer des surfaces et des volumes). Elles sont également couramment utilisées en physique des particules, où des simulations probabilistes permettent d'estimer la forme d'un signal ou la sensibilité d'un détecteur. La comparaison des données mesurées à ces simulations peut permettre de mettre en évidence des caractéristiques inattendues, par exemple de nouvelles particules.<br />
<br />
Le véritable développement des méthodes de Monte-Carlo s'est effectué notamment sous l'impulsion de John von Neumann et Stanislaw Ulam.<br />
<br />
<br />
<br />
<b>III. Répartition des nombres premiers</b><br />
<br />
Un <a href="https://fr.wikipedia.org/wiki/Nombre_premier" target="_blank">nombre premier</a> est un entier naturel qui admet seulement deux diviseurs distincts entiers et positifs : <b>1</b> et le nombre considéré lui-même. <br />
<br />
Puisque tout nombre a pour diviseurs <b>1</b> et lui-même, comme le montre l’égalité <b>n = 1 × n</b>, les nombres premiers sont ceux qui n'ont pas d'autre diviseur. Par exemple, le nombre entier <b>7</b> est premier car <b>1</b> et <b>7</b> sont ses seuls diviseurs entiers et positifs.<br />
<br />
<br />
<b>III-A. Méthode de Monte-Carlo : évaluation de la proportion et de la quantité de nombres premiers compris dans un certain intervalle</b><br />
<br />
On souhaite donc évaluer au mieux la proportion de nombres premiers compris dans un intervalle d'entiers suffisamment grand <b>[x<sub>1</sub>, x<sub>n</sub>]</b> de sorte qu'il n'est pas possible de tester dans un temps acceptable tous les nombres entiers compris dans cet intervalle.<br />
<br />
En supposant à priori que les nombres premiers sont répartis de façon aléatoire, on effectue donc un tirage restreint de <b>k</b> entiers au hasard.<br />
<br />
On évalue alors parmi ces entiers la proportion observée <b>f</b> (de nombres premiers) définie comme le quotient du nombre de <a href="https://fr.wikipedia.org/wiki/Test_de_primalit%C3%A9" target="_blank">tests de primalité</a> positifs par le nombre <b>k</b> de tirages, en supposant tout de même que <b>k</b> est suffisamment grand pour profiter de la loi des grands nombres et du théorème central limite. La loi des grands nombres assure dans ce cas qu’il est très probable que la fréquence observée soit proche de la proportion <b>p</b>, et l'<a href="https://fr.wikipedia.org/wiki/Intervalle_de_confiance" target="_blank">intervalle de confiance</a> à <b>95%</b> est alors :<br />
<br />
<span class="highlight">[f - 1/&#8730;k, f + 1/&#8730;k]</span><br />
<br />
Autrement dit, il y a (au moins) <b>95%</b> de chances que la vraie valeur <b>p</b> soit dans l'intervalle de confiance <span class="highlight">[f - 1/&#8730;k, f + 1/&#8730;k]</span>.<br />
<br />
On remarque que plus <b>k</b> augmente, plus l'intervalle de confiance se réduit, et donc plus grande est la précision.<br />
<br />
La quantité estimée de nombres premiers s'obtient alors en multipliant simplement la proportion obtenue par <b>n</b>.<br />
<br />
Cette procédure peut être réitérée pour plusieurs intervalles successifs et plusieurs valeurs de <b>k</b> afin de mieux évaluer la précision de notre méthode.<br />
<br />
<br />
<b>III-B. Théorème des nombres premiers</b><br />
<br />
D'après Wikipedia, le <a href="https://fr.wikipedia.org/wiki/Th%C3%A9or%C3%A8me_des_nombres_premiers" target="_blank">théorème des nombres premiers</a> (Hadamard et de La Vallée Poussin, 1896) est un résultat concernant la distribution asymptotique des nombres premiers.<br />
<br />
La fonction <b>&#120587;</b> qui à un réel <b>x</b> associe <b>&#120587;(x)</b> le nombre de nombres premiers inférieurs ou égaux à <b>x</b>, est équivalente lorsque <b>x</b> tend vers <b>+&#8734;</b>, au quotient de <b>x</b> par son logarithme népérien <span class="highlight">x/ln(x)</span>, c'est à dire : <br />
<br />
<img src="https://www.developpez.net/forums/attachments/p655270d1716908313/webmasters-developpement-web/outils/xmlrad/xmlrad-version-7rc-xmlgram/limite_-.png/" border="0" alt="Nom : limite_&#120587;(&#119909;).png
Affichages : 15740
Taille : 1,5 Ko"  style="float: CONFIG" /><br />
<br />
Un approximant de <b>&#120587;(x)</b> nettement meilleur que <span class="highlight">x/ln(x)</span> est la fonction logarithme intégral <b>li(x)</b> ou sa variante, la fonction d'écart logarithmique intégrale <b>Li(x)</b> : <br />
<br />
<img src="https://www.developpez.net/forums/attachments/p655271d1716908465/webmasters-developpement-web/outils/xmlrad/xmlrad-version-7rc-xmlgram/li-x-.png/" border="0" alt="Nom : Li(x).png
Affichages : 4688
Taille : 5,3 Ko"  style="float: CONFIG" /><br />
<br />
Représentation graphique des trois courbes par Noel Bush :<br />
<br />
<img src="https://www.developpez.net/forums/attachments/p655322d1717000385/webmasters-developpement-web/outils/xmlrad/xmlrad-version-7rc-xmlgram/courbe_li-x-.png/" border="0" alt="Nom : courbe_Li(x).png
Affichages : 4621
Taille : 32,0 Ko"  style="float: CONFIG" /><br />
<br />
Comme on le voit sur le graphique, la courbe représentative de la fonction <b>Li(x)</b> en bleu se confond pratiquement avec celle représentant la fonction <b>&#120587;(x)</b> en rouge donnant la quantité réelle de nombres premiers inférieurs ou égaux à <b>x</b>.<br />
<br />
Grâce au théorème dit des nombres premiers nous disposons donc de fonctions nous permettant de connaître avec une bonne précision la quantité de nombres premiers inférieurs ou égaux à un réel <b>x</b> quand <b>x</b> tend vers l'infini.<br />
<br />
Nous pouvons donc maintenant comparer le résultat obtenu à l'aide de la méthode de Monte-Carlo sur un intervalle suffisamment grand <b>[x<sub>1</sub>, x<sub>n</sub>]</b> à celui évalué avec la fonction <b>Li(x)</b> et utilisant la formule :<br />
<br />
<img src="https://www.developpez.net/forums/attachments/p655832d1718004566/webmasters-developpement-web/outils/xmlrad/xmlrad-version-7rc-xmlgram/estimation_li-x-.png/" border="0" alt="Nom : estimation_Li(x).png
Affichages : 4588
Taille : 2,3 Ko"  style="float: CONFIG" /><br />
<br />
Ou plus simplement :<br />
<br />
<img src="https://www.developpez.net/forums/attachments/p655833d1718004580/webmasters-developpement-web/outils/xmlrad/xmlrad-version-7rc-xmlgram/estimation_li-x-_2.png/" border="0" alt="Nom : estimation_Li(x)_2.png
Affichages : 4585
Taille : 2,2 Ko"  style="float: CONFIG" /><br />
<br />
<br />
<b>IV. Implémentation en Python</b><br />
<br />
<br />
<b>IV-A. Méthode de Monte-Carlo</b><br />
<br />
On présente maintenant les fonctions permettant d'évaluer au mieux la proportion et la quantité de nombres premiers compris dans un certain intervalle de valeurs à l'aide de la méthode de Monte-Carlo :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">def</span> proportion_premiers<span class="br0">&#40;</span>x1, xn, k<span class="br0">&#41;</span>:
    <span style="color: #808080;"># x1 : borne inf&eacute;rieure de l'intervalle des nombres entiers</span>
    <span style="color: #808080;"># xn : borne sup&eacute;rieure de l'intervalle des entiers</span>
    <span style="color: #808080;"># k : nombre de valeurs tir&eacute;es au hasard dans l'intervalle [x1, xn] </span>
&nbsp;
    <span style="color: #808080;"># s&eacute;quence de nombres entiers compris dans l'intervalle [x1, xn]</span>
    nombres_entiers = range<span class="br0">&#40;</span>x1, xn + <span style="color: #cc66cc;">1</span><span class="br0">&#41;</span>
&nbsp;
    <span style="color: #808080;"># initialisation du compteur de nombres premiers</span>
    qte_premiers = <span style="color: #cc66cc;">0</span>
&nbsp;
    <span style="color: #808080;"># tirage au hasard de k entiers parmi la s&eacute;quence de n entiers</span>
    <span style="color: #0000ff;">for</span> j <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span>k<span class="br0">&#41;</span>:
&nbsp;
        <span style="color: #808080;"># choix d'un nombre entier au hasard parmi la liste de nombres entiers</span>
        N = random.choice<span class="br0">&#40;</span>nombres_entiers<span class="br0">&#41;</span>
&nbsp;
        <span style="color: #808080;"># si N est premier</span>
        <span style="color: #0000ff;">if</span> test_primalite<span class="br0">&#40;</span>N<span class="br0">&#41;</span>:
            <span style="color: #808080;"># incr&eacute;mentation du compteur de nombres premiers</span>
            qte_premiers+=<span style="color: #cc66cc;">1</span>
&nbsp;
    <span style="color: #808080;"># proportion de nombre premiers choisis au hasard dans l'intervalle [x1, xn]</span>
    f = qte_premiers/k
&nbsp;
    <span style="color: #808080;"># renvoi de la proportion de nombres premiers compris dans l'intervalle</span>
    <span style="color: #0000ff;">return</span> f
&nbsp;
&nbsp;
<span style="color: #0000ff;">def</span> quantite_premiers<span class="br0">&#40;</span>x1, xn, k<span class="br0">&#41;</span>:
    <span style="color: #808080;"># x1 : borne inf&eacute;rieure de l'intervalle des nombres entiers</span>
    <span style="color: #808080;"># xn : borne sup&eacute;rieure de l'intervalle des entiers</span>
    <span style="color: #808080;"># k : nombre de valeurs tir&eacute;es au hasard dans l'intervalle [x1, xn]</span>
&nbsp;
    <span style="color: #0000ff;">return</span> proportion_premiers<span class="br0">&#40;</span>x1, xn, k<span class="br0">&#41;</span>*<span class="br0">&#40;</span>xn-x1+<span style="color: #cc66cc;">1</span><span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
On souhaite d'abord afficher les proportions évaluées avec la fonction <b>Li(x)</b> et celles obtenues avec la méthode de Monte-Carlo pour plusieurs intervalles d'entiers et plusieurs valeurs de <b>k</b> :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #808080;"># nombre d'entiers par intervalle</span>
n = <span style="color: #cc66cc;">4000000</span>
&nbsp;
<span style="color: #808080;"># s&eacute;quence des x avec un pas de longueur n</span>
x_values = range<span class="br0">&#40;</span><span style="color: #cc66cc;">2000000</span>, <span style="color: #cc66cc;">14000001</span>, n<span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># parcours des x avec un pas de longueur n</span>
<span style="color: #0000ff;">for</span> x <span style="color: #0000ff;">in</span> x_values:
&nbsp;
    <span style="color: #808080;"># proportion de nombres premiers dans cet intervalle suivant la fonction Li(x)</span>
    p = <span class="br0">&#40;</span>Li<span class="br0">&#40;</span>x+n-<span style="color: #cc66cc;">1</span><span class="br0">&#41;</span>-Li<span class="br0">&#40;</span>x-<span style="color: #cc66cc;">1</span><span class="br0">&#41;</span><span class="br0">&#41;</span>/n
&nbsp;
    <span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Intervalle des valeurs : &quot;</span> + str<span class="br0">&#40;</span><span class="br0">&#91;</span>x, x+n-<span style="color: #cc66cc;">1</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
    <span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Proportion estim&eacute;e avec Li(x) : &quot;</span> + str<span class="br0">&#40;</span>round<span class="br0">&#40;</span>p,<span style="color: #cc66cc;">7</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
    <span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Qt&eacute; estim&eacute;e avec Li(x) : &quot;</span> + str<span class="br0">&#40;</span>round<span class="br0">&#40;</span>p*n<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
    <span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
    <span style="color: #808080;"># initialisation de la liste des r&eacute;sultats</span>
    results = <span class="br0">&#91;</span><span class="br0">&#93;</span>
&nbsp;
    <span style="color: #808080;"># parcours des exposants de 10 : 10^3, .., 10^5</span>
    <span style="color: #0000ff;">for</span> i <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span><span style="color: #cc66cc;">3</span>, <span style="color: #cc66cc;">6</span><span class="br0">&#41;</span>:
        k = <span style="color: #cc66cc;">10</span>**i
&nbsp;
        <span style="color: #808080;"># &eacute;valuation de la proportion de nombres premiers compris dans [x, x+n-1] : m&eacute;thode de Monte-Carlo</span>
        f = round<span class="br0">&#40;</span>proportion_premiers<span class="br0">&#40;</span>x, x+n-<span style="color: #cc66cc;">1</span>, k<span class="br0">&#41;</span>,<span style="color: #cc66cc;">7</span><span class="br0">&#41;</span>
&nbsp;
        <span style="color: #808080;"># bornes inf&eacute;rieure et sup&eacute;rieure de l'intervalle de confiance</span>
        borne_inf, borne_sup = round<span class="br0">&#40;</span>f - <span style="color: #cc66cc;">1</span>/math.sqrt<span class="br0">&#40;</span>k<span class="br0">&#41;</span>,<span style="color: #cc66cc;">7</span><span class="br0">&#41;</span>, round<span class="br0">&#40;</span>f + <span style="color: #cc66cc;">1</span>/math.sqrt<span class="br0">&#40;</span>k<span class="br0">&#41;</span>,<span style="color: #cc66cc;">7</span><span class="br0">&#41;</span>
&nbsp;
	<span style="color: #808080;"># ligne de r&eacute;sultats : [k, f, [borne_inf, borne_sup], n*f, [n*borne_inf, n*borne_sup]]</span>
        result = <span class="br0">&#91;</span>k, f, str<span class="br0">&#40;</span><span class="br0">&#91;</span>borne_inf, borne_sup<span class="br0">&#93;</span><span class="br0">&#41;</span>, round<span class="br0">&#40;</span>n*f<span class="br0">&#41;</span>, str<span class="br0">&#40;</span><span class="br0">&#91;</span>round<span class="br0">&#40;</span>n*borne_inf<span class="br0">&#41;</span>, round<span class="br0">&#40;</span>n*borne_sup<span class="br0">&#41;</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="br0">&#93;</span>
&nbsp;
        <span style="color: #808080;"># ajout du r&eacute;sultat &agrave; la liste</span>
        results.append<span class="br0">&#40;</span>result<span class="br0">&#41;</span>
&nbsp;
    <span style="color: #808080;"># cr&eacute;ation du tableau numpy &agrave; 2 dimensions contennant la liste de r&eacute;sultats</span>
    tb_valeurs = np.array<span class="br0">&#40;</span>results<span class="br0">&#41;</span>
&nbsp;
    <span style="color: #808080;"># cr&eacute;ation du dataframe</span>
    df = pd.DataFrame<span class="br0">&#40;</span>tb_valeurs, columns = <span class="br0">&#91;</span><span style="color: #FF0000;">'  k'</span>, <span style="color: #FF0000;">'  Proportion observ&eacute;e avec MC'</span>, <span style="color: #FF0000;">'  Intervalle de confiance'</span>, <span style="color: #FF0000;">'  Qt&eacute; estim&eacute;e avec MC'</span>, <span style="color: #FF0000;">'  Intervalle de confiance'</span><span class="br0">&#93;</span><span class="br0">&#41;</span>
&nbsp;
    <span style="color: #808080;"># affiche le dataframe</span>
    <span style="color: #0000ff;">print</span><span class="br0">&#40;</span>df<span class="br0">&#41;</span>
&nbsp;
    <span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;------------------------------------------------------------------------------------------------------------------&quot;</span><span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
Le code affiche les résultats obtenus à l'aide de la méthode de Monte-Carlo (MC) dans des DataFrames Pandas :<br />
<br />
<img src="https://www.developpez.net/forums/attachments/p655837d1718005984/webmasters-developpement-web/outils/xmlrad/xmlrad-version-7rc-xmlgram/tableaux_results.png/" border="0" alt="Nom : tableaux_results.png
Affichages : 4548
Taille : 45,4 Ko"  style="float: CONFIG" /><br />
<br />
Nous constatons que globalement plus <b>k</b> est grand, plus la proportion de nombres premiers observée dans chaque intervalle se rapproche de l'estimation obtenue à l'aide de la fonction <b>Li(x)</b>. On peut aussi mieux évaluer la précision de chaque résultat grâce à son intervalle de confiance à <b>95%</b>.<br />
<br />
<br />
<b>IV-B. Représentation graphique</b><br />
<br />
Nous souhaitons maintenant tracer les courbes représentatives de la fonction Li(x) et des quantités évaluées à l'aide de la méthode de Monte-Carlo (MC).<br />
<br />
<br />
<b>IV-B-1. Génération du graphique avec la librairie matplotlib</b><br />
<br />
Nous allons donc d'abord générer le graphique à l'aide de la librairie matplotlib :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br />50<br />51<br /></div></td><td valign="top"><pre style="margin: 0">mport matplotlib.pyplot <span style="color: #0000ff;">as</span> plt
&nbsp;
...
&nbsp;
<span style="color: #808080;"># valeur du pas dans la s&eacute;quence de nombres entiers</span>
n = <span style="color: #cc66cc;">200000</span>
&nbsp;
<span style="color: #808080;"># s&eacute;quence des x avec un pas de longueur n</span>
x_values = range<span class="br0">&#40;</span>n, <span style="color: #cc66cc;">40</span>*n+<span style="color: #cc66cc;">1</span>, n<span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># liste des quantit&eacute;s de nombres premiers estim&eacute;es &agrave; l'aide de la fonction Li(x) </span>
Li_values =<span class="br0">&#91;</span>Li<span class="br0">&#40;</span>x<span class="br0">&#41;</span> <span style="color: #0000ff;">for</span> x <span style="color: #0000ff;">in</span> x_values<span class="br0">&#93;</span>
&nbsp;
<span style="color: #808080;"># nombre de tirages par intervalle </span>
k = <span style="color: #cc66cc;">1000</span>
&nbsp;
<span style="color: #808080;"># initialisation de la liste des qt&eacute;s de nombres premiers : m&eacute;thode de Monte-Carlo</span>
y_values = <span class="br0">&#91;</span><span class="br0">&#93;</span>
&nbsp;
<span style="color: #808080;"># initialisation de la quantit&eacute; de nombres premiers</span>
qte_premiers = <span style="color: #cc66cc;">0</span>
&nbsp;
<span style="color: #808080;"># borne inf&eacute;rieure de l'intervalle [x1, x]</span>
x1=<span style="color: #cc66cc;">1</span> 
&nbsp;
<span style="color: #808080;"># parcours des x avec un pas de longueur n</span>
<span style="color: #0000ff;">for</span> x <span style="color: #0000ff;">in</span> x_values:
&nbsp;
    <span style="color: #808080;"># &eacute;valuation de la quantit&eacute; de nombres premiers inf&eacute;rieurs ou &eacute;gaux &agrave; x  : m&eacute;thode de Monte-Carlo</span>
    qte_premiers += quantite_premiers<span class="br0">&#40;</span>x1, x, k<span class="br0">&#41;</span>
&nbsp;
    <span style="color: #808080;"># ajout de la quantit&eacute; &agrave; la liste y_values</span>
    y_values.append<span class="br0">&#40;</span>qte_premiers<span class="br0">&#41;</span>
&nbsp;
    x1 = x+<span style="color: #cc66cc;">1</span> <span style="color: #808080;"># borne inf&eacute;rieure prochain intervalle</span>
&nbsp;
<span style="color: #808080;"># lissage des points</span>
<span style="color: #808080;"># y_values = savgol_filter(y_values, len(y_values)//2+1, 3)</span>
&nbsp;
plt.plot<span class="br0">&#40;</span>x_values, Li_values, label = <span style="color: #FF0000;">&quot;Li(x)&quot;</span><span class="br0">&#41;</span>
plt.plot<span class="br0">&#40;</span>x_values, y_values, label = <span style="color: #FF0000;">&quot;Quantit&eacute;s &eacute;valu&eacute;es avec MC&quot;</span><span class="br0">&#41;</span>
&nbsp;
plt.ylim<span class="br0">&#40;</span><span style="color: #cc66cc;">0</span><span class="br0">&#41;</span>
&nbsp;
plt.legend<span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># titre du graphique </span>
plt.title<span class="br0">&#40;</span><span style="color: #FF0000;">'Qt&eacute;s de nombres premiers inf&eacute;rieurs ou &eacute;gaux &agrave; x'</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affichage du graphique </span>
plt.show<span class="br0">&#40;</span><span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
Le code affiche le graphique :<br />
<br />
<img src="https://www.developpez.net/forums/attachments/p655540d1717435342/webmasters-developpement-web/outils/xmlrad/xmlrad-version-7rc-xmlgram/graphique.png/" border="0" alt="Nom : graphique.png
Affichages : 4598
Taille : 36,6 Ko"  style="float: CONFIG" /><br />
<br />
On peux également effectuer un lissage des points représentant les quantités estimées avec la méthode de Monte-Carlo en utilisant la fonction <a href="https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.savgol_filter.html" target="_blank">savgol_filter</a> présente dans la librairie scipy.stats.<br />
<br />
<br />
<b>IV-B-2. Intégration du graphique dans une interface Tkinter</b><br />
<br />
Nous allons maintenant créer une interface paramétrable avec Tkinter sur laquelle nous allons pouvoir notamment choisir les valeurs mini et maxi des <b>x</b>, ainsi que le nombre d'entiers tirés au hasard dans chaque intervalle des <b>x</b>, puis tracer les courbes représentatives des deux fonctions.<br />
<br />
Cet interface est définie à l'aide d'une classe Interface_graphique présente dans la librairie interface_graphique.py qui est d'ailleurs disponible en téléchargement à la fin du billet.<br />
<br />
Testons maintenant notre interface graphique :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">from</span> interface_graphique <span style="color: #0000ff;">import</span> Interface_graphique
&nbsp;
...
&nbsp;
<span style="color: #808080;"># valeur du pas dans la s&eacute;quence de nombres entiers</span>
n = <span style="color: #cc66cc;">200000</span>
&nbsp;
<span style="color: #808080;"># nombre de tirages par intervalle </span>
k = <span style="color: #cc66cc;">1000</span>
&nbsp;
<span style="color: #808080;"># cr&eacute;ation de l'objet Interface_graphique avec les param&egrave;tres : valeur_mini, valeur_maxi, valeur_pas, nb_tirages, Li, quantite_premiers</span>
interface_graphique = Interface_graphique<span class="br0">&#40;</span>n, <span style="color: #cc66cc;">40</span>*n, n, k, Li, quantite_premiers<span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># centre la fen&ecirc;tre</span>
interface_graphique.eval<span class="br0">&#40;</span><span style="color: #FF0000;">'tk::PlaceWindow . center'</span><span class="br0">&#41;</span>
&nbsp;
interface_graphique.mainloop<span class="br0">&#40;</span><span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
Le code affiche :<br />
<br />
<img src="https://www.developpez.net/forums/attachments/p656156d1718696546/webmasters-developpement-web/outils/xmlrad/xmlrad-version-7rc-xmlgram/interface_graphique.png/" border="0" alt="Nom : interface_graphique.png
Affichages : 4509
Taille : 36,7 Ko"  style="float: CONFIG" /><br />
<br />
<br />
<br />
<b>IV-C. Module Python</b><br />
<br />
On donne pour finir le code complet du module présent dans le fichier joint <a href="https://www.developpez.net/forums/attachments/p656220d1718779694/webmasters-developpement-web/outils/xmlrad/xmlrad-version-7rc-xmlgram/dossier_test.zip/"  title="Nom : dossier_test.zip
Affichages : 6063
Taille : 6,1 Ko">dossier_test.zip</a> :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="40"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br />50<br />51<br />52<br />53<br />54<br />55<br />56<br />57<br />58<br />59<br />60<br />61<br />62<br />63<br />64<br />65<br />66<br />67<br />68<br />69<br />70<br />71<br />72<br />73<br />74<br />75<br />76<br />77<br />78<br />79<br />80<br />81<br />82<br />83<br />84<br />85<br />86<br />87<br />88<br />89<br />90<br />91<br />92<br />93<br />94<br />95<br />96<br />97<br />98<br />99<br />100<br />101<br />102<br />103<br />104<br />105<br />106<br />107<br />108<br />109<br />110<br />111<br />112<br />113<br />114<br />115<br />116<br />117<br />118<br />119<br />120<br />121<br />122<br />123<br />124<br />125<br />126<br />127<br />128<br />129<br />130<br />131<br />132<br />133<br />134<br />135<br />136<br />137<br />138<br />139<br />140<br />141<br />142<br />143<br />144<br />145<br />146<br />147<br />148<br />149<br />150<br />151<br />152<br />153<br />154<br />155<br />156<br />157<br />158<br />159<br />160<br />161<br />162<br />163<br />164<br />165<br />166<br />167<br />168<br />169<br />170<br />171<br />172<br />173<br />174<br />175<br />176<br />177<br />178<br />179<br />180<br />181<br />182<br />183<br />184<br />185<br />186<br />187<br />188<br />189<br />190<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">import</span> math
<span style="color: #0000ff;">import</span> random
<span style="color: #0000ff;">import</span> numpy <span style="color: #0000ff;">as</span> np
<span style="color: #0000ff;">import</span> scipy.integrate <span style="color: #0000ff;">as</span> integrate
<span style="color: #0000ff;">import</span> pandas <span style="color: #0000ff;">as</span> pd
<span style="color: #0000ff;">import</span> matplotlib.pyplot <span style="color: #0000ff;">as</span> plt
<span style="color: #0000ff;">from</span> scipy.signal <span style="color: #0000ff;">import</span> savgol_filter
<span style="color: #0000ff;">from</span> interface_graphique <span style="color: #0000ff;">import</span> Interface_graphique
&nbsp;
&nbsp;
<span style="color: #0000ff;">def</span> Li<span class="br0">&#40;</span>x<span class="br0">&#41;</span>:
    s = integrate.quad<span class="br0">&#40;</span><span style="color: #0000ff;">lambda</span> t: <span style="color: #cc66cc;">1</span>/math.log<span class="br0">&#40;</span>t<span class="br0">&#41;</span>, <span style="color: #cc66cc;">2</span>, x<span class="br0">&#41;</span>
    <span style="color: #0000ff;">return</span> s<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span><span class="br0">&#93;</span>
&nbsp;
<span style="color: #0000ff;">def</span> proportion_premiers<span class="br0">&#40;</span>x1, xn, k<span class="br0">&#41;</span>:
    <span style="color: #808080;"># x1 : borne inf&eacute;rieure de l'intervalle des nombres entiers</span>
    <span style="color: #808080;"># xn : borne sup&eacute;rieure de l'intervalle des entiers</span>
    <span style="color: #808080;"># k : nombre de valeurs tir&eacute;es au hasard dans l'intervalle [x1, xn] </span>
&nbsp;
    <span style="color: #808080;"># s&eacute;quence de nombres entiers compris dans l'intervalle [x1, xn]</span>
    nombres_entiers = range<span class="br0">&#40;</span>x1, xn + <span style="color: #cc66cc;">1</span><span class="br0">&#41;</span>
&nbsp;
    <span style="color: #808080;"># initialisation du compteur de nombres premiers</span>
    qte_premiers = <span style="color: #cc66cc;">0</span>
&nbsp;
    <span style="color: #808080;"># tirage au hasard de k entiers parmi la s&eacute;quence de n entiers</span>
    <span style="color: #0000ff;">for</span> j <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span>k<span class="br0">&#41;</span>:
&nbsp;
        <span style="color: #808080;"># choix d'un nombre entier au hasard parmi la liste de nombres entiers</span>
        N = random.choice<span class="br0">&#40;</span>nombres_entiers<span class="br0">&#41;</span>
&nbsp;
        <span style="color: #808080;"># si N est premier</span>
        <span style="color: #0000ff;">if</span> test_primalite<span class="br0">&#40;</span>N<span class="br0">&#41;</span>:
            <span style="color: #808080;"># incr&eacute;mentation du compteur de nombres premiers</span>
            qte_premiers+=<span style="color: #cc66cc;">1</span>
&nbsp;
    <span style="color: #808080;"># proportion de nombre premiers choisis au hasard dans l'intervalle [x1, xn]</span>
    f = qte_premiers/k
&nbsp;
    <span style="color: #808080;"># renvoi de la proportion de nombres premiers compris dans l'intervalle</span>
    <span style="color: #0000ff;">return</span> f
&nbsp;
&nbsp;
<span style="color: #0000ff;">def</span> quantite_premiers<span class="br0">&#40;</span>x1, xn, k<span class="br0">&#41;</span>:
    <span style="color: #808080;"># x1 : borne inf&eacute;rieure de l'intervalle des nombres entiers</span>
    <span style="color: #808080;"># xn : borne sup&eacute;rieure de l'intervalle des entiers</span>
    <span style="color: #808080;"># k : nombre de valeurs tir&eacute;es au hasard dans l'intervalle [x1, xn]</span>
&nbsp;
    <span style="color: #0000ff;">return</span> proportion_premiers<span class="br0">&#40;</span>x1, xn, k<span class="br0">&#41;</span>*<span class="br0">&#40;</span>xn-x1+<span style="color: #cc66cc;">1</span><span class="br0">&#41;</span>
&nbsp;
&nbsp;
<span style="color: #0000ff;">def</span> test_primalite<span class="br0">&#40;</span>N<span class="br0">&#41;</span>:
    <span style="color: #808080;"># fonction permettant de tester si N est premier en utilisant la m&eacute;thode na&iuml;ve</span>
    <span style="color: #808080;"># N : nombre entier &agrave; tester</span>
&nbsp;
    <span style="color: #0000ff;">if</span> N==<span style="color: #cc66cc;">1</span>: <span style="color: #0000ff;">return</span> <span style="color: #339933;">False</span> <span style="color: #808080;"># 1 n'est pas un nombre premier</span>
&nbsp;
    <span style="color: #808080;"># d&eacute;termination du dernier entier m &agrave; tester comme diviseur de N : m est &eacute;gal &agrave; la partie enti&egrave;re de &radic;&#119873;</span>
    m = int<span class="br0">&#40;</span>math.sqrt<span class="br0">&#40;</span>N<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
    <span style="color: #808080;"># parcours des entiers : 2 -&gt; m</span>
    <span style="color: #0000ff;">for</span> i <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span><span style="color: #cc66cc;">2</span>, m+<span style="color: #cc66cc;">1</span><span class="br0">&#41;</span>:
        <span style="color: #808080;"># Si i divise N</span>
        <span style="color: #0000ff;">if</span> N % i == <span style="color: #cc66cc;">0</span>:
            <span style="color: #808080;"># N poss&egrave;de un diviseur donc n'est pas premier</span>
            <span style="color: #808080;"># renvoie le tuple False =&gt; est_premier</span>
            <span style="color: #0000ff;">return</span> <span style="color: #339933;">False</span>
&nbsp;
    <span style="color: #808080;"># N n'a pas de diviseur autre que 1 et lui-m&ecirc;me, il est donc premier.</span>
    <span style="color: #808080;"># renvoie True =&gt; est_premier</span>
    <span style="color: #0000ff;">return</span> <span style="color: #339933;">True</span>
&nbsp;
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;I. M&eacute;thode de Monte-Carlo : &eacute;valuation des proportions et des qt&eacute;s de nombres premiers compris dans des intervalles successifs ..<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
pd.set_option<span class="br0">&#40;</span><span style="color: #FF0000;">'display.max_columns'</span>, <span style="color: #cc66cc;">500</span><span class="br0">&#41;</span>
pd.set_option<span class="br0">&#40;</span><span style="color: #FF0000;">'display.width'</span>, <span style="color: #cc66cc;">1000</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># nombre d'entiers par intervalle</span>
n = <span style="color: #cc66cc;">4000000</span>
&nbsp;
<span style="color: #808080;"># s&eacute;quence des x avec un pas de longueur n</span>
x_values = range<span class="br0">&#40;</span><span style="color: #cc66cc;">2000000</span>, <span style="color: #cc66cc;">14000001</span>, n<span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># parcours des x avec un pas de longueur n</span>
<span style="color: #0000ff;">for</span> x <span style="color: #0000ff;">in</span> x_values:
&nbsp;
    <span style="color: #808080;"># proportion de nombres premiers dans cet intervalle suivant la fonction Li(x)</span>
    p = <span class="br0">&#40;</span>Li<span class="br0">&#40;</span>x+n-<span style="color: #cc66cc;">1</span><span class="br0">&#41;</span>-Li<span class="br0">&#40;</span>x-<span style="color: #cc66cc;">1</span><span class="br0">&#41;</span><span class="br0">&#41;</span>/n
&nbsp;
    <span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Intervalle des valeurs : &quot;</span> + str<span class="br0">&#40;</span><span class="br0">&#91;</span>x, x+n-<span style="color: #cc66cc;">1</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
    <span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Proportion estim&eacute;e avec Li(x) : &quot;</span> + str<span class="br0">&#40;</span>round<span class="br0">&#40;</span>p,<span style="color: #cc66cc;">7</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
    <span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Qt&eacute; estim&eacute;e avec Li(x) : &quot;</span> + str<span class="br0">&#40;</span>round<span class="br0">&#40;</span>p*n<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
    <span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
    <span style="color: #808080;"># initialisation de la liste des r&eacute;sultats</span>
    results = <span class="br0">&#91;</span><span class="br0">&#93;</span>
&nbsp;
    <span style="color: #808080;"># parcours des exposants de 10 : 10^3, .., 10^5</span>
    <span style="color: #0000ff;">for</span> i <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span><span style="color: #cc66cc;">3</span>, <span style="color: #cc66cc;">6</span><span class="br0">&#41;</span>:
        k = <span style="color: #cc66cc;">10</span>**i
&nbsp;
        <span style="color: #808080;"># &eacute;valuation de la proportion de nombres premiers compris dans [x, x+n-1] : m&eacute;thode de Monte-Carlo</span>
        f = round<span class="br0">&#40;</span>proportion_premiers<span class="br0">&#40;</span>x, x+n-<span style="color: #cc66cc;">1</span>, k<span class="br0">&#41;</span>,<span style="color: #cc66cc;">7</span><span class="br0">&#41;</span>
&nbsp;
        <span style="color: #808080;"># bornes inf&eacute;rieure et sup&eacute;rieure de l'intervalle de confiance</span>
        borne_inf, borne_sup = round<span class="br0">&#40;</span>f - <span style="color: #cc66cc;">1</span>/math.sqrt<span class="br0">&#40;</span>k<span class="br0">&#41;</span>,<span style="color: #cc66cc;">7</span><span class="br0">&#41;</span>, round<span class="br0">&#40;</span>f + <span style="color: #cc66cc;">1</span>/math.sqrt<span class="br0">&#40;</span>k<span class="br0">&#41;</span>,<span style="color: #cc66cc;">7</span><span class="br0">&#41;</span>
&nbsp;
	<span style="color: #808080;"># ligne de r&eacute;sultats : [k, f, [borne_inf, borne_sup], n*f, [n*borne_inf, n*borne_sup]]</span>
        result = <span class="br0">&#91;</span>k, f, str<span class="br0">&#40;</span><span class="br0">&#91;</span>borne_inf, borne_sup<span class="br0">&#93;</span><span class="br0">&#41;</span>, round<span class="br0">&#40;</span>n*f<span class="br0">&#41;</span>, str<span class="br0">&#40;</span><span class="br0">&#91;</span>round<span class="br0">&#40;</span>n*borne_inf<span class="br0">&#41;</span>, round<span class="br0">&#40;</span>n*borne_sup<span class="br0">&#41;</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="br0">&#93;</span>
&nbsp;
        <span style="color: #808080;"># ajout du r&eacute;sultat &agrave; la liste</span>
        results.append<span class="br0">&#40;</span>result<span class="br0">&#41;</span>
&nbsp;
    <span style="color: #808080;"># cr&eacute;ation du tableau numpy &agrave; 2 dimensions contennant la liste de r&eacute;sultats</span>
    tb_valeurs = np.array<span class="br0">&#40;</span>results<span class="br0">&#41;</span>
&nbsp;
    <span style="color: #808080;"># cr&eacute;ation du dataframe</span>
    df = pd.DataFrame<span class="br0">&#40;</span>tb_valeurs, columns = <span class="br0">&#91;</span><span style="color: #FF0000;">'  k'</span>, <span style="color: #FF0000;">'  Proportion observ&eacute;e avec MC'</span>, <span style="color: #FF0000;">'  Intervalle de confiance'</span>, <span style="color: #FF0000;">'  Qt&eacute; estim&eacute;e avec MC'</span>, <span style="color: #FF0000;">'  Intervalle de confiance'</span><span class="br0">&#93;</span><span class="br0">&#41;</span>
&nbsp;
    <span style="color: #808080;"># affiche le dataframe</span>
    <span style="color: #0000ff;">print</span><span class="br0">&#40;</span>df<span class="br0">&#41;</span>
&nbsp;
    <span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;------------------------------------------------------------------------------------------------------------------&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;II. Courbes repr&eacute;sentatives des qt&eacute;s de nombres premiers inf&eacute;rieurs o&ugrave; &eacute;gaux &agrave; x : valeurs de Li(x) / qt&eacute;s estim&eacute;es avec MC<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;II-A. G&eacute;n&eacute;ration du graphique avec la librairie matplotlib ..<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># valeur du pas dans la s&eacute;quence de nombres entiers</span>
n = <span style="color: #cc66cc;">200000</span>
&nbsp;
<span style="color: #808080;"># s&eacute;quence des x avec un pas de longueur n</span>
x_values = range<span class="br0">&#40;</span>n, <span style="color: #cc66cc;">40</span>*n+<span style="color: #cc66cc;">1</span>, n<span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># liste des quantit&eacute;s de nombres premiers estim&eacute;es &agrave; l'aide de la fonction Li(x) </span>
Li_values =<span class="br0">&#91;</span>Li<span class="br0">&#40;</span>x<span class="br0">&#41;</span> <span style="color: #0000ff;">for</span> x <span style="color: #0000ff;">in</span> x_values<span class="br0">&#93;</span>
&nbsp;
<span style="color: #808080;"># nombre de tirages par intervalle </span>
k = <span style="color: #cc66cc;">1000</span>
&nbsp;
<span style="color: #808080;"># initialisation de la liste des qt&eacute;s de nombres premiers : m&eacute;thode de Monte-Carlo</span>
y_values = <span class="br0">&#91;</span><span class="br0">&#93;</span>
&nbsp;
<span style="color: #808080;"># initialisation de la quantit&eacute; de nombres premiers</span>
qte_premiers = <span style="color: #cc66cc;">0</span>
&nbsp;
<span style="color: #808080;"># borne inf&eacute;rieure de l'intervalle [x1, x]</span>
x1=<span style="color: #cc66cc;">1</span> 
&nbsp;
<span style="color: #808080;"># parcours des x avec un pas de longueur n</span>
<span style="color: #0000ff;">for</span> x <span style="color: #0000ff;">in</span> x_values:
&nbsp;
    <span style="color: #808080;"># &eacute;valuation de la quantit&eacute; de nombres premiers inf&eacute;rieurs ou &eacute;gaux &agrave; x  : m&eacute;thode de Monte-Carlo</span>
    qte_premiers += quantite_premiers<span class="br0">&#40;</span>x1, x, k<span class="br0">&#41;</span>
&nbsp;
    <span style="color: #808080;"># ajout de la quantit&eacute; &agrave; la liste y_values</span>
    y_values.append<span class="br0">&#40;</span>qte_premiers<span class="br0">&#41;</span>
&nbsp;
    x1 = x+<span style="color: #cc66cc;">1</span> <span style="color: #808080;"># borne inf&eacute;rieure prochain intervalle</span>
&nbsp;
<span style="color: #808080;"># lissage des points</span>
<span style="color: #808080;"># y_values = savgol_filter(y_values, len(y_values)//2+1, 3)</span>
&nbsp;
plt.plot<span class="br0">&#40;</span>x_values, Li_values, label = <span style="color: #FF0000;">&quot;Li(x)&quot;</span><span class="br0">&#41;</span>
plt.plot<span class="br0">&#40;</span>x_values, y_values, label = <span style="color: #FF0000;">&quot;Quantit&eacute;s &eacute;valu&eacute;es avec MC&quot;</span><span class="br0">&#41;</span>
&nbsp;
plt.ylim<span class="br0">&#40;</span><span style="color: #cc66cc;">0</span><span class="br0">&#41;</span>
&nbsp;
plt.legend<span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># titre du graphique </span>
plt.title<span class="br0">&#40;</span><span style="color: #FF0000;">'Qt&eacute;s de nombres premiers inf&eacute;rieurs ou &eacute;gaux &agrave; x'</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affichage du graphique </span>
plt.show<span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;II-B. Param&eacute;trage du graphique sur une interface Tkinter ..&quot;</span><span class="br0">&#41;</span> 
&nbsp;
<span style="color: #808080;"># cr&eacute;ation de l'objet Interface_graphique avec les param&egrave;tres : valeur_mini, valeur_maxi, valeur_pas, nb_tirages, Li, quantite_premiers</span>
interface_graphique = Interface_graphique<span class="br0">&#40;</span>n, <span style="color: #cc66cc;">40</span>*n, n, k, Li, quantite_premiers<span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># centre la fen&ecirc;tre</span>
interface_graphique.eval<span class="br0">&#40;</span><span style="color: #FF0000;">'tk::PlaceWindow . center'</span><span class="br0">&#41;</span>
&nbsp;
interface_graphique.mainloop<span class="br0">&#40;</span><span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
<br />
<br />
<b>V. Conclusion</b><br />
<br />
Après avoir défini ce qu'est une méthode de Monte-Carlo, on a pu montrer comment l'utiliser pour évaluer au mieux la proportion de nombres premiers compris dans un intervalle suffisamment grand. <br />
<br />
Enfin, on a pu implémenter cet algorithme en Python afin notamment de vérifier que plus le nombre de valeurs choisies dans l'intervalle est important, plus le résultat est précis et proche de celui obtenu avec la fonction <b>Li(x)</b>. On a ainsi pu également montrer sur une série de grands nombres entiers que la fonction <b>Li(x)</b> se rapproche de  <b>&#120587;(x)</b> quand <b>x</b> augmente.<br />
<br />
<br />
<b>Téléchargement :</b><br />
<br />
<a href="https://www.developpez.net/forums/attachments/p656220d1718779694/webmasters-developpement-web/outils/xmlrad/xmlrad-version-7rc-xmlgram/dossier_test.zip/"  title="Nom : dossier_test.zip
Affichages : 6063
Taille : 6,1 Ko">dossier_test.zip</a><br />
<br />
<b>Sources :</b><br />
<br />
<a href="https://fr.wikipedia.org/wiki/M%C3%A9thode_de_Monte-Carlo" target="_blank">https://fr.wikipedia.org/wiki/M%C3%A...de_Monte-Carlo</a><br />
<a href="https://fr.wikipedia.org/wiki/Nombre_premier" target="_blank">https://fr.wikipedia.org/wiki/Nombre_premier</a><br />
<a href="https://fr.wikipedia.org/wiki/Intervalle_de_confiance" target="_blank">https://fr.wikipedia.org/wiki/Intervalle_de_confiance</a><br />
<a href="https://fr.wikipedia.org/wiki/Th%C3%A9or%C3%A8me_des_nombres_premiers" target="_blank">https://fr.wikipedia.org/wiki/Th%C3%...mbres_premiers</a><br />
</font></blockquote>

]]></content:encoded>
			<dc:creator>User</dc:creator>
			<guid isPermaLink="true">https://www.developpez.net/forums/blogs/44027-user/b10611/methode-monte-carlo-repartition-nombres-premiers/</guid>
		</item>
		<item>
			<title>Algorithmes probabilistes et nombres premiers : le test de primalité de Fermat</title>
			<link>https://www.developpez.net/forums/blogs/44027-user/b10604/algorithmes-probabilistes-nombres-premiers-test-primalite-fermat/</link>
			<pubDate>Mon, 06 May 2024 11:58:11 GMT</pubDate>
			<description>*I. Introduction* 
 
On...</description>
			<content:encoded><![CDATA[<blockquote class="blogcontent restore"><font size="2"><b>I. Introduction</b><br />
<br />
On s'intéresse maintenant aux <a href="https://fr.wikipedia.org/wiki/Algorithme_probabiliste" target="_blank">algorithmes probabilistes</a> et plus précisément au <a href="https://fr.wikipedia.org/wiki/Test_de_primalit%C3%A9_de_Fermat" target="_blank">test de primalité de Fermat</a> :<br />
<br />
On va d'abord définir ce qu'est un <a href="https://fr.wikipedia.org/wiki/Test_de_primalit%C3%A9#Tests_probabilistes" target="_blank">test de primalité probabiliste</a> en donnant comme exemple le test de primalité de Fermat. Ensuite, on va décrire cet algorithme et montrer comment le rendre plus fiable. <br />
<br />
Enfin, on va implémenter ce test en Python afin de le comparer au test de primalité classique en termes de rapidité d'exécution.<br />
<br />
<br />
<b>II. Algorithme probabiliste</b><br />
<br />
D'après Wikipedia, un <a href="https://fr.wikipedia.org/wiki/Algorithme_probabiliste" target="_blank">algorithme probabiliste</a>, ou algorithme randomisé, est un algorithme qui utilise une source de hasard. Plus précisément le déroulement de l’algorithme fait appel à des données tirées au hasard. Par exemple à un certain point de l’exécution, on tire un bit <b>0</b> ou <b>1</b>, selon la loi uniforme et si le résultat est <b>0</b>, on fait une certaine action <b>A</b> et si c'est <b>1</b>, on fait une autre action.<br />
<br />
<br />
<b>III. Test de primalité</b><br />
<br />
Un <a href="https://fr.wikipedia.org/wiki/Test_de_primalit%C3%A9" target="_blank">test de primalité</a> est un algorithme permettant de savoir si un nombre entier est <a href="https://fr.wikipedia.org/wiki/Nombre_premier" target="_blank">premier</a>. <br />
<br />
<br />
<b>III-A. Méthode naïve</b><br />
<br />
Le test le plus simple est celui des divisions successives : pour tester <b>N</b>, on vérifie s’il est divisible par l’un des entiers compris au sens large entre <b>2</b> et <b>N-1</b>. Si la réponse est négative, alors <b>N</b> est premier, sinon il est composé. <br />
<br />
On peut améliorer les performances de cet algorithme en testant tous les entiers entre <b>2</b> et <b>&#8730;&#119873;</b>, puisque si <b>N = pq</b>, alors soit <b>p&#8804;&#8730;&#119873;</b>, soit <b>q&#8804;&#8730;&#119873;</b>.<br />
<br />
<br />
<b>III-B. Tests probabilistes</b><br />
<br />
Toujours d'après Wikipedia, les <a href="https://fr.wikipedia.org/wiki/Test_de_primalit%C3%A9#Tests_probabilistes" target="_blank">tests probabilistes</a> ne sont pas des tests de primalité au sens strict (ils font partie des méthodes de Monte-Carlo) : ils ne permettent pas de garantir de façon certaine qu’un nombre est premier, mais leur faible coût en temps de calcul en font d’excellents candidats pour les applications en cryptologie qui souvent dépend de façon critique de grands nombres premiers et accepte un taux d’erreur pourvu qu’il soit très faible : on les appelle des nombres premiers industriels. L’idée de base du test de la primalité d’un nombre <b>N</b> est la suivante :<br />
<br />
<ul><li style="">Tirer aléatoirement un nombre <b>a</b>.</li><li style="">Vérifier une certaine identité qui fait intervenir <b>a</b> ainsi que le nombre donné <b>N</b> et qui est vraie si le nombre <b>N</b> est premier. Si l’identité n’est pas satisfaite, alors <b>N</b> est nécessairement composé et le test s’arrête ; dans ce cas, <b>a</b> est appelé un témoin du test.</li><li style="">Répéter l’étape <b>1</b> jusqu’à ce que la marge d’incertitude souhaitée soit atteinte.</li></ul><br />
Après plusieurs itérations, si <b>N</b> n’est pas reconnu comme un nombre composé, il est déclaré probablement premier.<br />
<br />
Étant donné un test, il peut exister certains nombres composés qui sont déclarés « probablement premier » quel que soit le témoin. De tels nombres résistant au test sont appelés nombres pseudopremiers pour ce test. <br />
<br />
<br />
<b>III-B-1. Test de primalité de Fermat</b><br />
<br />
En algorithmique, le <a href="https://fr.wikipedia.org/wiki/Test_de_primalit%C3%A9_de_Fermat" target="_blank">test de primalité de Fermat</a> est un test de primalité probabiliste basé sur le <a href="https://fr.wikipedia.org/wiki/Petit_th%C3%A9or%C3%A8me_de_Fermat" target="_blank">petit théorème de Fermat</a>. Il est de type <a href="https://fr.wikipedia.org/wiki/Algorithme_de_Monte-Carlo" target="_blank">Monte-Carlo</a> : s'il détecte qu'un nombre est composé alors il a raison ; en revanche, il peut se tromper s'il prétend que le nombre est premier. <br />
<br />
<div style="text-align: center;"><img src="https://www.developpez.net/forums/attachments/p653647d1713789211/webmasters-developpement-web/outils/xmlrad/xmlrad-eviter-certains-refresh-aux-consequences-genantes/test_fermat.png/" border="0" alt="Nom : test_fermat.png
Affichages : 17331
Taille : 9,2 Ko"  style="float: CONFIG" /></div><br />
<b>Petit théorème de Fermat :</b><br />
<br />
<div class="bbcode_container">
	<div class="bbcode_quote">
		<div class="quote_container">
			<div class="bbcode_quote_container"></div>
			
				<font size="2">Si <b>p</b> est un nombre premier alors pour tout <b>1 &#8804; a &lt; p</b>, alors <span class="highlight">a<sup>p-1</sup> &#8801; 1 (mod p)</span> ou encore <span class="highlight">a<sup>p-1</sup> mod p = 1</span>.</font>
			
		</div>
	</div>
</div>L'opération <span class="highlight">a<sup>p-1</sup> mod p</span> représente une <a href="https://fr.wikipedia.org/wiki/Exponentiation_modulaire" target="_blank">exponentiation modulaire</a>. Son calcul est considéré comme facile, même lorsque les nombres en jeu sont énormes.<br />
<br />
Si maintenant on fixe <b>a</b>, il se peut en fait que <span class="highlight">a<sup>p-1</sup> &#8801; 1 (mod p)</span> sans que <b>p</b> ne soit premier ; un tel nombre <b>a</b> est nécessairement premier avec <b>p</b>. Le nombre <b>p</b> est dit alors pseudo-premier de Fermat de base <b>a</b>.<br />
<br />
Le test de primalité de Fermat repose sur l'idée suivante : si <b>p</b> est composé, alors il est peu probable que <b>a<sup>p–1</sup></b> soit congru à <b>1</b> modulo <b>p</b> pour une valeur arbitraire de <b>a</b>, autrement dit il est peu probable qu'on ait <span class="highlight">a<sup>p-1</sup> mod p = 1</span>. <br />
<br />
Voici un pseudo-code pour le test de Fermat :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code  :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:156px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br /></div></td><td valign="top"><pre style="margin: 0">Fonction testPrimaliteFermat(N)
    choisir un entier positif a &lt; N au hasard   

    Si a<sup>N-1</sup> &#8801; 1 mod N alors
        renvoyer oui (N est probablement premier)
    Sinon
        renvoyer non (N est composé)
    Fin Si 

Fin Fonction</pre></td></tr></table></pre>
</div>On peut maintenant imaginer que si le test est positif pour plusieurs entiers positifs <b>a<sub>1</sub>, ..., a<sub>k</sub> &lt; N</b> choisis au hasard, on augmente les chances qu'il soit juste.<br />
<br />
On sait en fait que si <b>N</b> n'est pas un <a href="https://fr.wikipedia.org/wiki/Nombre_de_Carmichael" target="_blank">nombre de Carmichael</a>, alors on peut choisir <b>k</b> entiers positifs <b>a<sub>1</sub>, ..., a<sub>k</sub> &lt; N</b> au hasard, et la probabilité que le test de Fermat soit positif pour les <b>k</b> entiers si <b>N</b> est composé est inférieure à <b>1/2<sup>k</sup></b>.<br />
<br />
On obtient ainsi le pseudo-code :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code  :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br /></div></td><td valign="top"><pre style="margin: 0">Fonction testPrimaliteFermatItere(N)
     
    pour i de 1 jusqu'à k

	choisir un entier positif a<sub>i</sub> &lt; N au hasard

        Si a<sub>i</sub><sup>N-1</sup> &#8802; 1 mod N alors
            renvoyer non (N est composé : sortie de la fonction)
        Fin Si 

    Fin Pour

    renvoyer oui (N est probablement premier : sortie de la fonction)

Fin fonction</pre></td></tr></table></pre>
</div><br />
Le test de primalité de Fermat est le test probabiliste le plus simple. Le <a href="https://fr.wikipedia.org/wiki/Test_de_primalit%C3%A9_de_Miller-Rabin" target="_blank">test de primalité de Miller-Rabin</a> et le <a href="https://fr.wikipedia.org/wiki/Test_de_primalit%C3%A9_de_Solovay-Strassen" target="_blank">test de primalité de Solovay-Strassen</a> sont des variantes plus sophistiquées qui détectent tous les composés.<br />
<br />
<br />
<br />
<b>IV. Implémentation en Python</b><br />
<br />
<br />
<b>IV-A. Test de primalité : méthode naïve</b><br />
<br />
La fonction naïve vérifie si <b>N</b> est divisible par l’un des entiers compris entre <b>2</b> et <b>&#8730;&#119873;</b>. Si la réponse est négative, alors <b>N</b> est premier, sinon il est composé :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">def</span> test_primalite<span class="br0">&#40;</span>N<span class="br0">&#41;</span>:
    <span style="color: #808080;"># fonction permettant de tester si N est premier en utilisant la m&eacute;thode na&iuml;ve</span>
    <span style="color: #808080;"># N : nombre entier &agrave; tester</span>
&nbsp;
    <span style="color: #808080;"># d&eacute;termination du dernier entier m &agrave; tester comme diviseur de N : m est &eacute;gal &agrave; la partie enti&egrave;re de &radic;&#119873;</span>
    m = int<span class="br0">&#40;</span>math.sqrt<span class="br0">&#40;</span>N<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
    <span style="color: #808080;"># parcours des entiers : 2 -&gt; m</span>
    <span style="color: #0000ff;">for</span> i <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span><span style="color: #cc66cc;">2</span>, m+<span style="color: #cc66cc;">1</span><span class="br0">&#41;</span>:
        <span style="color: #808080;"># Si i divise N</span>
        <span style="color: #0000ff;">if</span> N % i == <span style="color: #cc66cc;">0</span>:
            <span style="color: #808080;"># N poss&egrave;de un diviseur donc n'est pas premier</span>
            <span style="color: #808080;"># renvoie le tuple : (False, i-1) =&gt; (est_premier, nbre_iterations)</span>
            <span style="color: #0000ff;">return</span> <span class="br0">&#40;</span><span style="color: #339933;">False</span>, i-<span style="color: #cc66cc;">1</span><span class="br0">&#41;</span>
&nbsp;
    <span style="color: #808080;"># N n'a pas de diviseur autre que 1 et lui-m&ecirc;me, il est donc premier.</span>
    <span style="color: #808080;"># renvoie le tuple : (True, m-1) =&gt; (est_premier, nbre_iterations)</span>
    <span style="color: #0000ff;">return</span> <span class="br0">&#40;</span><span style="color: #339933;">True</span>, m-<span style="color: #cc66cc;">1</span><span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
Elle renvoie donc un tuple contenant le résultat du test (<b>True/False</b>) et le nombre de divisions nécessaires pour aboutir. <br />
<br />
Testons maintenant notre fonction pour un grand nombre entier <b>N</b>  :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Test de primalit&eacute; classique :<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># valeur de N</span>
N = <span style="color: #cc66cc;">99999980021</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;N = &quot;</span> + str<span class="br0">&#40;</span>N<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># Teste si le nombre entier N est premier par la m&eacute;thode na&iuml;ve.</span>
est_premier, nbre_iterations = test_primalite<span class="br0">&#40;</span>N<span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># Affiche le r&eacute;sultat</span>
<span style="color: #0000ff;">if</span> est_premier:
    <span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;R&eacute;sultat du test : {0} est premier.&quot;</span>.format<span class="br0">&#40;</span>N<span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">else</span>:
    <span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;R&eacute;sultat du test : {0} est compos&eacute;.&quot;</span>.format<span class="br0">&#40;</span>N<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;------------------------------------------&quot;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Nombre de division(s) : &quot;</span> + str<span class="br0">&#40;</span>nbre_iterations<span class="br0">&#41;</span><span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
Résultat du test :<br />
<br />
<span class="highlight"><font color="#000080">Test de primalité classique :<br />
<br />
N = 99999980021<br />
<br />
Résultat du test : 99999980021 est premier.<br />
----------------------------------------------------<br />
Nombre de division(s) : 316226</font></span><br />
<br />
<br />
On constate dans ce cas que le test de primalité classique utilise beaucoup de divisions successives avant d'aboutir à un résultat (de l'ordre de <b>&#8730;&#119873;</b> dans le pire des cas).<br />
<br />
<br />
<b>IV-B. Test de primalité de Fermat : test probabiliste</b><br />
<br />
On sait que si <b>N</b> est premier, alors il est très probable que pour <b>1 &#8804; a &lt; N</b> on ait <span class="highlight">a<sup>N-1</sup> mod N = 1</span>.<br />
<br />
On peut alors écrire la fonction en Python qui permet d'effectuer ce test :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">def</span> test_primalite_fermat<span class="br0">&#40;</span>N<span class="br0">&#41;</span>:
    <span style="color: #808080;"># fonction permettant de tester si N est premier avec un entier positif a &lt; N choisi au hasard</span>
    <span style="color: #808080;"># N : nombre entier &agrave; tester</span>
&nbsp;
    <span style="color: #808080;"># s&eacute;quence de nombres entiers compris entre 2 et N-1 : 2 -&gt; N-1</span>
    nombres_entiers = range<span class="br0">&#40;</span><span style="color: #cc66cc;">2</span>, N<span class="br0">&#41;</span>
&nbsp;
    <span style="color: #808080;"># choix au hasard de l'entier positif a &lt; N</span>
    a = random.choice<span class="br0">&#40;</span>nombres_entiers<span class="br0">&#41;</span>
&nbsp;
    <span style="color: #808080;"># Si a^(N-1) mod N = 1 : a^(N-1) est congru &agrave; 1 modulo N</span>
    <span style="color: #0000ff;">if</span> pow<span class="br0">&#40;</span>a, N-<span style="color: #cc66cc;">1</span>, N<span class="br0">&#41;</span> == <span style="color: #cc66cc;">1</span>:
        <span style="color: #808080;"># N est probablement premier</span>
        <span style="color: #0000ff;">return</span> <span style="color: #339933;">True</span>
&nbsp;
    <span style="color: #0000ff;">else</span>: <span style="color: #808080;"># sinon : N est compos&eacute;</span>
        <span style="color: #0000ff;">return</span> <span style="color: #339933;">False</span></pre></td></tr></table></pre>
</div><br />
En Python, l'opération <span class="highlight">pow(a, N-1, N)</span> permet donc de réaliser l'exponentiation modulaire <span class="highlight">a<sup>N-1</sup> mod N</span>.<br />
<br />
On souhaite maintenant itérer le test plusieurs fois pour avoir un résultat plus fiable dans le cas où il est toujours positif.<br />
<br />
On peut alors écrire notre fonction permettant de tester si un nombre entier est premier avec un paramètre de fiabilité <b>k</b> passé en argument :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">def</span> test_primalite_fermat_iter<span class="br0">&#40;</span>N, k, n=<span style="color: #339933;">None</span><span class="br0">&#41;</span>:
    <span style="color: #808080;"># fonction permettant de tester si N est premier en it&eacute;rant au plus k fois le test de Fermat</span>
    <span style="color: #808080;"># N : nombre entier &agrave; tester</span>
    <span style="color: #808080;"># k : nombre maxi. d'it&eacute;rations ou d'entiers positifs a1, ... ak &lt; N choisis au hasard</span>
    <span style="color: #808080;"># n : valeur maxi de la s&eacute;quence de nombre entiers inf&eacute;rieurs &agrave; N : 2 -&gt; n, si n est omis ou si n &ge; N, alors n = N-1</span>
&nbsp;
    <span style="color: #808080;"># si l'argument n est omis ou si n &ge; N</span>
    <span style="color: #0000ff;">if</span> <span class="br0">&#40;</span><span style="color: #0000ff;">not</span> n<span class="br0">&#41;</span> <span style="color: #0000ff;">or</span> <span class="br0">&#40;</span>n &gt;= N<span class="br0">&#41;</span> : n = N-<span style="color: #cc66cc;">1</span>
&nbsp;
    <span style="color: #808080;"># s&eacute;quence de nombres entiers compris entre 2 et n : 2 -&gt; n, avec n &lt; N</span>
    nombres_entiers = range<span class="br0">&#40;</span><span style="color: #cc66cc;">2</span>, n+<span style="color: #cc66cc;">1</span><span class="br0">&#41;</span>
&nbsp;
    <span style="color: #808080;"># on it&egrave;re k fois le test de Fermat : 0 -&gt; k-1</span>
    <span style="color: #0000ff;">for</span> i <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span>k<span class="br0">&#41;</span>:
&nbsp;
        <span style="color: #808080;"># choix de l'entier positif ai &lt; N au hasard</span>
        ai = random.choice<span class="br0">&#40;</span>nombres_entiers<span class="br0">&#41;</span>
&nbsp;
        <span style="color: #808080;"># Si ai^(N-1) mod N &ne; 1 : ai^(N-1) n'est pas congru &agrave; 1 modulo N</span>
        <span style="color: #808080;">#if not test_primalite_fermat(N):</span>
        <span style="color: #0000ff;">if</span> pow<span class="br0">&#40;</span>ai, N-<span style="color: #cc66cc;">1</span>, N<span class="br0">&#41;</span> != <span style="color: #cc66cc;">1</span>:
            <span style="color: #808080;"># N n'est pas premier :</span>
            <span style="color: #808080;"># renvoie le tuple : (False, i+1) =&gt; (est_premier, nbre_iterations)</span>
            <span style="color: #0000ff;">return</span> <span class="br0">&#40;</span><span style="color: #339933;">False</span>, i+<span style="color: #cc66cc;">1</span><span class="br0">&#41;</span>
&nbsp;
    <span style="color: #808080;"># N est probablement premier</span>
    <span style="color: #808080;"># renvoie le tuple : (True, k) =&gt; (est_premier, nbre_iterations)</span>
    <span style="color: #0000ff;">return</span> <span class="br0">&#40;</span><span style="color: #339933;">True</span>, k<span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
Elle renvoie donc un tuple contenant le résultat du test (<b>True/False</b>) et le nombre d'itérations nécessaires pour aboutir. <br />
<br />
L'argument <b>n</b> permet de borner la séquence de nombre entiers sur lesquels on effectue le tirage : <b>2, 3, ..., n &lt; N</b>. On peut ainsi économiser de la mémoire et augmenter la rapidité d'exécution de la fonction en diminuant le nombre de choix possibles lors de chaque tirage.<br />
<br />
Testons la maintenant avec notre grand nombre entier :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Test de primalit&eacute; de Fermat :<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># valeur de N</span>
N = <span style="color: #cc66cc;">99999980021</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;N = &quot;</span> + str<span class="br0">&#40;</span>N<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># param&egrave;tre de fiabilit&eacute; k : nombres d'entiers positifs a1, ..., ak &lt; N choisis au hasard </span>
k = <span style="color: #cc66cc;">20</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;N = &quot;</span> + str<span class="br0">&#40;</span>N<span class="br0">&#41;</span><span class="br0">&#41;</span> 
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;k = &quot;</span> + str<span class="br0">&#40;</span>k<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># test de primalit&eacute; de Fermat pour un nombre entier N et au plus k it&eacute;rations</span>
est_premier, nbre_iterations = test_primalite_fermat_iter<span class="br0">&#40;</span>N, k, n=<span style="color: #cc66cc;">1000</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># Affiche le r&eacute;sultat</span>
<span style="color: #0000ff;">if</span> est_premier: <span style="color: #808080;"># si N est premier</span>
    <span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;R&eacute;sultat du test : {0} est probablement premier.&quot;</span>.format<span class="br0">&#40;</span>N<span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">else</span>: <span style="color: #808080;"># sinon</span>
    <span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;R&eacute;sultat du test : {0} est compos&eacute;.&quot;</span>.format<span class="br0">&#40;</span>N<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;------------------------------------------------------------------------------------------&quot;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Nombre de tirage(s) : &quot;</span> + str<span class="br0">&#40;</span>nbre_iterations<span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Nombre d'exponentiation(s) modulaire(s) : &quot;</span> + str<span class="br0">&#40;</span>nbre_iterations<span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">if</span> est_premier:
    <span style="color: #808080;"># risque d'erreur maxi si ce n'est pas un nombre de Carmichael : t = 1/(2^k)</span>
    t = pow<span class="br0">&#40;</span><span style="color: #cc66cc;">2</span>,-k<span class="br0">&#41;</span>
    <span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Risque d'erreur si N n'est pas un nombre de Carmichael inf&eacute;rieur &agrave; : &quot;</span> + str<span class="br0">&#40;</span>t<span class="br0">&#41;</span><span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
Résultat du test :<br />
<br />
<span class="highlight"><font color="#000080">Test de primalité de Fermat :<br />
<br />
N = 99999980021<br />
k = 20<br />
<br />
Résultat du test : 99999980021 est probablement premier.<br />
---------------------------------------------------------------------------------------------------------<br />
Nombre de tirage(s) : 20<br />
Nombre d'exponentiation(s) modulaire(s) : 20<br />
Risque d'erreur si N n'est pas un nombre de Carmichael inférieur à : 9.5367431640625e-07</font></span><br />
<br />
<br />
On constate que le test de Fermat nécessite beaucoup moins d'opérations que le test classique pour ce grand nombre premier (<b>k</b> tirages et <b>k</b> exponentiations modulaires dans le pire des cas, c'est à dire si <b>N</b> est premier, contre environ <b>&#8730;&#119873;</b> divisions successives pour la version naïve). Comme mentionné précédemment, il devrait donc être en moyenne plus rapide à l'exécution pour de grands nombres entiers.<br />
<br />
<br />
<b>IV-C. Comparaison des temps d'exécution des deux fonctions</b><br />
<br />
Pour vérifier notre hypothèse, on souhaite maintenant mesurer le temps mis par chacune des fonctions pour effectuer une série de tests de primalité sur de grands nombres entiers :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Mesure du temps d'ex&eacute;cution des deux fonctions de test sur une s&eacute;rie de 20 000 nombres entiers ..<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># initialisation des compteurs de tests positifs</span>
cpt1 = <span style="color: #cc66cc;">0</span>; cpt2 = <span style="color: #cc66cc;">0</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Version n&deg;1 - Test de primalit&eacute; classique :<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># heure Unix de d&eacute;but (exprim&eacute;e en secondes)</span>
start = time.time<span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># parcours des 20 0000 nombres entiers : 99999980000 -&gt; 99999999999</span>
<span style="color: #0000ff;">for</span> N <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span><span style="color: #cc66cc;">99999980000</span>, <span style="color: #cc66cc;">100000000000</span><span class="br0">&#41;</span>:
&nbsp;
    <span style="color: #808080;"># test classique pour N</span>
    est_premier, nbre_iterations = test_primalite<span class="br0">&#40;</span>N<span class="br0">&#41;</span>
&nbsp;
    <span style="color: #0000ff;">if</span> est_premier: <span style="color: #808080;"># si le test est positif</span>
        cpt1+=<span style="color: #cc66cc;">1</span> <span style="color: #808080;"># incr&eacute;mentation du compteur</span>
&nbsp;
<span style="color: #808080;"># heure Unix de fin (exprim&eacute;e en secondes)</span>
end = time.time<span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># Affiche la dur&eacute;e d'ex&eacute;cution.</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span>f<span style="color: #FF0000;">&quot;Dur&eacute;e d'ex&eacute;cution : {end - start} sec.<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Version n&deg;2 - Test de primalit&eacute; de Fermat<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># heure Unix de d&eacute;but (exprim&eacute;e en secondes)</span>
start = time.time<span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># parcours des 20 0000 nombres entiers : 99999980000 -&gt; 99999999999</span>
<span style="color: #0000ff;">for</span> N <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span><span style="color: #cc66cc;">99999980000</span>, <span style="color: #cc66cc;">100000000000</span><span class="br0">&#41;</span>:
&nbsp;
    <span style="color: #808080;"># test de primalit&eacute; de Fermat pour N et k</span>
    est_premier, nbre_iterations = test_primalite_fermat_iter<span class="br0">&#40;</span>N, k=<span style="color: #cc66cc;">10</span>, n=<span style="color: #cc66cc;">1000</span><span class="br0">&#41;</span>
&nbsp;
    <span style="color: #0000ff;">if</span> est_premier: <span style="color: #808080;"># si le test est positif</span>
        cpt2+=<span style="color: #cc66cc;">1</span> <span style="color: #808080;"># incr&eacute;mentation du compteur</span>
&nbsp;
<span style="color: #808080;"># heure Unix de fin (exprim&eacute;e en secondes)</span>
end = time.time<span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># Affiche la dur&eacute;e d'ex&eacute;cution.</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span>f<span style="color: #FF0000;">&quot;Dur&eacute;e d'ex&eacute;cution : {end - start} sec.&quot;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Taux d'erreur : &quot;</span> + str<span class="br0">&#40;</span><span class="br0">&#40;</span>cpt2-cpt1<span class="br0">&#41;</span>/<span style="color: #cc66cc;">20000</span><span class="br0">&#41;</span><span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
<br />
Résultat :<br />
<br />
<span class="highlight"><font color="#000080">Mesure du temps d'exécution des deux fonctions de test sur une série de 20 000 nombres entiers ..<br />
<br />
Version n°1 - Test de primalité classique :<br />
<br />
Durée d'exécution : 88.61510872840881 sec.<br />
<br />
Version n°2 - Test de primalité de Fermat :<br />
<br />
Durée d'exécution : 0.6873371601104736 sec.<br />
Taux d'erreur : 0.0</font></span><br />
<br />
On constate que le test de Fermat est environ <b>130</b> fois plus rapide que le test classique sur cette série de grands nombres.<br />
<br />
Ce type d'algorithme est d'ailleurs très utilisé en cryptologie, domaine dans lequel on a souvent besoin de générer rapidement un grand nombre premier en acceptant un taux d'erreur infime.<br />
<br />
<br />
<b>IV-D. Module complet</b><br />
<br />
On donne pour finir le code complet du module contenant les fonctions de test de primalité :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="40"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br />50<br />51<br />52<br />53<br />54<br />55<br />56<br />57<br />58<br />59<br />60<br />61<br />62<br />63<br />64<br />65<br />66<br />67<br />68<br />69<br />70<br />71<br />72<br />73<br />74<br />75<br />76<br />77<br />78<br />79<br />80<br />81<br />82<br />83<br />84<br />85<br />86<br />87<br />88<br />89<br />90<br />91<br />92<br />93<br />94<br />95<br />96<br />97<br />98<br />99<br />100<br />101<br />102<br />103<br />104<br />105<br />106<br />107<br />108<br />109<br />110<br />111<br />112<br />113<br />114<br />115<br />116<br />117<br />118<br />119<br />120<br />121<br />122<br />123<br />124<br />125<br />126<br />127<br />128<br />129<br />130<br />131<br />132<br />133<br />134<br />135<br />136<br />137<br />138<br />139<br />140<br />141<br />142<br />143<br />144<br />145<br />146<br />147<br />148<br />149<br />150<br />151<br />152<br />153<br />154<br />155<br />156<br />157<br />158<br />159<br />160<br />161<br />162<br />163<br />164<br />165<br />166<br />167<br />168<br />169<br />170<br />171<br />172<br />173<br />174<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">import</span> math
<span style="color: #0000ff;">import</span> random
<span style="color: #0000ff;">import</span> time
&nbsp;
<span style="color: #0000ff;">def</span> test_primalite<span class="br0">&#40;</span>N<span class="br0">&#41;</span>:
    <span style="color: #808080;"># fonction permettant de tester si N est premier en utilisant la m&eacute;thode na&iuml;ve</span>
    <span style="color: #808080;"># N : nombre entier &agrave; tester</span>
&nbsp;
    <span style="color: #808080;"># d&eacute;termination du dernier entier m &agrave; tester comme diviseur de N : m est &eacute;gal &agrave; la partie enti&egrave;re de &radic;&#119873;</span>
    m = int<span class="br0">&#40;</span>math.sqrt<span class="br0">&#40;</span>N<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
    <span style="color: #808080;"># parcours des entiers : 2 -&gt; m</span>
    <span style="color: #0000ff;">for</span> i <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span><span style="color: #cc66cc;">2</span>, m+<span style="color: #cc66cc;">1</span><span class="br0">&#41;</span>:
        <span style="color: #808080;"># Si i divise N</span>
        <span style="color: #0000ff;">if</span> N % i == <span style="color: #cc66cc;">0</span>:
            <span style="color: #808080;"># N poss&egrave;de un diviseur donc n'est pas premier</span>
            <span style="color: #808080;"># renvoie le tuple : (False, i-1) =&gt; (est_premier, nbre_iterations)</span>
            <span style="color: #0000ff;">return</span> <span class="br0">&#40;</span><span style="color: #339933;">False</span>, i-<span style="color: #cc66cc;">1</span><span class="br0">&#41;</span>
&nbsp;
    <span style="color: #808080;"># N n'a pas de diviseur autre que 1 et lui-m&ecirc;me, il est donc premier.</span>
    <span style="color: #808080;"># renvoie le tuple : (True, m-1) =&gt; (est_premier, nbre_iterations)</span>
    <span style="color: #0000ff;">return</span> <span class="br0">&#40;</span><span style="color: #339933;">True</span>, m-<span style="color: #cc66cc;">1</span><span class="br0">&#41;</span>
&nbsp;
&nbsp;
<span style="color: #0000ff;">def</span> test_primalite_fermat<span class="br0">&#40;</span>N<span class="br0">&#41;</span>:
    <span style="color: #808080;"># fonction permettant de tester si N est premier avec un entier positif a &lt; N choisi au hasard</span>
    <span style="color: #808080;"># N : nombre entier &agrave; tester</span>
&nbsp;
    <span style="color: #808080;"># s&eacute;quence de nombres entiers compris entre 2 et N-1 : 2 -&gt; N-1</span>
    nombres_entiers = range<span class="br0">&#40;</span><span style="color: #cc66cc;">2</span>, N<span class="br0">&#41;</span>
&nbsp;
    <span style="color: #808080;"># choix de l'entier positif a &lt; N au hasard</span>
    a = random.choice<span class="br0">&#40;</span>nombres_entiers<span class="br0">&#41;</span>
&nbsp;
    <span style="color: #808080;"># Si a^(N-1) mod N = 1 : a^(N-1) est congru &agrave; 1 modulo N</span>
    <span style="color: #0000ff;">if</span> pow<span class="br0">&#40;</span>a, N-<span style="color: #cc66cc;">1</span>, N<span class="br0">&#41;</span> == <span style="color: #cc66cc;">1</span>:
        <span style="color: #808080;"># N est probablement premier</span>
        <span style="color: #0000ff;">return</span> <span style="color: #339933;">True</span>
&nbsp;
    <span style="color: #0000ff;">else</span>: <span style="color: #808080;"># sinon : N est compos&eacute;</span>
        <span style="color: #0000ff;">return</span> <span style="color: #339933;">False</span>
&nbsp;
&nbsp;
<span style="color: #0000ff;">def</span> test_primalite_fermat_iter<span class="br0">&#40;</span>N, k, n=<span style="color: #339933;">None</span><span class="br0">&#41;</span>:
    <span style="color: #808080;"># fonction permettant de tester si N est premier en it&eacute;rant au plus k fois le test de Fermat</span>
    <span style="color: #808080;"># N : nombre entier &agrave; tester</span>
    <span style="color: #808080;"># k : nombre maxi. d'it&eacute;rations ou d'entiers positifs a1, ... ak &lt; N choisis au hasard</span>
    <span style="color: #808080;"># n : valeur maxi de la s&eacute;quence de nombre entiers inf&eacute;rieurs &agrave; N : 2 -&gt; n, si n est omis ou si n &ge; N, alors n = N-1</span>
&nbsp;
    <span style="color: #808080;"># si l'argument n est omis ou si n &ge; N</span>
    <span style="color: #0000ff;">if</span> <span class="br0">&#40;</span><span style="color: #0000ff;">not</span> n<span class="br0">&#41;</span> <span style="color: #0000ff;">or</span> <span class="br0">&#40;</span>n &gt;= N<span class="br0">&#41;</span> : n = N-<span style="color: #cc66cc;">1</span>
&nbsp;
    <span style="color: #808080;"># s&eacute;quence de nombres entiers compris entre 2 et n : 2 -&gt; n, avec n &lt; N</span>
    nombres_entiers = range<span class="br0">&#40;</span><span style="color: #cc66cc;">2</span>, n+<span style="color: #cc66cc;">1</span><span class="br0">&#41;</span>
&nbsp;
    <span style="color: #808080;"># on it&egrave;re k fois le test de Fermat : 0 -&gt; k-1</span>
    <span style="color: #0000ff;">for</span> i <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span>k<span class="br0">&#41;</span>:
&nbsp;
        <span style="color: #808080;"># choix de l'entier positif ai &lt; N au hasard</span>
        ai = random.choice<span class="br0">&#40;</span>nombres_entiers<span class="br0">&#41;</span>
&nbsp;
        <span style="color: #808080;"># Si ai^(N-1) mod N &ne; 1 : ai^(N-1) n'est pas congru &agrave; 1 modulo N</span>
        <span style="color: #808080;">#if not test_primalite_fermat(N):</span>
        <span style="color: #0000ff;">if</span> pow<span class="br0">&#40;</span>ai, N-<span style="color: #cc66cc;">1</span>, N<span class="br0">&#41;</span> != <span style="color: #cc66cc;">1</span>:
            <span style="color: #808080;"># N n'est pas premier :</span>
            <span style="color: #808080;"># renvoie le tuple : (False, i+1) =&gt; (est_premier, nbre_iterations)</span>
            <span style="color: #0000ff;">return</span> <span class="br0">&#40;</span><span style="color: #339933;">False</span>, i+<span style="color: #cc66cc;">1</span><span class="br0">&#41;</span>
&nbsp;
    <span style="color: #808080;"># N est probablement premier</span>
    <span style="color: #808080;"># renvoie le tuple : (True, k) =&gt; (est_premier, nbre_iterations)</span>
    <span style="color: #0000ff;">return</span> <span class="br0">&#40;</span><span style="color: #339933;">True</span>, k<span class="br0">&#41;</span> 
&nbsp;
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;I. Test de primalit&eacute;..<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;I-A. Version n&deg;1 - M&eacute;thode na&iuml;ve :<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># valeur de N</span>
N = <span style="color: #cc66cc;">99999980021</span> <span style="color: #808080;"># 99999980051, 99999980053, 99999980057, 99999980089, 99999980099, 99999980123, 99999980147, 99999980159, 99999980167</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;N = &quot;</span> + str<span class="br0">&#40;</span>N<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># Teste si le nombre entier N est premier par la m&eacute;thode na&iuml;ve.</span>
est_premier, nbre_iterations = test_primalite<span class="br0">&#40;</span>N<span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># Affiche le r&eacute;sultat</span>
<span style="color: #0000ff;">if</span> est_premier:
    <span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;R&eacute;sultat du test : {0} est premier.&quot;</span>.format<span class="br0">&#40;</span>N<span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">else</span>:
    <span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;R&eacute;sultat du test : {0} est compos&eacute;.&quot;</span>.format<span class="br0">&#40;</span>N<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;--------------------------------------------&quot;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Nombre de division(s) : &quot;</span> + str<span class="br0">&#40;</span>nbre_iterations<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;I-B. Version n&deg;2 - Test probabiliste de Fermat :<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># param&egrave;tre de fiabilit&eacute; k : nombres d'entiers positifs a1, ..., ak &lt; N choisis au hasard</span>
k = <span style="color: #cc66cc;">20</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;N = &quot;</span> + str<span class="br0">&#40;</span>N<span class="br0">&#41;</span><span class="br0">&#41;</span> 
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;k = &quot;</span> + str<span class="br0">&#40;</span>k<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># test de primalit&eacute; de Fermat pour un nombre entier N et au plus k it&eacute;rations</span>
est_premier, nbre_iterations = test_primalite_fermat_iter<span class="br0">&#40;</span>N, k, n=<span style="color: #cc66cc;">1000</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># Affiche le r&eacute;sultat</span>
<span style="color: #0000ff;">if</span> est_premier: <span style="color: #808080;"># si N est premier</span>
    <span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;R&eacute;sultat du test : {0} est probablement premier.&quot;</span>.format<span class="br0">&#40;</span>N<span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">else</span>: <span style="color: #808080;"># sinon</span>
    <span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;R&eacute;sultat du test : {0} est compos&eacute;.&quot;</span>.format<span class="br0">&#40;</span>N<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;------------------------------------------------------------------------------------------&quot;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Nombre de tirage(s) : &quot;</span> + str<span class="br0">&#40;</span>nbre_iterations<span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Nombre d'exponentiation(s) modulaire(s) : &quot;</span> + str<span class="br0">&#40;</span>nbre_iterations<span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">if</span> est_premier:
    <span style="color: #808080;"># risque d'erreur maxi si ce n'est pas un nombre de Carmichael : t = 1/(2^k)</span>
    t = pow<span class="br0">&#40;</span><span style="color: #cc66cc;">2</span>,-k<span class="br0">&#41;</span>
    <span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Risque d'erreur si N n'est pas un nombre de Carmichael inf&eacute;rieur &agrave; : &quot;</span> + str<span class="br0">&#40;</span>t<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>; <span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;II. Mesure du temps d'ex&eacute;cution des deux fonctions de test sur une s&eacute;rie de 20 000 nombres entiers ..<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># initialisation des compteurs de tests positifs</span>
cpt1 = <span style="color: #cc66cc;">0</span>; cpt2 = <span style="color: #cc66cc;">0</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Version n&deg;1 - Test de primalit&eacute; classique :<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># heure Unix de d&eacute;but (exprim&eacute;e en secondes)</span>
start = time.time<span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># parcours des 20 0000 nombres entiers : 99999980000 -&gt; 99999999999</span>
<span style="color: #0000ff;">for</span> N <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span><span style="color: #cc66cc;">99999980000</span>, <span style="color: #cc66cc;">100000000000</span><span class="br0">&#41;</span>:
&nbsp;
    <span style="color: #808080;"># test classique pour N</span>
    est_premier, nbre_iterations = test_primalite<span class="br0">&#40;</span>N<span class="br0">&#41;</span>
&nbsp;
    <span style="color: #0000ff;">if</span> est_premier: <span style="color: #808080;"># si le test est positif</span>
        cpt1+=<span style="color: #cc66cc;">1</span> <span style="color: #808080;"># incr&eacute;mentation du compteur</span>
&nbsp;
<span style="color: #808080;"># heure Unix de fin (exprim&eacute;e en secondes)</span>
end = time.time<span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># Affiche la dur&eacute;e d'ex&eacute;cution.</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span>f<span style="color: #FF0000;">&quot;Dur&eacute;e d'ex&eacute;cution : {end - start} sec.<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Version n&deg;2 - Test de primalit&eacute; de Fermat :<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># heure Unix de d&eacute;but (exprim&eacute;e en secondes)</span>
start = time.time<span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># parcours des 20 0000 nombres entiers : 99999980000 -&gt; 99999999999</span>
<span style="color: #0000ff;">for</span> N <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span><span style="color: #cc66cc;">99999980000</span>, <span style="color: #cc66cc;">100000000000</span><span class="br0">&#41;</span>:
&nbsp;
    <span style="color: #808080;"># test de primalit&eacute; de Fermat pour N et k</span>
    est_premier, nbre_iterations = test_primalite_fermat_iter<span class="br0">&#40;</span>N, k=<span style="color: #cc66cc;">10</span>, n=<span style="color: #cc66cc;">1000</span><span class="br0">&#41;</span>
&nbsp;
    <span style="color: #0000ff;">if</span> est_premier: <span style="color: #808080;"># si le test est positif</span>
        cpt2+=<span style="color: #cc66cc;">1</span> <span style="color: #808080;"># incr&eacute;mentation du compteur</span>
&nbsp;
<span style="color: #808080;"># heure Unix de fin (exprim&eacute;e en secondes)</span>
end = time.time<span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># Affiche la dur&eacute;e d'ex&eacute;cution.</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span>f<span style="color: #FF0000;">&quot;Dur&eacute;e d'ex&eacute;cution : {end - start} sec.&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Taux d'erreur : &quot;</span> + str<span class="br0">&#40;</span><span class="br0">&#40;</span>cpt2-cpt1<span class="br0">&#41;</span>/<span style="color: #cc66cc;">20000</span><span class="br0">&#41;</span><span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
<br />
<b>V. Conclusion</b><br />
<br />
Après avoir défini ce qu'est le test de primalité de Fermat, on a pu décrire cet algorithme, puis l'implémenter en Python.<br />
<br />
Enfin, on a pu vérifier avec nos fonctions en Python que le test de Fermat est en moyenne beaucoup plus rapide à l'exécution que le test classique sur une série de grands nombres entiers.<br />
<br />
<br />
<b>Sources :</b><br />
<br />
<a href="https://fr.wikipedia.org/wiki/Nombre_premier" target="_blank">https://fr.wikipedia.org/wiki/Nombre_premier</a><br />
<a href="https://fr.wikipedia.org/wiki/Algorithme_probabiliste" target="_blank">https://fr.wikipedia.org/wiki/Algorithme_probabiliste</a><br />
<a href="https://fr.wikipedia.org/wiki/Algorithme_de_Monte-Carlo" target="_blank">https://fr.wikipedia.org/wiki/Algorithme_de_Monte-Carlo</a><br />
<a href="https://fr.wikipedia.org/wiki/Test_de_primalit%C3%A9" target="_blank">https://fr.wikipedia.org/wiki/Test_de_primalit%C3%A9</a><br />
<a href="https://fr.wikipedia.org/wiki/Test_de_primalit%C3%A9_de_Fermat" target="_blank">https://fr.wikipedia.org/wiki/Test_d...3%A9_de_Fermat</a><br />
<a href="https://fr.wikipedia.org/wiki/Test_de_primalit%C3%A9_de_Miller-Rabin" target="_blank">https://fr.wikipedia.org/wiki/Test_d...e_Miller-Rabin</a><br />
<a href="https://fr.wikipedia.org/wiki/Exponentiation_modulaire" target="_blank">https://fr.wikipedia.org/wiki/Exponentiation_modulaire</a></font></blockquote>

]]></content:encoded>
			<dc:creator>User</dc:creator>
			<guid isPermaLink="true">https://www.developpez.net/forums/blogs/44027-user/b10604/algorithmes-probabilistes-nombres-premiers-test-primalite-fermat/</guid>
		</item>
		<item>
			<title>Analyse combinatoire et Python : générer des arrangements par récursivité</title>
			<link>https://www.developpez.net/forums/blogs/44027-user/b10600/analyse-combinatoire-python-generer-arrangements-recursivite/</link>
			<pubDate>Wed, 17 Apr 2024 08:25:20 GMT</pubDate>
			<description>*I. Introduction* 
 
Après...</description>
			<content:encoded><![CDATA[<blockquote class="blogcontent restore"><font size="3"><b>I. Introduction</b><br />
<br />
Après les <a href="https://fr.wikipedia.org/wiki/Combinaison_sans_r%C3%A9p%C3%A9tition" target="_blank">combinaisons</a>, on s'intéresse maintenant aux <a href="https://fr.wikipedia.org/wiki/Arrangement" target="_blank">arrangements</a> :<br />
<br />
L'objectif sera cette fois de créer une fonction récursive en Python qui pourra générer la liste des arrangements de <b>k</b> éléments pris dans un ensemble à <b>n</b> éléments.<br />
<br />
On va ensuite montrer comment transformer ce code en une <a href="https://gayerie.dev/docs/python/python3/iterateur_generateur.html#les-fonctions-generatrices-avec-yield" target="_blank">fonction génératrice</a> qui va nous permettre d'obtenir les arrangements sans avoir besoin de les stocker dans une liste.<br />
<br />
<br />
<br />
<b>II. Arrangements</b><br />
<br />
D'après Wikipedia, en analyse combinatoire, le nombre d'arrangements, défini pour tout entier naturel <b>n</b> et tout entier naturel <b>k</b> inférieur ou égal à <b>n</b>, est le nombre de parties ordonnées de <b>k</b> éléments dans un ensemble de <b>n</b> éléments.<br />
<br />
Lorsque l'on choisit <b>k</b> objets parmi <b>n</b> objets et que l’ordre dans lequel les objets sont sélectionnés revêt une importance, on peut les représenter par un k-uplet d'éléments distincts et on en constitue une liste ordonnée sans répétition possible, c'est-à-dire dans laquelle l'ordre des éléments est pris en compte (si l'on permute deux éléments de la liste, on a une liste différente, et un élément ne peut être présent qu'une seule fois). Une telle liste ordonnée est un arrangement. <br />
<br />
Par exemple, au tiercé, il faut deviner l'ordre d'arrivée des <b>3</b> premiers chevaux parmi <b>n</b> au départ. Il y a alors autant de tiercés possibles à l'arrivée que d'arrangements de <b>k=3</b> éléments pris parmi <b>n</b>. <br />
<br />
Autre exemple, dans une assemblée de <b>30</b> personnes on doit élire un bureau composé de <b>4</b> membres (un président, un vice-président, un secrétaire et un trésorier). Il y a alors autant de bureaux possibles que d'arrangements de <b>4</b> éléments pris parmi <b>30</b>.<br />
<br />
Le nombre d'arrangements de <b>k</b> éléments pris dans un ensemble à <b>n</b> éléments est donné par les formules :<br />
<br />
<img src="https://www.developpez.net/forums/attachments/p653274d1712923222/webmasters-developpement-web/outils/xmlrad/xmlrad-eviter-certains-refresh-aux-consequences-genantes/arrangements.png/" border="0" alt="Nom : arrangements.png
Affichages : 17151
Taille : 4,8 Ko"  style="float: CONFIG" /><br />
<br />
On peut remarquer que ce nombre croit rapidement quand <b>k</b> et <b>n</b> augmentent.<br />
<br />
<br />
<br />
<b>III. Génération des arrangements</b><br />
<br />
Prenons par exemple un ensemble à <b>n=4</b> éléments :<br />
<br />
<span class="highlight"><i>E</i> = {a, b, c, d}</span><br />
<br />
On souhaite obtenir tous les arrangements de <b>k=3</b> éléments pris dans l'ensemble <b>E</b>, c'est-à-dire générer la liste des triplets :<br />
<br />
<span class="highlight">(a, b, c), (a, b, d), ..., (d, c, b)</span>.<br />
<br />
<br />
On peut dénombrer tous les résultats possibles à l'aide d'un arbre des possibilités :<br />
<br />
<img src="https://www.developpez.net/forums/attachments/p653275d1712923261/webmasters-developpement-web/outils/xmlrad/xmlrad-eviter-certains-refresh-aux-consequences-genantes/arbre_arrangements.png/" border="0" alt="Nom : arbre_arrangements.png
Affichages : 3926
Taille : 89,6 Ko"  style="float: CONFIG" /><br />
<br />
On a <b>4</b> choix possibles (ou branches) au premier niveau, puis <b>3</b> choix possibles pour chaque nœud au second niveau, et enfin plus que <b>2</b> pour chaque nœud au dernier niveau, ce qui fait donc bien <span class="highlight">4×3×2=24</span> triplets à la fin.<br />
<br />
<br />
Cet arbre de dénombrement nous permet également de mieux visualiser le processus récursif de génération des arrangements.<br />
<br />
Si on voulait par exemple afficher tous les arrangements de <b>k</b> éléments pris dans une liste donnée, on obtiendrait ainsi le pseudo-code récursif :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code  :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br /></div></td><td valign="top"><pre style="margin: 0">Algo arrangements(elements, k, arr=()):
    Si k=0 alors
        afficher(arr)
    Sinon
        Pour i de 0 jusqu'à longueur(elements)-1
            # nouvelle liste d'éléments sans elements[i] (indice débutant à 0 : comme en Python)
	    new_elements = elements[0:i] + elements[i+1:]

            # nouveau tuple avec elements[i] en plus
	    new_arr = arr + elements[i]

            # appel récursif pour k-1
            arrangements(new_elements, k-1, new_arr) 
	Fin pour
    Fin si   
Fin Algo</pre></td></tr></table></pre>
</div>On va maintenant se baser sur cet algorithme pour écrire nos fonctions en Python.<br />
<br />
<br />
<br />
<b>IV. Implémentation en Python</b><br />
<br />
<br />
<b>IV-A. Génération des arrangements</b><br />
<br />
On présente maintenant la fonction récursive qui génère la liste contenant les arrangements de <b>k</b> éléments pris dans un ensemble à <b>n</b> éléments :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">def</span> generer_arrangements<span class="br0">&#40;</span>elements, k, arr=<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>:
    <span style="color: #808080;"># fonction permettant de g&eacute;n&eacute;rer la liste des arrangements de k &eacute;l&eacute;ments pris dans un ensemble de n &eacute;l&eacute;ments</span>
    <span style="color: #808080;"># generer_arrangements(['a','b','c'], 2) &rarr; ('a','b'), ('a','c'), ('b','a'), ('b','c'), ('c','a'), ('c','b')</span>
&nbsp;
    <span style="color: #808080;"># si k=0</span>
    <span style="color: #0000ff;">if</span> k==<span style="color: #cc66cc;">0</span>:
        <span style="color: #808080;"># On renvoie une liste contenant l'arrangement arr. </span>
        <span style="color: #0000ff;">return</span> <span class="br0">&#91;</span>arr<span class="br0">&#93;</span>
&nbsp;
    <span style="color: #0000ff;">else</span>: <span style="color: #808080;"># sinon</span>
        <span style="color: #808080;"># initialisation de la liste des arrangements</span>
        arrangements = <span class="br0">&#91;</span><span class="br0">&#93;</span>
&nbsp;
        <span style="color: #808080;"># parcours des &eacute;l&eacute;ments et de leur indice</span>
        <span style="color: #0000ff;">for</span> i,e <span style="color: #0000ff;">in</span> enumerate<span class="br0">&#40;</span>elements<span class="br0">&#41;</span>:
            <span style="color: #808080;"># appel r&eacute;cursif pour k-1 : generer_arrangements(elements[0:i] + elements[i+1:], k-1, arr + (e,))</span>
            <span style="color: #808080;"># arguments : elements[0:i] + elements[i+1:] &rarr; elements, k-1 &rarr; k, arr + (e,) &rarr; arr </span>
            arrangements += generer_arrangements<span class="br0">&#40;</span>elements<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span>:i<span class="br0">&#93;</span> + elements<span class="br0">&#91;</span>i+<span style="color: #cc66cc;">1</span>:<span class="br0">&#93;</span>, k-<span style="color: #cc66cc;">1</span>, arr + <span class="br0">&#40;</span>e,<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
        <span style="color: #808080;"># Renvoie la liste des arrangements.</span>
        <span style="color: #0000ff;">return</span> arrangements</pre></td></tr></table></pre>
</div><br />
Testons maintenant la fonction :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:168px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #808080;"># valeur de k</span>
k = <span style="color: #cc66cc;">3</span>
&nbsp;
<span style="color: #808080;"># cr&eacute;ation de la liste d'&eacute;l&eacute;ments</span>
elements = <span class="br0">&#91;</span><span style="color: #FF0000;">'a'</span>,<span style="color: #FF0000;">'b'</span>,<span style="color: #FF0000;">'c'</span>,<span style="color: #FF0000;">'d'</span><span class="br0">&#93;</span>
&nbsp;
<span style="color: #808080;"># G&eacute;n&egrave;re la liste des arrangements de k &eacute;l&eacute;ments pris dans un ensemble de n &eacute;l&eacute;ments.</span>
arrangements = generer_arrangements<span class="br0">&#40;</span>elements, k<span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># Affiche la liste des arrangements.</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span>arrangements<span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
Le code affiche :<br />
<br />
<span class="highlight"><font color="#000080">[('a', 'b', 'c'), ('a', 'b', 'd'), ('a', 'c', 'b'), ('a', 'c', 'd'), ('a', 'd', 'b'), ('a', 'd', 'c'), ('b', 'a', 'c'), ('b', 'a', 'd'), ('b', 'c', 'a'), ('b', 'c', 'd'), ('b', 'd', 'a'), ('b', 'd', 'c'), ('c', 'a', 'b'), ('c', 'a', 'd'), ('c', 'b', 'a'), ('c', 'b', 'd'), ('c', 'd', 'a'), ('c', 'd', 'b'), ('d', 'a', 'b'), ('d', 'a', 'c'), ('d', 'b', 'a'), ('d', 'b', 'c'), ('d', 'c', 'a'), ('d', 'c', 'b')]<br />
</font></span><br />
<br />
<br />
<b>IV-B. Fonction génératrice avec yield et yield from</b><br />
<br />
Comme on l'a vu précédemment, le nombre d'arrangements croît très rapidement quand les paramètres <b>k</b> et <b>n</b> augmentent, ce qui risque d'entrainer des problèmes de mémoire insuffisante (MemoryError, ...).<br />
<br />
On peut dans ce cas utiliser à la place une <a href="https://gayerie.dev/docs/python/python3/iterateur_generateur.html#les-fonctions-generatrices-avec-yield" target="_blank">fonction génératrice</a> qui va créer à la demande l'élément suivant de la séquence sans avoir besoin de le stocker dans une liste, permettant ainsi d’économiser de la mémoire.<br />
<br />
Pour cela, Python dispose des instructions <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">yield</span> et <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">yield from</span> qui permettent de transformer la fonction récursive précédente en générateur :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">def</span> generateur_arrangements<span class="br0">&#40;</span>elements, k, arr=<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>:
    <span style="color: #808080;"># fonction permettant de g&eacute;n&eacute;rer tous les arrangements de k &eacute;l&eacute;ments pris dans un ensemble de n &eacute;l&eacute;ments</span>
    <span style="color: #808080;"># generateur_arrangements(['a','b','c'], 2) &rarr; ('a','b'), ('a','c'), ('b','a'), ('b','c'), ('c','a'), ('c','b')</span>
&nbsp;
    <span style="color: #808080;"># si k=0 </span>
    <span style="color: #0000ff;">if</span> k==<span style="color: #cc66cc;">0</span>:
        <span style="color: #808080;"># On g&eacute;n&egrave;re l'arrangement arr. </span>
        <span style="color: #0000ff;">yield</span> arr
&nbsp;
    <span style="color: #0000ff;">else</span>: <span style="color: #808080;"># sinon</span>
        <span style="color: #808080;"># parcours des &eacute;l&eacute;ments et de leur indice</span>
        <span style="color: #0000ff;">for</span> i,e <span style="color: #0000ff;">in</span> enumerate<span class="br0">&#40;</span>elements<span class="br0">&#41;</span>:
            <span style="color: #808080;"># appel r&eacute;cursif pour k-1 : generer_arrangements(elements[0:i] + elements[i+1:], k-1, arr + (e,)) : yield from ..</span>
            <span style="color: #808080;"># arguments : elements[0:i] + elements[i+1:] &rarr; elements, k-1 &rarr; k, arr + (e,) &rarr; arr </span>
            <span style="color: #0000ff;">yield</span> <span style="color: #0000ff;">from</span> generateur_arrangements<span class="br0">&#40;</span>elements<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span>:i<span class="br0">&#93;</span> + elements<span class="br0">&#91;</span>i+<span style="color: #cc66cc;">1</span>:<span class="br0">&#93;</span>, k-<span style="color: #cc66cc;">1</span>, arr + <span class="br0">&#40;</span>e,<span class="br0">&#41;</span><span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
Comme on peut le constater, on utilise l'instruction <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">yield from</span> juste avant l'appel récursif et l'instruction <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">yield</span> pour générer l'arrangement.<br />
<br />
L'instruction <a href="https://docs.python.org/3/whatsnew/3.3.html#pep-380" target="_blank">yield from</a>, apparue avec la version 3.3 de Python,  autorise le générateur à déléguer une partie de ses opérations à un autre générateur.<br />
<br />
Testons maintenant notre fonction :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #808080;"># valeur de k</span>
k = <span style="color: #cc66cc;">3</span>
&nbsp;
<span style="color: #808080;"># cr&eacute;ation de la liste d'&eacute;l&eacute;ments</span>
elements = <span class="br0">&#91;</span><span style="color: #FF0000;">'a'</span>,<span style="color: #FF0000;">'b'</span>,<span style="color: #FF0000;">'c'</span>,<span style="color: #FF0000;">'d'</span><span class="br0">&#93;</span>
&nbsp;
<span style="color: #808080;"># Cr&eacute;e le g&eacute;n&eacute;rateur permettant de parcourir la liste des arrangements de k &eacute;l&eacute;ments pris dans un ensemble de n &eacute;l&eacute;ments.</span>
gen_arrangements = generateur_arrangements<span class="br0">&#40;</span>elements, k<span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Liste des arrangements :<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># parcours des arrangements un &agrave; un</span>
<span style="color: #0000ff;">for</span> arrangement <span style="color: #0000ff;">in</span> gen_arrangements:
    <span style="color: #808080;"># Affiche l'arrangement.</span>
    <span style="color: #0000ff;">print</span><span class="br0">&#40;</span>arrangement<span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
Le code affiche :<br />
<br />
<span class="highlight"><font color="#000080">Liste des arrangements :<br />
<br />
('a', 'b', 'c')<br />
('a', 'b', 'd')<br />
('a', 'c', 'b')<br />
('a', 'c', 'd')<br />
('a', 'd', 'b')<br />
('a', 'd', 'c')<br />
('b', 'a', 'c')<br />
('b', 'a', 'd')<br />
('b', 'c', 'a')<br />
('b', 'c', 'd')<br />
('b', 'd', 'a')<br />
('b', 'd', 'c')<br />
('c', 'a', 'b')<br />
('c', 'a', 'd')<br />
('c', 'b', 'a')<br />
('c', 'b', 'd')<br />
('c', 'd', 'a')<br />
('c', 'd', 'b')<br />
('d', 'a', 'b')<br />
('d', 'a', 'c')<br />
('d', 'b', 'a')<br />
('d', 'b', 'c')<br />
('d', 'c', 'a')<br />
('d', 'c', 'b')</font></span><br />
<br />
Vous pouvez d'ailleurs retrouver ce type de fonction dans la <a href="https://docs.python.org/fr/3/library/itertools.html" target="_blank">librairie itertools</a>.<br />
<br />
<br />
<b>IV-C. Application : tiercés dans l'ordre</b><br />
<br />
On a <b>4</b> chevaux au départ d'une course, numérotés de <b>1</b> à <b>4</b>, et on souhaite obtenir tous les tiercés dans l'ordre possibles :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #808080;"># valeur de k</span>
k = <span style="color: #cc66cc;">3</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;k = &quot;</span> + str<span class="br0">&#40;</span>k<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># cr&eacute;ation de la liste d'&eacute;l&eacute;ments : num&eacute;ros au d&eacute;part</span>
elements = <span class="br0">&#91;</span><span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">2</span>, <span style="color: #cc66cc;">3</span>, <span style="color: #cc66cc;">4</span><span class="br0">&#93;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;E = &quot;</span> + str<span class="br0">&#40;</span>elements<span class="br0">&#41;</span>.replace<span class="br0">&#40;</span><span style="color: #FF0000;">&quot;[&quot;</span>,<span style="color: #FF0000;">&quot;{&quot;</span><span class="br0">&#41;</span>.replace<span class="br0">&#40;</span><span style="color: #FF0000;">&quot;]&quot;</span>,<span style="color: #FF0000;">&quot;}&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># Cr&eacute;e le g&eacute;n&eacute;rateur permettant de parcourir la liste des arrangements de k &eacute;l&eacute;ments pris dans un ensemble de n &eacute;l&eacute;ments</span>
gen_arrangements = generateur_arrangements<span class="br0">&#40;</span>elements, k<span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Liste des tierc&eacute;s dans l'ordre possibles :<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># parcours les arrangements un &agrave; un : tierc&eacute;s possibles</span>
<span style="color: #0000ff;">for</span> arrangement <span style="color: #0000ff;">in</span> gen_arrangements:
    <span style="color: #808080;"># Affiche l'arrangement : tierc&eacute; possible</span>
    <span style="color: #0000ff;">print</span><span class="br0">&#40;</span>arrangement<span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
Le code affiche :<br />
<br />
<span class="highlight"><font color="#000080">k = 3<br />
E = {1, 2, 3, 4}<br />
<br />
Liste des tiercés dans l'ordre possibles :<br />
<br />
(1, 2, 3)<br />
(1, 2, 4)<br />
(1, 3, 2)<br />
(1, 3, 4)<br />
(1, 4, 2)<br />
(1, 4, 3)<br />
(2, 1, 3)<br />
(2, 1, 4)<br />
(2, 3, 1)<br />
(2, 3, 4)<br />
(2, 4, 1)<br />
(2, 4, 3)<br />
(3, 1, 2)<br />
(3, 1, 4)<br />
(3, 2, 1)<br />
(3, 2, 4)<br />
(3, 4, 1)<br />
(3, 4, 2)<br />
(4, 1, 2)<br />
(4, 1, 3)<br />
(4, 2, 1)<br />
(4, 2, 3)<br />
(4, 3, 1)<br />
(4, 3, 2)</font></span><br />
<br />
<br />
<b>IV-D. Module complet</b><br />
<br />
On donne pour finir le code complet contenant les fonctions permettant de générer ces arrangements :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="40"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br />50<br />51<br />52<br />53<br />54<br />55<br />56<br />57<br />58<br />59<br />60<br />61<br />62<br />63<br />64<br />65<br />66<br />67<br />68<br />69<br />70<br />71<br />72<br />73<br />74<br />75<br />76<br />77<br />78<br />79<br />80<br />81<br />82<br />83<br />84<br />85<br />86<br />87<br />88<br />89<br />90<br />91<br />92<br />93<br />94<br />95<br />96<br />97<br />98<br />99<br />100<br />101<br />102<br />103<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">def</span> generer_arrangements<span class="br0">&#40;</span>elements, k, arr=<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>:
    <span style="color: #808080;"># fonction permettant de g&eacute;n&eacute;rer la liste des arrangements de k &eacute;l&eacute;ments pris dans un ensemble de n &eacute;l&eacute;ments</span>
    <span style="color: #808080;"># generer_arrangements(['a','b','c'], 2) &rarr; ('a','b'), ('a','c'), ('b','a'), ('b','c'), ('c','a'), ('c','b')</span>
&nbsp;
    <span style="color: #808080;"># si k=0</span>
    <span style="color: #0000ff;">if</span> k==<span style="color: #cc66cc;">0</span>:
        <span style="color: #808080;"># On renvoie une liste contenant l'arrangement arr. </span>
        <span style="color: #0000ff;">return</span> <span class="br0">&#91;</span>arr<span class="br0">&#93;</span>
&nbsp;
    <span style="color: #0000ff;">else</span>: <span style="color: #808080;"># sinon</span>
        <span style="color: #808080;"># initialisation de la liste des arrangements</span>
        arrangements = <span class="br0">&#91;</span><span class="br0">&#93;</span>
&nbsp;
        <span style="color: #808080;"># parcours des &eacute;l&eacute;ments et de leur indice</span>
        <span style="color: #0000ff;">for</span> i,e <span style="color: #0000ff;">in</span> enumerate<span class="br0">&#40;</span>elements<span class="br0">&#41;</span>:
            <span style="color: #808080;"># appel r&eacute;cursif pour k-1 : generer_arrangements(elements[0:i] + elements[i+1:], k-1, arr + (e,))</span>
            <span style="color: #808080;"># arguments : elements[0:i] + elements[i+1:] &rarr; elements, k-1 &rarr; k, arr + (e,) &rarr; arr </span>
            arrangements += generer_arrangements<span class="br0">&#40;</span>elements<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span>:i<span class="br0">&#93;</span> + elements<span class="br0">&#91;</span>i+<span style="color: #cc66cc;">1</span>:<span class="br0">&#93;</span>, k-<span style="color: #cc66cc;">1</span>, arr + <span class="br0">&#40;</span>e,<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
        <span style="color: #808080;"># Renvoie la liste des arrangements.</span>
        <span style="color: #0000ff;">return</span> arrangements
&nbsp;
&nbsp;
<span style="color: #0000ff;">def</span> generateur_arrangements<span class="br0">&#40;</span>elements, k, arr=<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>:
    <span style="color: #808080;"># fonction permettant de g&eacute;n&eacute;rer tous les arrangements de k &eacute;l&eacute;ments pris dans un ensemble de n &eacute;l&eacute;ments</span>
    <span style="color: #808080;"># generateur_arrangements(['a','b','c'], 2) &rarr; ('a','b'), ('a','c'), ('b','a'), ('b','c'), ('c','a'), ('c','b')</span>
&nbsp;
    <span style="color: #808080;"># si k=0 </span>
    <span style="color: #0000ff;">if</span> k==<span style="color: #cc66cc;">0</span>:
        <span style="color: #808080;"># On g&eacute;n&egrave;re l'arrangement arr.</span>
        <span style="color: #0000ff;">yield</span> arr
&nbsp;
    <span style="color: #0000ff;">else</span>: <span style="color: #808080;"># sinon</span>
        <span style="color: #808080;"># parcours des &eacute;l&eacute;ments et de leur indice</span>
        <span style="color: #0000ff;">for</span> i,e <span style="color: #0000ff;">in</span> enumerate<span class="br0">&#40;</span>elements<span class="br0">&#41;</span>:
            <span style="color: #808080;"># appel r&eacute;cursif pour k-1 : generer_arrangements(elements[0:i] + elements[i+1:], k-1, arr + (e,)) : yield from ..</span>
            <span style="color: #808080;"># arguments : elements[0:i] + elements[i+1:] &rarr; elements, k-1 &rarr; k, arr + (e,) &rarr; arr  </span>
            <span style="color: #0000ff;">yield</span> <span style="color: #0000ff;">from</span> generateur_arrangements<span class="br0">&#40;</span>elements<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span>:i<span class="br0">&#93;</span> + elements<span class="br0">&#91;</span>i+<span style="color: #cc66cc;">1</span>:<span class="br0">&#93;</span>, k-<span style="color: #cc66cc;">1</span>, arr + <span class="br0">&#40;</span>e,<span class="br0">&#41;</span><span class="br0">&#41;</span>    
&nbsp;
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;G&eacute;n&eacute;ration des arrangements de k &eacute;l&eacute;ments pris dans un ensemble de n &eacute;l&eacute;ments..<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># valeur de k</span>
k = <span style="color: #cc66cc;">3</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;k = &quot;</span> + str<span class="br0">&#40;</span>k<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># cr&eacute;ation de la liste d'&eacute;l&eacute;ments</span>
elements = <span class="br0">&#91;</span><span style="color: #FF0000;">'a'</span>,<span style="color: #FF0000;">'b'</span>,<span style="color: #FF0000;">'c'</span>,<span style="color: #FF0000;">'d'</span><span class="br0">&#93;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;E = &quot;</span> + str<span class="br0">&#40;</span>elements<span class="br0">&#41;</span>.replace<span class="br0">&#40;</span><span style="color: #FF0000;">&quot;[&quot;</span>,<span style="color: #FF0000;">&quot;{&quot;</span><span class="br0">&#41;</span>.replace<span class="br0">&#40;</span><span style="color: #FF0000;">&quot;]&quot;</span>,<span style="color: #FF0000;">&quot;}&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;I. Version n&deg;1 : fonction r&eacute;cursive classique<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># G&eacute;n&egrave;re la liste des arrangements de k &eacute;l&eacute;ments pris dans un ensemble de n &eacute;l&eacute;ments.</span>
arrangements = generer_arrangements<span class="br0">&#40;</span>elements, k<span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Liste des arrangements :<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># Affiche la liste des arrangements</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span>arrangements<span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;II. Version n&deg;2 : fonction g&eacute;n&eacute;ratrice avec yield et yield from<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># Cr&eacute;e le g&eacute;n&eacute;rateur permettant de parcourir la liste des arrangements de k &eacute;l&eacute;ments pris dans un ensemble de n &eacute;l&eacute;ments.</span>
gen_arrangements = generateur_arrangements<span class="br0">&#40;</span>elements, k<span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Liste des arrangements :<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># parcours des arrangements un &agrave; un</span>
<span style="color: #0000ff;">for</span> arrangement <span style="color: #0000ff;">in</span> gen_arrangements:
    <span style="color: #808080;"># Affiche l'arrangement.</span>
    <span style="color: #0000ff;">print</span><span class="br0">&#40;</span>arrangement<span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;III. Application : tierc&eacute;s dans l'ordre<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># valeur de k</span>
k = <span style="color: #cc66cc;">3</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;k = &quot;</span> + str<span class="br0">&#40;</span>k<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># cr&eacute;ation de la liste d'&eacute;l&eacute;ments : num&eacute;ros au d&eacute;part</span>
elements = <span class="br0">&#91;</span><span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">2</span>, <span style="color: #cc66cc;">3</span>, <span style="color: #cc66cc;">4</span><span class="br0">&#93;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;E = &quot;</span> + str<span class="br0">&#40;</span>elements<span class="br0">&#41;</span>.replace<span class="br0">&#40;</span><span style="color: #FF0000;">&quot;[&quot;</span>,<span style="color: #FF0000;">&quot;{&quot;</span><span class="br0">&#41;</span>.replace<span class="br0">&#40;</span><span style="color: #FF0000;">&quot;]&quot;</span>,<span style="color: #FF0000;">&quot;}&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># Cr&eacute;e le g&eacute;n&eacute;rateur permettant de parcourir la liste des arrangements de k &eacute;l&eacute;ments pris dans un ensemble de n &eacute;l&eacute;ments</span>
gen_arrangements = generateur_arrangements<span class="br0">&#40;</span>elements, k<span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Liste des tierc&eacute;s dans l'ordre possibles :<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># parcours les arrangements un &agrave; un : tierc&eacute;s possibles</span>
<span style="color: #0000ff;">for</span> arrangement <span style="color: #0000ff;">in</span> gen_arrangements:
    <span style="color: #808080;"># Affiche l'arrangement : tierc&eacute; possible</span>
    <span style="color: #0000ff;">print</span><span class="br0">&#40;</span>arrangement<span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
<br />
<b>V. Conclusion</b><br />
<br />
On a donc d'abord montré comment obtenir à l'aide d'un arbre de dénombrement tous les arrangements de <b>3</b> éléments pris dans un ensemble à <b>4</b> éléments. Puis, on a proposé une première fonction récursive en Python permettant de générer la liste des arrangements de <b>k</b> éléments pris parmi <b>n</b>. <br />
<br />
Enfin, on a créé une fonction génératrice à partir de ce code pour éviter les problèmes de mémoire insuffisante.<br />
<br />
<br />
<b>Sources :</b><br />
<br />
<a href="https://fr.wikipedia.org/wiki/Arrangement" target="_blank">https://fr.wikipedia.org/wiki/Arrangement</a><br />
<a href="https://fr.wikipedia.org/wiki/Combinaison_sans_r%C3%A9p%C3%A9tition" target="_blank">https://fr.wikipedia.org/wiki/Combin...9p%C3%A9tition</a><br />
<a href="https://fr.wikipedia.org/wiki/Combinatoire" target="_blank">https://fr.wikipedia.org/wiki/Combinatoire</a><br />
<a href="https://fr.wikipedia.org/wiki/Pseudo-code" target="_blank">https://fr.wikipedia.org/wiki/Pseudo-code</a><br />
<a href="https://gayerie.dev/docs/python/python3/iterateur_generateur.html#les-generateurs" target="_blank">https://gayerie.dev/docs/python/pyth...es-generateurs</a><br />
<a href="https://docs.python.org/3/whatsnew/3.3.html#pep-380" target="_blank">https://docs.python.org/3/whatsnew/3.3.html#pep-380</a><br />
<a href="http://villemin.gerard.free.fr/Puzzle/HazTierc.htm" target="_blank">http://villemin.gerard.free.fr/Puzzle/HazTierc.htm</a></font></blockquote>

]]></content:encoded>
			<dc:creator>User</dc:creator>
			<guid isPermaLink="true">https://www.developpez.net/forums/blogs/44027-user/b10600/analyse-combinatoire-python-generer-arrangements-recursivite/</guid>
		</item>
		<item>
			<title>Analyse combinatoire et Python : les combinaisons avec répétition</title>
			<link>https://www.developpez.net/forums/blogs/44027-user/b10594/analyse-combinatoire-python-combinaisons-repetition/</link>
			<pubDate>Wed, 03 Apr 2024 12:27:58 GMT</pubDate>
			<description>*I. Introduction* 
 
Après...</description>
			<content:encoded><![CDATA[<blockquote class="blogcontent restore"><font size="3"><b>I. Introduction</b><br />
<br />
Après les <a href="https://fr.wikipedia.org/wiki/Combinaison_sans_r%C3%A9p%C3%A9tition" target="_blank">combinaisons sans répétition</a>, on s'intéresse maintenant aux <a href="https://fr.wikipedia.org/wiki/Combinaison_avec_r%C3%A9p%C3%A9tition" target="_blank">combinaisons avec répétition</a> :<br />
<br />
L'objectif sera cette fois de créer une fonction en Python qui pourra générer la liste des combinaisons avec répétition de <b>k</b> éléments pris dans un ensemble de <b>n</b> éléments.<br />
<br />
On va ensuite montrer comment transformer ce code en une <a href="https://gayerie.dev/docs/python/python3/iterateur_generateur.html#les-fonctions-generatrices-avec-yield" target="_blank">fonction génératrice</a> qui va nous permettre d'obtenir les combinaisons sans avoir besoin de les stocker dans une liste.<br />
<br />
<br />
<br />
<b>II. Combinaisons avec répétition</b><br />
<br />
D'après Wikipedia, en <a href="https://fr.wikipedia.org/wiki/Combinatoire" target="_blank">analyse combinatoire</a>, une <a href="https://fr.wikipedia.org/wiki/Combinaison_avec_r%C3%A9p%C3%A9tition" target="_blank">combinaison avec répétition</a> est une combinaison où donc l'ordre des éléments n'importe pas et où, contrairement à une combinaison classique (sans répétition), chaque élément de la combinaison peut apparaître plusieurs fois. <br />
<br />
Par exemple, lorsque dix dés à six faces (numérotées de <b>1</b> à <b>6</b>) sont jetés, le résultat fourni par ces dix dés, si l'ordre dans lequel sont jetés les dés n'est pas pris en compte, (par exemple un <b>2</b>, trois <b>4</b>, deux <b>5</b> et quatre <b>6</b>, sans retenir à quel dé précisément correspond chaque face) est une combinaison des différentes faces apparaissant sur chaque dé, et où chaque face peut apparaître plusieurs fois. <br />
<br />
Cette expérience peut être modélisée par une <a href="https://fr.wikipedia.org/wiki/Loi_multinomiale" target="_blank">loi multinomiale</a> dans laquelle chaque combinaison possible est associée à un coefficient multinomial.<br />
<br />
Dans un jeu de dominos, les <b>28</b> pièces représentent les combinaisons avec répétition de <b>2</b> éléments pris dans un ensemble <span class="highlight">E = {blanc, 1, 2, 3, 4 ,5, 6}</span> à <b>7</b> éléments. <br />
<br />
Le nombre de combinaisons avec répétition de <b>k</b> éléments pris dans un ensemble à <b>n</b> éléments est égal au nombre de k-combinaisons (sans répétition) de <b>n + k – 1</b> éléments :<br />
<br />
<img src="https://www.developpez.net/forums/attachments/p652691d1711620386/autres-langages/assembleur/x86-16-bits/nouveau-tutoriel-benoit-m/nombre_combinaisons.png/" border="0" alt="Nom : nombre_combinaisons.png
Affichages : 21990
Taille : 2,6 Ko"  style="float: CONFIG" /><br />
<br />
On peut remarquer avec cette formule que le nombre de combinaisons croit rapidement quand <b>k</b> et <b>n</b> augmentent.<br />
<br />
<br />
<br />
<b>III. Génération des combinaisons avec répétition</b><br />
<br />
Prenons par exemple un ensemble de <b>n=3</b> éléments :<br />
<br />
<span class="highlight"><i>E</i> = {a, b, c}</span><br />
<br />
On souhaite obtenir la liste des combinaisons de <b>k=4</b> éléments pris avec remise dans l'ensemble <b>E</b>, c'est-à-dire générer la liste des 4-combinaisons avec répétition :<br />
<br />
<span class="highlight">(a, a, a, a), (a, a, a, b), ..., (c, c, c, c)</span>.<br />
<br />
<br />
On va d'abord associer à chaque élément de cet ensemble un indice débutant à <b>0</b> comme en Python :<br />
<br />
<span class="highlight">(a, b, c) &#8594; (0, 1, 2)</span><br />
<br />
On génère ensuite les 4-uplets ou quadruplets d'indices <span class="highlight">(i<sub>0</sub>, i<sub>1</sub>, i<sub>2</sub>, i<sub>3</sub>)</span> (croissants au sens large) et leur combinaison, du premier <span class="highlight">(0, 0, 0, 0)</span> au dernier <span class="highlight">(2, 2, 2, 2)</span>, dans cet ordre :<br />
<br />
<span class="highlight">(0, 0, 0, 0) &#8594; (a, a, a, a)<br />
(0, 0, 0, 1) &#8594; (a, a, a, b)<br />
(0, 0, 0, 2) &#8594; (a, a, a, c)<br />
(0, 0, 1, 1) &#8594; (a, a, b, b)<br />
(0, 0, 1, 2) &#8594; (a, a, b, c)<br />
(0, 0, 2, 2) &#8594; (a, a, c, c)<br />
(0, 1, 1, 1) &#8594; (a, b, b, b)<br />
(0, 1, 1, 2) &#8594; (a, b, b, c)<br />
(0, 1, 2, 2) &#8594; (a, b, c, c)<br />
(0, 2, 2, 2) &#8594; (a, c, c, c)<br />
(1, 1, 1, 1) &#8594; (b, b, b, b)<br />
(1, 1, 1, 2) &#8594; (b, b, b, c)<br />
(1, 1, 2, 2) &#8594; (b, b, c, c)<br />
(1, 2, 2, 2) &#8594; (b, c, c, c)<br />
(2, 2, 2, 2) &#8594; (c, c, c, c)</span><br />
<br />
On incrémente donc à chaque fois les indices des k-uplets <span class="highlight">(i<sub>0</sub>, i<sub>1</sub>, i<sub>2</sub>, i<sub>3</sub>)</span> en commençant par la droite, un peu comme pour les chiffres des nombres entiers, mais de façon à toujours conserver un ordre croissant des indices <span class="highlight">i<sub>0</sub> &#8804; i<sub>1</sub> &#8804; i<sub>2</sub> &#8804; i<sub>3</sub> &#8804; 2</span>.<br />
<br />
Dans le même temps, on transforme chaque k-uplet d'indices croissants en une k-combinaison d'éléments de <b>E</b> en utilisant la correspondance entre indices et éléments de <b>E</b> : <span class="highlight">(0, 1, 2) &#8594; (a, b, c)</span>.<br />
<br />
<br />
<br />
<b>IV. Implémentation en Python</b><br />
<br />
<br />
<b>IV-A. Génération des combinaisons avec répétition</b><br />
<br />
On présente maintenant une fonction qui génère la liste des combinaisons avec répétition de <b>k</b> éléments pris dans un ensemble de <b>n</b> éléments :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">def</span> generer_combinaisons<span class="br0">&#40;</span>elements, k<span class="br0">&#41;</span>:
    <span style="color: #808080;"># fonction permettant de g&eacute;n&eacute;rer la liste des combinaisons avec r&eacute;p&eacute;tition de k &eacute;l&eacute;ments pris dans un ensemble de n &eacute;l&eacute;ments</span>
    <span style="color: #808080;"># generer_combinaisons(['a','b','c'], 2) &rarr; ('a','a'), ('a','b'), ('a','c'), ('b','b'), ('b','c'), ('c','c')</span>
&nbsp;
    <span style="color: #808080;"># nombre d'&eacute;l&eacute;ments de l'ensemble</span>
    n = len<span class="br0">&#40;</span>elements<span class="br0">&#41;</span>
&nbsp;
    <span style="color: #808080;"># initialisation de la liste d'indices correspondant &agrave; une k-combinaison : [0, 0, .., 0] &rarr; ('a', 'a', .., 'a')</span>
    indices = <span class="br0">&#91;</span><span style="color: #cc66cc;">0</span><span class="br0">&#93;</span> * k
&nbsp;
    <span style="color: #808080;"># On cr&eacute;e la 1re combinaison &agrave; partir de la liste d'indices. ex. : [0, 0, 0] &rarr; ('a', 'a', 'a')</span>
    k_combinaison = tuple<span class="br0">&#40;</span>elements<span class="br0">&#91;</span>i<span class="br0">&#93;</span> <span style="color: #0000ff;">for</span> i <span style="color: #0000ff;">in</span> indices<span class="br0">&#41;</span>
&nbsp;
    <span style="color: #808080;"># initialisation de la liste avec la 1re combinaison</span>
    k_combinaisons = <span class="br0">&#91;</span>k_combinaison<span class="br0">&#93;</span>
&nbsp;
    <span style="color: #808080;"># tant que vrai</span>
    <span style="color: #0000ff;">while</span> <span style="color: #339933;">True</span>:
&nbsp;
        <span style="color: #808080;"># parcours des indices de la liste</span>
        <span style="color: #0000ff;">for</span> i <span style="color: #0000ff;">in</span> reversed<span class="br0">&#40;</span>range<span class="br0">&#40;</span>k<span class="br0">&#41;</span><span class="br0">&#41;</span>:
            <span style="color: #808080;"># Si la valeur de l'indice est diff&eacute;rente de n-1.</span>
            <span style="color: #0000ff;">if</span> indices<span class="br0">&#91;</span>i<span class="br0">&#93;</span> != n - <span style="color: #cc66cc;">1</span>:
                <span style="color: #0000ff;">break</span> <span style="color: #808080;"># On sort de la boucle : indice trouv&eacute;</span>
        <span style="color: #0000ff;">else</span>: <span style="color: #808080;"># sinon</span>
            <span style="color: #0000ff;">break</span> <span style="color: #808080;"># On sort de la boucle.</span>
&nbsp;
        <span style="color: #808080;"># copie (k-i) fois la valeur (indices[i] + 1) &agrave; partir de l'indice i dans la liste </span>
        indices<span class="br0">&#91;</span>i:<span class="br0">&#93;</span> = <span class="br0">&#91;</span>indices<span class="br0">&#91;</span>i<span class="br0">&#93;</span> + <span style="color: #cc66cc;">1</span><span class="br0">&#93;</span> * <span class="br0">&#40;</span>k - i<span class="br0">&#41;</span>
&nbsp;
        <span style="color: #808080;"># On g&eacute;n&egrave;re la combinaison correspondant &agrave; la liste d'indices.</span>
        k_combinaison = tuple<span class="br0">&#40;</span>elements<span class="br0">&#91;</span>i<span class="br0">&#93;</span> <span style="color: #0000ff;">for</span> i <span style="color: #0000ff;">in</span> indices<span class="br0">&#41;</span>
&nbsp;
        <span style="color: #808080;"># ajout de la combinaison &agrave; la liste</span>
        k_combinaisons.append<span class="br0">&#40;</span>k_combinaison<span class="br0">&#41;</span>
&nbsp;
    <span style="color: #808080;"># renvoi la liste des combinaisons</span>
    <span style="color: #0000ff;">return</span> k_combinaisons</pre></td></tr></table></pre>
</div><br />
Le code est basé sur la fonction <a href="https://docs.python.org/fr/3/library/itertools.html#itertools.combinations_with_replacement" target="_blank">combinations_with_replacement</a> présentée dans la <a href="https://docs.python.org/fr/3/library/itertools.html" target="_blank">documentation du module itertools</a>.<br />
<br />
<br />
Testons maintenant la fonction :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:168px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #808080;"># valeur de k</span>
k = <span style="color: #cc66cc;">4</span>
&nbsp;
<span style="color: #808080;"># cr&eacute;ation de la liste d'&eacute;l&eacute;ments</span>
elements = <span class="br0">&#91;</span><span style="color: #FF0000;">'a'</span>,<span style="color: #FF0000;">'b'</span>,<span style="color: #FF0000;">'c'</span><span class="br0">&#93;</span>
&nbsp;
<span style="color: #808080;"># G&eacute;n&egrave;re la liste des combinaisons avec r&eacute;p&eacute;tition de k &eacute;l&eacute;ments pris dans un ensemble de n &eacute;l&eacute;ments.</span>
combinaisons = generer_combinaisons<span class="br0">&#40;</span>elements, k<span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># Affiche la liste des combinaisons.</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span>combinaisons<span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
Le code affiche :<br />
<br />
<span class="highlight"><font color="#000080">[('a', 'a', 'a', 'a'), ('a', 'a', 'a', 'b'), ('a', 'a', 'a', 'c'), ('a', 'a', 'b', 'b'), ('a', 'a', 'b', 'c'), ('a', 'a', 'c', 'c'), ('a', 'b', 'b', 'b'), ('a', 'b', 'b', 'c'), ('a', 'b', 'c', 'c'), ('a', 'c', 'c', 'c'), ('b', 'b', 'b', 'b'), ('b', 'b', 'b', 'c'), ('b', 'b', 'c', 'c'), ('b', 'c', 'c', 'c'), ('c', 'c', 'c', 'c')]</font></span><br />
<br />
<br />
<b>IV-B. Fonction génératrice avec yield</b><br />
<br />
Comme on l'a vu précédemment, le nombre de combinaisons croît très rapidement quand les paramètres <b>k</b> et <b>n</b> augmentent, ce qui risque d'entrainer des problèmes de mémoire insuffisante (MemoryError, ...).<br />
<br />
On peut dans ce cas utiliser à la place une <a href="https://gayerie.dev/docs/python/python3/iterateur_generateur.html#les-fonctions-generatrices-avec-yield" target="_blank">fonction génératrice</a> qui va créer à la demande l'élément suivant de la séquence sans avoir besoin de le stocker dans une liste, permettant ainsi d’économiser de la mémoire.<br />
<br />
Pour cela, Python dispose de l'instruction yield qui permet de transformer la fonction précédente en générateur :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">def</span> generateur_combinaisons<span class="br0">&#40;</span>elements, k<span class="br0">&#41;</span>:
    <span style="color: #808080;"># fonction permettant de g&eacute;n&eacute;rer la liste des combinaisons avec r&eacute;p&eacute;tition de k &eacute;l&eacute;ments pris dans un ensemble de n &eacute;l&eacute;ments</span>
    <span style="color: #808080;"># generateur_combinaisons(['a','b','c'], 2) &rarr; ('a','a'), ('a','b'), ('a','c'), ('b','b'), ('b','c'), ('c','c')</span>
&nbsp;
    <span style="color: #808080;"># nombre d'&eacute;l&eacute;ments de l'ensemble</span>
    n = len<span class="br0">&#40;</span>elements<span class="br0">&#41;</span>
&nbsp;
    <span style="color: #808080;"># initialisation de la liste d'indices correspondant &agrave; une k-combinaison : [0, 0, .., 0] &rarr; ('a', 'a', .., 'a')</span>
    indices = <span class="br0">&#91;</span><span style="color: #cc66cc;">0</span><span class="br0">&#93;</span> * k
&nbsp;
    <span style="color: #808080;"># On g&eacute;n&egrave;re la 1re combinaison. ex. : [0, 0, 0] &rarr; ('a', 'a', 'a')</span>
    <span style="color: #0000ff;">yield</span> tuple<span class="br0">&#40;</span>elements<span class="br0">&#91;</span>i<span class="br0">&#93;</span> <span style="color: #0000ff;">for</span> i <span style="color: #0000ff;">in</span> indices<span class="br0">&#41;</span>
&nbsp;
    <span style="color: #0000ff;">while</span> <span style="color: #339933;">True</span>:
&nbsp;
        <span style="color: #808080;"># parcours des indices de la liste indices</span>
        <span style="color: #0000ff;">for</span> i <span style="color: #0000ff;">in</span> reversed<span class="br0">&#40;</span>range<span class="br0">&#40;</span>k<span class="br0">&#41;</span><span class="br0">&#41;</span>:
            <span style="color: #808080;"># Si la valeur de l'indice est diff&eacute;rente de n-1</span>
            <span style="color: #0000ff;">if</span> indices<span class="br0">&#91;</span>i<span class="br0">&#93;</span> != n - <span style="color: #cc66cc;">1</span>:
                <span style="color: #0000ff;">break</span> <span style="color: #808080;"># On sort de la boucle : indice trouv&eacute;</span>
        <span style="color: #0000ff;">else</span>:
            <span style="color: #0000ff;">return</span>
&nbsp;
        <span style="color: #808080;"># copie (k-i) fois la valeur (indices[i] + 1) &agrave; partir de l'indice i dans la liste</span>
        indices<span class="br0">&#91;</span>i:<span class="br0">&#93;</span> = <span class="br0">&#91;</span>indices<span class="br0">&#91;</span>i<span class="br0">&#93;</span> + <span style="color: #cc66cc;">1</span><span class="br0">&#93;</span> * <span class="br0">&#40;</span>k - i<span class="br0">&#41;</span>
&nbsp;
        <span style="color: #808080;"># On g&eacute;n&egrave;re la combinaison correspondant aux indices.</span>
        <span style="color: #0000ff;">yield</span> tuple<span class="br0">&#40;</span>elements<span class="br0">&#91;</span>i<span class="br0">&#93;</span> <span style="color: #0000ff;">for</span> i <span style="color: #0000ff;">in</span> indices<span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
Vous pouvez retrouver <a href="https://docs.python.org/fr/3/library/itertools.html#itertools.combinations_with_replacement" target="_blank">cette fonction</a> dans la <a href="https://docs.python.org/fr/3/library/itertools.html" target="_blank">documentation du module itertools</a>.<br />
<br />
<br />
Testons la maintenant :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:192px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #808080;"># valeur de k</span>
k = <span style="color: #cc66cc;">4</span>
&nbsp;
<span style="color: #808080;"># cr&eacute;ation de la liste d'&eacute;l&eacute;ments</span>
elements = <span class="br0">&#91;</span><span style="color: #FF0000;">'a'</span>,<span style="color: #FF0000;">'b'</span>,<span style="color: #FF0000;">'c'</span><span class="br0">&#93;</span>
&nbsp;
<span style="color: #808080;"># Cr&eacute;e le g&eacute;n&eacute;rateur permettant de parcourir la liste des combinaisons avec r&eacute;p&eacute;tition de k &eacute;l&eacute;ments pris dans un ensemble de n &eacute;l&eacute;ments.</span>
gen_combinaisons = generateur_combinaisons<span class="br0">&#40;</span>elements, k<span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Liste des combinaisons avec r&eacute;p&eacute;titions :<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># Affiche les combinaisons une &agrave; une.</span>
<span style="color: #0000ff;">for</span> combinaison <span style="color: #0000ff;">in</span> gen_combinaisons:
    <span style="color: #0000ff;">print</span><span class="br0">&#40;</span>combinaison<span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
Le code affiche :<br />
<br />
<span class="highlight"><font color="#000080">Liste des combinaisons avec répétition :<br />
<br />
('a', 'a', 'a', 'a')<br />
('a', 'a', 'a', 'b')<br />
('a', 'a', 'a', 'c')<br />
('a', 'a', 'b', 'b')<br />
('a', 'a', 'b', 'c')<br />
('a', 'a', 'c', 'c')<br />
('a', 'b', 'b', 'b')<br />
('a', 'b', 'b', 'c')<br />
('a', 'b', 'c', 'c')<br />
('a', 'c', 'c', 'c')<br />
('b', 'b', 'b', 'b')<br />
('b', 'b', 'b', 'c')<br />
('b', 'b', 'c', 'c')<br />
('b', 'c', 'c', 'c')<br />
('c', 'c', 'c', 'c')</font></span><br />
<br />
<br />
<b>IV-C. Application : génération des triplets (x, y, z) tels que x + y + z = 4</b><br />
<br />
Déterminer les triplets <span class="highlight">(x, y, z)</span> de <b>&#8469;<sup>3</sup></b> tels que <span class="highlight">x + y + z = 4</span>.<br />
<br />
On peut se dire que l'on a trois types d'objets : ceux du type <b>X</b>, ceux du type <b>Y</b> et ceux du type <b>Z</b>. On doit en choisir <b>4</b> avec remise dans l'ensemble <span class="highlight">E = {X, Y, Z}</span>. Le nombre <b>x</b> sera donné par le nombre d'éléments du type <b>X</b> choisis, <b>y</b> par le nombre d'éléments du type <b>Y</b> et <b>z</b> par ceux du type <b>Z</b> :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #808080;"># valeur de k</span>
k = <span style="color: #cc66cc;">4</span>
&nbsp;
<span style="color: #808080;"># cr&eacute;ation de la liste d'&eacute;l&eacute;ments</span>
elements = <span class="br0">&#91;</span><span style="color: #FF0000;">'X'</span>, <span style="color: #FF0000;">'Y'</span>, <span style="color: #FF0000;">'Z'</span><span class="br0">&#93;</span>
&nbsp;
<span style="color: #808080;"># Cr&eacute;e le g&eacute;n&eacute;rateur permettant de parcourir la liste des combinaisons avec r&eacute;p&eacute;tition de k &eacute;l&eacute;ments pris dans un ensemble de n &eacute;l&eacute;ments.</span>
gen_combinaisons = generateur_combinaisons<span class="br0">&#40;</span>elements, k<span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Liste des combinaisons et leur triplet (x, y, z) tel que x + y + z = 4 :<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># Affiche les triplets (x, y, z) tels que x + y + z = 4.</span>
<span style="color: #0000ff;">for</span> combinaison <span style="color: #0000ff;">in</span> gen_combinaisons:
    <span style="color: #808080;"># d&eacute;termination du nombre de 'X', de 'Y' et de 'Z' pour chaque combinaison</span>
    x, y, z = combinaison.count<span class="br0">&#40;</span><span style="color: #FF0000;">&quot;X&quot;</span><span class="br0">&#41;</span>, combinaison.count<span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Y&quot;</span><span class="br0">&#41;</span>, combinaison.count<span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Z&quot;</span><span class="br0">&#41;</span>
&nbsp;
    <span style="color: #808080;"># Affiche la combinaison et son triplet (x, y, z).</span>
    <span style="color: #0000ff;">print</span><span class="br0">&#40;</span>str<span class="br0">&#40;</span>combinaison<span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot; &rarr; &quot;</span> + str<span class="br0">&#40;</span><span class="br0">&#40;</span>x, y, z<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
Le code affiche :<br />
<br />
<span class="highlight"><font color="#000080">Liste des combinaisons et leur triplet (x, y, z) tel que x + y + z = 4 :<br />
<br />
('X', 'X', 'X', 'X') &#8594; (4, 0, 0)<br />
('X', 'X', 'X', 'Y') &#8594; (3, 1, 0)<br />
('X', 'X', 'X', 'Z') &#8594; (3, 0, 1)<br />
('X', 'X', 'Y', 'Y') &#8594; (2, 2, 0)<br />
('X', 'X', 'Y', 'Z') &#8594; (2, 1, 1)<br />
('X', 'X', 'Z', 'Z') &#8594; (2, 0, 2)<br />
('X', 'Y', 'Y', 'Y') &#8594; (1, 3, 0)<br />
('X', 'Y', 'Y', 'Z') &#8594; (1, 2, 1)<br />
('X', 'Y', 'Z', 'Z') &#8594; (1, 1, 2)<br />
('X', 'Z', 'Z', 'Z') &#8594; (1, 0, 3)<br />
('Y', 'Y', 'Y', 'Y') &#8594; (0, 4, 0)<br />
('Y', 'Y', 'Y', 'Z') &#8594; (0, 3, 1)<br />
('Y', 'Y', 'Z', 'Z') &#8594; (0, 2, 2)<br />
('Y', 'Z', 'Z', 'Z') &#8594; (0, 1, 3)<br />
('Z', 'Z', 'Z', 'Z') &#8594; (0, 0, 4)</font></span><br />
<br />
<br />
<b>IV-D. Module complet</b><br />
<br />
On donne pour finir le code complet contenant les fonctions permettant de générer ces combinaisons :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="40"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br />50<br />51<br />52<br />53<br />54<br />55<br />56<br />57<br />58<br />59<br />60<br />61<br />62<br />63<br />64<br />65<br />66<br />67<br />68<br />69<br />70<br />71<br />72<br />73<br />74<br />75<br />76<br />77<br />78<br />79<br />80<br />81<br />82<br />83<br />84<br />85<br />86<br />87<br />88<br />89<br />90<br />91<br />92<br />93<br />94<br />95<br />96<br />97<br />98<br />99<br />100<br />101<br />102<br />103<br />104<br />105<br />106<br />107<br />108<br />109<br />110<br />111<br />112<br />113<br />114<br />115<br />116<br />117<br />118<br />119<br />120<br />121<br />122<br />123<br />124<br />125<br />126<br />127<br />128<br />129<br />130<br />131<br />132<br />133<br />134<br />135<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">def</span> generer_combinaisons<span class="br0">&#40;</span>elements, k<span class="br0">&#41;</span>:
    <span style="color: #808080;"># fonction permettant de g&eacute;n&eacute;rer la liste des combinaisons avec r&eacute;p&eacute;tition de k &eacute;l&eacute;ments pris dans un ensemble de n &eacute;l&eacute;ments</span>
    <span style="color: #808080;"># generer_combinaisons(['a','b','c'], 2) &rarr; ('a','a'), ('a','b'), ('a','c'), ('b','b'), ('b','c'), ('c','c')</span>
&nbsp;
    <span style="color: #808080;"># nombre d'&eacute;l&eacute;ments de l'ensemble</span>
    n = len<span class="br0">&#40;</span>elements<span class="br0">&#41;</span>
&nbsp;
    <span style="color: #808080;"># initialisation de la liste d'indices correspondant &agrave; une k-combinaison : [0, 0, .., 0] &rarr; ('a', 'a', .., 'a')</span>
    indices = <span class="br0">&#91;</span><span style="color: #cc66cc;">0</span><span class="br0">&#93;</span> * k
&nbsp;
    <span style="color: #808080;"># On cr&eacute;e la 1re combinaison &agrave; partir de la liste d'indices. ex. : [0, 0, 0] &rarr; ('a', 'a', 'a')</span>
    k_combinaison = tuple<span class="br0">&#40;</span>elements<span class="br0">&#91;</span>i<span class="br0">&#93;</span> <span style="color: #0000ff;">for</span> i <span style="color: #0000ff;">in</span> indices<span class="br0">&#41;</span>
&nbsp;
    <span style="color: #808080;"># initialisation de la liste avec la 1re combinaison</span>
    k_combinaisons = <span class="br0">&#91;</span>k_combinaison<span class="br0">&#93;</span>
&nbsp;
    <span style="color: #808080;"># tant que vrai</span>
    <span style="color: #0000ff;">while</span> <span style="color: #339933;">True</span>:
&nbsp;
        <span style="color: #808080;"># parcours des indices de la liste</span>
        <span style="color: #0000ff;">for</span> i <span style="color: #0000ff;">in</span> reversed<span class="br0">&#40;</span>range<span class="br0">&#40;</span>k<span class="br0">&#41;</span><span class="br0">&#41;</span>:
            <span style="color: #808080;"># Si la valeur de l'indice est diff&eacute;rente de n-1.</span>
            <span style="color: #0000ff;">if</span> indices<span class="br0">&#91;</span>i<span class="br0">&#93;</span> != n - <span style="color: #cc66cc;">1</span>:
                <span style="color: #0000ff;">break</span> <span style="color: #808080;"># On sort de la boucle : indice trouv&eacute;</span>
        <span style="color: #0000ff;">else</span>: <span style="color: #808080;"># sinon</span>
            <span style="color: #0000ff;">break</span> <span style="color: #808080;"># On sort de la boucle.</span>
&nbsp;
        <span style="color: #808080;"># copie (k-i) fois la valeur (indices[i] + 1) &agrave; partir de l'indice i dans la liste </span>
        indices<span class="br0">&#91;</span>i:<span class="br0">&#93;</span> = <span class="br0">&#91;</span>indices<span class="br0">&#91;</span>i<span class="br0">&#93;</span> + <span style="color: #cc66cc;">1</span><span class="br0">&#93;</span> * <span class="br0">&#40;</span>k - i<span class="br0">&#41;</span>
&nbsp;
        <span style="color: #808080;"># On g&eacute;n&egrave;re la combinaison correspondant &agrave; la liste d'indices.</span>
        k_combinaison = tuple<span class="br0">&#40;</span>elements<span class="br0">&#91;</span>i<span class="br0">&#93;</span> <span style="color: #0000ff;">for</span> i <span style="color: #0000ff;">in</span> indices<span class="br0">&#41;</span>
&nbsp;
        <span style="color: #808080;"># ajout de la combinaison &agrave; la liste</span>
        k_combinaisons.append<span class="br0">&#40;</span>k_combinaison<span class="br0">&#41;</span>
&nbsp;
    <span style="color: #808080;"># renvoi la liste des combinaisons</span>
    <span style="color: #0000ff;">return</span> k_combinaisons
&nbsp;
&nbsp;
<span style="color: #0000ff;">def</span> generateur_combinaisons<span class="br0">&#40;</span>elements, k<span class="br0">&#41;</span>:
    <span style="color: #808080;"># fonction permettant de g&eacute;n&eacute;rer la liste des combinaisons avec r&eacute;p&eacute;tition de k &eacute;l&eacute;ments pris dans un ensemble de n &eacute;l&eacute;ments</span>
    <span style="color: #808080;"># generateur_combinaisons(['a','b','c'], 2) &rarr; ('a','a'), ('a','b'), ('a','c'), ('b','b'), ('b','c'), ('c','c')</span>
&nbsp;
    <span style="color: #808080;"># nombre d'&eacute;l&eacute;ments de l'ensemble</span>
    n = len<span class="br0">&#40;</span>elements<span class="br0">&#41;</span>
&nbsp;
    <span style="color: #808080;"># initialisation de la liste d'indices correspondant &agrave; une k-combinaison : [0, 0, .., 0] &rarr; ('a', 'a', .., 'a')</span>
    indices = <span class="br0">&#91;</span><span style="color: #cc66cc;">0</span><span class="br0">&#93;</span> * k
&nbsp;
    <span style="color: #808080;"># On g&eacute;n&egrave;re la 1re combinaison. ex. : [0, 0, 0] &rarr; ('a', 'a', 'a')</span>
    <span style="color: #0000ff;">yield</span> tuple<span class="br0">&#40;</span>elements<span class="br0">&#91;</span>i<span class="br0">&#93;</span> <span style="color: #0000ff;">for</span> i <span style="color: #0000ff;">in</span> indices<span class="br0">&#41;</span>
&nbsp;
    <span style="color: #0000ff;">while</span> <span style="color: #339933;">True</span>:
&nbsp;
        <span style="color: #808080;"># parcours des indices de la liste indices</span>
        <span style="color: #0000ff;">for</span> i <span style="color: #0000ff;">in</span> reversed<span class="br0">&#40;</span>range<span class="br0">&#40;</span>k<span class="br0">&#41;</span><span class="br0">&#41;</span>:
            <span style="color: #808080;"># Si la valeur de l'indice est diff&eacute;rente de n-1</span>
            <span style="color: #0000ff;">if</span> indices<span class="br0">&#91;</span>i<span class="br0">&#93;</span> != n - <span style="color: #cc66cc;">1</span>:
                <span style="color: #0000ff;">break</span> <span style="color: #808080;"># On sort de la boucle : indice trouv&eacute;</span>
        <span style="color: #0000ff;">else</span>:
            <span style="color: #0000ff;">return</span>
&nbsp;
        <span style="color: #808080;"># copie (k-i) fois la valeur (indices[i] + 1) &agrave; partir de l'indice i dans la liste</span>
        indices<span class="br0">&#91;</span>i:<span class="br0">&#93;</span> = <span class="br0">&#91;</span>indices<span class="br0">&#91;</span>i<span class="br0">&#93;</span> + <span style="color: #cc66cc;">1</span><span class="br0">&#93;</span> * <span class="br0">&#40;</span>k - i<span class="br0">&#41;</span>
&nbsp;
        <span style="color: #808080;"># On g&eacute;n&egrave;re la combinaison correspondant aux indices.</span>
        <span style="color: #0000ff;">yield</span> tuple<span class="br0">&#40;</span>elements<span class="br0">&#91;</span>i<span class="br0">&#93;</span> <span style="color: #0000ff;">for</span> i <span style="color: #0000ff;">in</span> indices<span class="br0">&#41;</span>
&nbsp;
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;G&eacute;n&eacute;ration des combinaisons avec r&eacute;p&eacute;tition de k &eacute;l&eacute;ments pris dans un ensemble de n &eacute;l&eacute;ments..<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># valeur de k</span>
k = <span style="color: #cc66cc;">4</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;k = &quot;</span> + str<span class="br0">&#40;</span>k<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># cr&eacute;ation de la liste d'&eacute;l&eacute;ments</span>
elements = <span class="br0">&#91;</span><span style="color: #FF0000;">'a'</span>,<span style="color: #FF0000;">'b'</span>,<span style="color: #FF0000;">'c'</span><span class="br0">&#93;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;E = &quot;</span> + str<span class="br0">&#40;</span>elements<span class="br0">&#41;</span>.replace<span class="br0">&#40;</span><span style="color: #FF0000;">&quot;[&quot;</span>,<span style="color: #FF0000;">&quot;{&quot;</span><span class="br0">&#41;</span>.replace<span class="br0">&#40;</span><span style="color: #FF0000;">&quot;]&quot;</span>,<span style="color: #FF0000;">&quot;}&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;I. Version n&deg;1 : m&eacute;thode classique<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># G&eacute;n&egrave;re la liste des combinaisons avec r&eacute;p&eacute;tition de k &eacute;l&eacute;ments pris dans un ensemble de n &eacute;l&eacute;ments.</span>
combinaisons = generer_combinaisons<span class="br0">&#40;</span>elements, k<span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Liste des combinaisons avec r&eacute;p&eacute;tition :<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># Affiche la liste des combinaisons</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span>combinaisons<span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;II. Version n&deg;2 : fonction g&eacute;n&eacute;ratrice avec yield<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># Cr&eacute;e le g&eacute;n&eacute;rateur permettant de parcourir la liste des combinaisons avec r&eacute;p&eacute;tition de k &eacute;l&eacute;ments pris dans un ensemble de n &eacute;l&eacute;ments.</span>
gen_combinaisons = generateur_combinaisons<span class="br0">&#40;</span>elements, k<span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Liste des combinaisons avec r&eacute;p&eacute;tition :<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># Affiche les combinaisons une &agrave; une.</span>
<span style="color: #0000ff;">for</span> combinaison <span style="color: #0000ff;">in</span> gen_combinaisons:
    <span style="color: #0000ff;">print</span><span class="br0">&#40;</span>combinaison<span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;III. Application : g&eacute;n&eacute;ration des triplets (x, y, z) tels que x + y + z = 4<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># valeur de k</span>
k = <span style="color: #cc66cc;">4</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;k = &quot;</span> + str<span class="br0">&#40;</span>k<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># cr&eacute;ation de la liste d'&eacute;l&eacute;ments</span>
elements = <span class="br0">&#91;</span><span style="color: #FF0000;">'X'</span>, <span style="color: #FF0000;">'Y'</span>, <span style="color: #FF0000;">'Z'</span><span class="br0">&#93;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;E = &quot;</span> + str<span class="br0">&#40;</span>elements<span class="br0">&#41;</span>.replace<span class="br0">&#40;</span><span style="color: #FF0000;">&quot;[&quot;</span>,<span style="color: #FF0000;">&quot;{&quot;</span><span class="br0">&#41;</span>.replace<span class="br0">&#40;</span><span style="color: #FF0000;">&quot;]&quot;</span>,<span style="color: #FF0000;">&quot;}&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># Cr&eacute;e le g&eacute;n&eacute;rateur permettant de parcourir la liste des combinaisons avec r&eacute;p&eacute;tition de k &eacute;l&eacute;ments pris dans un ensemble de n &eacute;l&eacute;ments</span>
gen_combinaisons = generateur_combinaisons<span class="br0">&#40;</span>elements, k<span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Liste des combinaisons et leur triplet (x, y, z) tel que x + y + z = 4 :<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># Affiche les triplets (x, y, z) tels que x + y + z = 4</span>
<span style="color: #0000ff;">for</span> combinaison <span style="color: #0000ff;">in</span> gen_combinaisons:
    <span style="color: #808080;"># d&eacute;termination du nombre de 'X', de 'Y' et de 'Z' pour chaque combinaison</span>
    x, y, z = combinaison.count<span class="br0">&#40;</span><span style="color: #FF0000;">&quot;X&quot;</span><span class="br0">&#41;</span>, combinaison.count<span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Y&quot;</span><span class="br0">&#41;</span>, combinaison.count<span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Z&quot;</span><span class="br0">&#41;</span>
&nbsp;
    <span style="color: #808080;"># Affiche la combinaison et son triplet (x, y, z).</span>
    <span style="color: #0000ff;">print</span><span class="br0">&#40;</span>str<span class="br0">&#40;</span>combinaison<span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot; &rarr; &quot;</span> + str<span class="br0">&#40;</span><span class="br0">&#40;</span>x, y, z<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
<br />
<b>V. Conclusion</b><br />
<br />
Après avoir décrit brièvement l'algorithme permettant d'obtenir la liste des combinaisons avec répétition, on a pu proposer une première fonction en Python basée sur cet algorithme. <br />
<br />
Enfin, on a créé une fonction génératrice à partir de ce code pour éviter les problèmes de mémoire insuffisante.<br />
<br />
<br />
<b>Sources :</b><br />
<br />
<a href="https://fr.wikipedia.org/wiki/Combinaison_avec_r%C3%A9p%C3%A9tition" target="_blank">https://fr.wikipedia.org/wiki/Combin...9p%C3%A9tition</a><br />
<a href="https://fr.wikipedia.org/wiki/Combinaison_sans_r%C3%A9p%C3%A9tition" target="_blank">https://fr.wikipedia.org/wiki/Combin...9p%C3%A9tition</a><br />
<a href="https://fr.wikipedia.org/wiki/Combinatoire" target="_blank">https://fr.wikipedia.org/wiki/Combinatoire</a><br />
<a href="https://docs.python.org/fr/3/library/itertools.html" target="_blank">https://docs.python.org/fr/3/library/itertools.html</a><br />
<a href="https://gayerie.dev/docs/python/python3/iterateur_generateur.html#les-generateurs" target="_blank">https://gayerie.dev/docs/python/pyth...es-generateurs</a><br />
<a href="https://www.mathraining.be/chapters/35?type=1&amp;which=118" target="_blank">https://www.mathraining.be/chapters/35?type=1&amp;which=118</a></font></blockquote>

]]></content:encoded>
			<dc:creator>User</dc:creator>
			<guid isPermaLink="true">https://www.developpez.net/forums/blogs/44027-user/b10594/analyse-combinatoire-python-combinaisons-repetition/</guid>
		</item>
		<item>
			<title><![CDATA[Calcul formel en Python : les polynômes d'interpolation de Lagrange vus comme des vecteurs]]></title>
			<link>https://www.developpez.net/forums/blogs/44027-user/b10590/calcul-formel-python-polynomes-d-interpolation-lagrange-vus-vecteurs/</link>
			<pubDate>Mon, 18 Mar 2024 08:44:47 GMT</pubDate>
			<description><![CDATA[*I. Introduction* 
 
D'après...]]></description>
			<content:encoded><![CDATA[<blockquote class="blogcontent restore"><font size="3"><br />
<b>I. Introduction</b><br />
<br />
D'après Wikipedia, en algèbre linéaire, un <a href="https://fr.wikipedia.org/wiki/Espace_vectoriel" target="_blank">espace vectoriel</a> est un ensemble d'objets, appelés vecteurs, que l'on peut additionner entre eux, et que l'on peut multiplier par un scalaire (pour les étirer ou les rétrécir, les tourner, etc.).<br />
<br />
On va d'abord montrer que l'ensemble des polynômes pouvant être construits sur la base des polynômes de Lagrange <b>(l<sub>0</sub>, l<sub>1</sub>, …, l<sub>n</sub>)</b> constitue un espace vectoriel.<br />
<br />
Dans un second temps, on va représenter les polynômes d'interpolation de Lagrange à l'aide d'une classe en Python, puis définir les opérations d'addition entre ces vecteurs et de multiplication par un scalaire en utilisant la <a href="https://docs.python.org/fr/3/reference/datamodel.html#emulating-numeric-types" target="_blank">surcharge d'opérateur</a>.<br />
<br />
Enfin, on va tester le code Python en effectuant différentes opérations sur ces nouveaux objets comme on le ferait sur des vecteurs.<br />
<br />
<br />
<b>II. Espace vectoriel</b><br />
<br />
<div style="text-align: center;"><img src="https://www.developpez.net/forums/attachments/p652083d1710321910/autres-langages/xml-xsl-soap/xsl-xslt-xpath/probleme-xsl-inclure-donnee-xml-balise-html/e.png/" border="0" alt="Nom : E.png
Affichages : 23541
Taille : 3,5 Ko"  style="float: CONFIG" /></div><br />
<b>II-A. Définition</b><br />
<br />
Soit <b>K</b> un <a href="https://fr.wikipedia.org/wiki/Corps_commutatif" target="_blank">corps commutatif</a>, comme le corps commutatif <b>&#8474;</b> des rationnels, celui, <b>&#8477;</b>, des réels ou celui, <b>&#8450;</b>, des complexes (on parlera dans ces cas d'espace vectoriel rationnel, réel ou complexe).<br />
<br />
D'après Wikipedia, un espace vectoriel sur <b>K</b>, est un ensemble <b>E</b>, dont les éléments sont appelés vecteurs, muni de deux lois :<br />
<br />
<ul><li style="">une loi de composition interne « + » : <b>E<sup>2</sup></b> &#8594; <b>E</b>, appelée addition ou somme vectorielle ;</li><li style="">une loi de composition externe à gauche « • » : <b>K × E</b> &#8594; <b>E</b>, appelée multiplication par un scalaire.</li></ul><br />
<br />
Une loi de composition interne est donc une application qui, à deux éléments d'un ensemble <b>E</b>, associe un élément de <b>E</b>, comme la multiplication ou l'addition dans l'ensemble des naturels.<br />
<br />
Contrairement à une loi de composition interne, une loi de composition externe fait intervenir des éléments de l’extérieur, ici un scalaire dans <b>K</b>. <br />
<br />
On admettra sans les démontrer les propriétés suivantes :<br />
<br />
<ul><li style="">La loi « + » est commutative, associative, admet un élément neutre et tout élément de cette espace possède un opposé.</li><li style="">La loi « • » est distributive par rapport à la loi « + », vérifie une associativité mixte et admet un élément neutre à gauche.</li></ul><br />
<br />
<b>II-B. Base d'un espace vectoriel</b><br />
<br />
<div style="text-align: center;"><img src="https://www.developpez.net/forums/attachments/p652051d1710262924/autres-langages/xml-xsl-soap/xsl-xslt-xpath/probleme-xsl-inclure-donnee-xml-balise-html/base.png/" border="0" alt="Nom : base.png
Affichages : 7389
Taille : 50,1 Ko"  style="float: CONFIG" /></div><br />
En algèbre linéaire, une <a href="https://fr.wikipedia.org/wiki/Base_(alg%C3%A8bre_lin%C3%A9aire)" target="_blank">base</a> d'un espace vectoriel <b>V</b> est une <a href="https://fr.wikipedia.org/wiki/Famille_(math%C3%A9matiques)" target="_blank">famille</a> de vecteurs de <b>V</b> linéairement indépendants et dont tout vecteur de <b>V</b> est <a href="https://fr.wikipedia.org/wiki/Combinaison_lin%C3%A9aire" target="_blank">combinaison linéaire</a>. <br />
<br />
Autrement dit, une base de <b>V</b> est une <a href="https://fr.wikipedia.org/wiki/Ind%C3%A9pendance_lin%C3%A9aire" target="_blank">famille libre</a> de vecteurs de <b>V</b> qui engendre <b>V</b>. <br />
<br />
<br />
<br />
<b>III. Polynômes d'interpolation de Lagrange</b><br />
<br />
Soit <b>n + 1</b> points <b>(x<sub>0</sub> ,y<sub>0</sub>) , … , (x<sub>n</sub> , y<sub>n</sub>)</b> (avec les <b>x<sub>i</sub></b> des réels distincts deux à deux). <br />
<br />
Le <a href="https://fr.wikipedia.org/wiki/Interpolation_lagrangienne" target="_blank">polynôme d'interpolation de Lagrange</a> de degré au plus <b>n</b> qui passe par ces points est défini par :<br />
<br />
<img src="https://www.developpez.net/forums/attachments/p652058d1710267870/autres-langages/xml-xsl-soap/xsl-xslt-xpath/probleme-xsl-inclure-donnee-xml-balise-html/polynome_interpolation_lagrange.png/" border="0" alt="Nom : polynome_interpolation_lagrange.png
Affichages : 8287
Taille : 9,3 Ko"  style="float: CONFIG" /><br />
<br />
<br />
<b>III-A. Espace &#8477;<sub>n</sub>[X] des polynômes</b><br />
<br />
<div style="text-align: center;"><img src="https://www.developpez.net/forums/attachments/p652239d1710592393/autres-langages/xml-xsl-soap/xsl-xslt-xpath/probleme-xsl-inclure-donnee-xml-balise-html/rn-x-.png/" border="0" alt="Nom : Rn[X].png
Affichages : 7333
Taille : 5,1 Ko"  style="float: CONFIG" /></div><br />
<b>L</b> étant une <a href="https://fr.wikipedia.org/wiki/Combinaison_lin%C3%A9aire" target="_blank">combinaison linéaire</a> de polynômes de degré <b>n</b>, il est de degré au plus <b>n</b> et appartient donc à l'ensemble <b>&#8477;<sub>n</sub>[X]</b>. <br />
<br />
Quel que soit le polynôme <b>P</b> appartenant à <b>&#8477;<sub>n</sub>[X]</b>, on peut également écrire :<br />
<br />
<img src="https://www.developpez.net/forums/attachments/p652046d1710262582/autres-langages/xml-xsl-soap/xsl-xslt-xpath/probleme-xsl-inclure-donnee-xml-balise-html/polynome_interpolation_lagrange2.png/" border="0" alt="Nom : polynome_interpolation_lagrange2.png
Affichages : 9119
Taille : 2,1 Ko"  style="float: CONFIG" /><br />
<br />
<b>Proposition :</b><br />
<br />
Étant donné <b>n + 1</b> réels distincts <b>x<sub>0</sub>, …, x<sub>n</sub></b>, l'ensemble des polynômes que l'on peut construire avec la <a href="https://fr.wikipedia.org/wiki/Famille_(math%C3%A9matiques)" target="_blank">famille</a> de polynômes <b>(l<sub>0</sub>, l<sub>1</sub>, …, l<sub>n</sub>)</b> constitue un espace vectoriel muni de deux lois :<br />
<br />
<ul><li style="">une loi de composition interne « + », appelée addition ou somme vectorielle ;</li><li style="">une loi de composition externe à gauche « • », appelée multiplication par un scalaire.</li></ul><br />
<br />
Décrivons maintenant pour le vérifier les opérations pouvant être réalisées sur ces vecteurs.<br />
<br />
<br />
<b>III-A-1. Addition de polynômes</b><br />
<br />
Soit deux polynômes d'interpolation de Lagrange <b>P</b> et <b>Q</b> construits avec la même famille de polynômes <b>(l<sub>0</sub>, l<sub>1</sub>, …, l<sub>n</sub>)</b> :<br />
<br />
<img src="https://www.developpez.net/forums/attachments/p652043d1710262477/autres-langages/xml-xsl-soap/xsl-xslt-xpath/probleme-xsl-inclure-donnee-xml-balise-html/polynomes.png/" border="0" alt="Nom : polynomes.png
Affichages : 7353
Taille : 4,2 Ko"  style="float: CONFIG" /><br />
<br />
L'addition de ces deux polynômes donne :<br />
<br />
<img src="https://www.developpez.net/forums/attachments/p652044d1710262510/autres-langages/xml-xsl-soap/xsl-xslt-xpath/probleme-xsl-inclure-donnee-xml-balise-html/addition_polynomes.png/" border="0" alt="Nom : addition_polynomes.png
Affichages : 7324
Taille : 3,0 Ko"  style="float: CONFIG" /><br />
<br />
On obtient donc un nouveau polynôme d'interpolation de Lagrange construit avec la même famille de polynômes <b>(l<sub>0</sub>, l<sub>1</sub>, …, l<sub>n</sub>)</b> et appartenant au même espace <b>&#8477;<sub>n</sub>[X]</b>. <br />
<br />
Cette addition est donc bien une loi de composition interne dans cet espace vectoriel.<br />
<br />
<br />
<b>III-A-2. Multiplication d'un polynôme par un scalaire</b><br />
<br />
La multiplication de <b>P(X)</b> par un scalaire <b>s</b> donne :<br />
<br />
<img src="https://www.developpez.net/forums/attachments/p652045d1710262547/autres-langages/xml-xsl-soap/xsl-xslt-xpath/probleme-xsl-inclure-donnee-xml-balise-html/multiplication_scalaire.png/" border="0" alt="Nom : multiplication_scalaire.png
Affichages : 7303
Taille : 2,1 Ko"  style="float: CONFIG" /><br />
<br />
On obtient donc un nouveau polynôme d'interpolation de Lagrange construit avec la même famille de polynômes <b>(l<sub>0</sub>, l<sub>1</sub>, …, l<sub>n</sub>)</b> et appartenant au même espace. <br />
<br />
Cette opération est donc bien une loi de composition externe dans cet espace vectoriel.<br />
<br />
Ces deux opérations vérifient également les propriétés citées plus haut.<br />
<br />
<br />
<b>III-B. Base de polynômes</b><br />
<br />
On se donne à nouveau <b>n + 1</b> réels distincts <b>x<sub>0</sub>, …, x<sub>n</sub></b>. Pour tout polynôme <b>P</b> appartenant à un espace <b>&#8477;<sub>n</sub>[X]</b> des polynômes, si on pose <span class="highlight">y<sub>i</sub> = P(x<sub>i</sub>)</span>, <b>P</b> étant le polynôme d'interpolation correspondant aux points, il est égal au polynôme <b>L</b> défini précédemment. <br />
<br />
On a donc :<br />
<br />
<img src="https://www.developpez.net/forums/attachments/p652046d1710262582/autres-langages/xml-xsl-soap/xsl-xslt-xpath/probleme-xsl-inclure-donnee-xml-balise-html/polynome_interpolation_lagrange2.png/" border="0" alt="Nom : polynome_interpolation_lagrange2.png
Affichages : 9119
Taille : 2,1 Ko"  style="float: CONFIG" /><br />
<br />
Et donc <b>(l<sub>0</sub>, l<sub>1</sub>, …, l<sub>n</sub>)</b> forme une famille génératrice de <b>&#8477;<sub>n</sub>[X]</b> et son cardinal (égal à <b>n + 1</b>) est égal à la dimension de l'espace. <br />
<br />
Par exemple, en choisissant <b>P = 1</b> ou <b>P = X</b>, on obtient :<br />
<br />
<img src="https://www.developpez.net/forums/attachments/p652047d1710262620/autres-langages/xml-xsl-soap/xsl-xslt-xpath/probleme-xsl-inclure-donnee-xml-balise-html/egalites_polynomes.png/" border="0" alt="Nom : egalites_polynomes.png
Affichages : 7331
Taille : 2,7 Ko"  style="float: CONFIG" /><br />
<br />
On peut remarquer également que le polynôme nul <span class="highlight">P = 0</span> est tel que :<br />
<br />
<img src="https://www.developpez.net/forums/attachments/p652196d1710494583/autres-langages/xml-xsl-soap/xsl-xslt-xpath/probleme-xsl-inclure-donnee-xml-balise-html/polynome_nul.png/" border="0" alt="Nom : polynome_nul.png
Affichages : 7280
Taille : 2,3 Ko"  style="float: CONFIG" /><br />
<br />
Cela implique nécessairement que :<br />
<br />
<img src="https://www.developpez.net/forums/attachments/p652197d1710494630/autres-langages/xml-xsl-soap/xsl-xslt-xpath/probleme-xsl-inclure-donnee-xml-balise-html/coefficients_nuls.png/" border="0" alt="Nom : coefficients_nuls.png
Affichages : 7287
Taille : 1,8 Ko"  style="float: CONFIG" /><br />
<br />
On en déduit que cette famille génératrice <b>(l<sub>0</sub>, l<sub>1</sub>, …, l<sub>n</sub>)</b> est également <a href="https://fr.wikipedia.org/wiki/Ind%C3%A9pendance_lin%C3%A9aire" target="_blank">libre</a>, et par conséquent c'est une base de l'espace des polynômes qu'elle engendre.<br />
<br />
Cette famille forme en fait une base orthonormée de <b>&#8477;<sub>n</sub>[X]</b>.<br />
<br />
Si vous souhaitez avoir plus d'information sur le sujet je vous invite à consulter la page Wikipedia <a href="https://fr.wikipedia.org/wiki/Interpolation_lagrangienne" target="_blank">Interpolation lagrangienne</a>.<br />
<br />
<br />
<br />
<b>IV. Implémentation en Python</b><br />
<br />
Ces polynômes peuvent donc être vus comme des vecteurs sur lesquels on peut réaliser les opérations d'addition et de multiplication par un scalaire.<br />
<br />
On va maintenant représenter les polynômes d'interpolation de Lagrange en Python à l'aide d'une classe, puis définir ces opérations en utilisant la <a href="https://docs.python.org/fr/3/reference/datamodel.html#emulating-numeric-types" target="_blank">surcharge d'opérateur</a>.<br />
<br />
<br />
<b>IV-A. Création de la classe Polynome_lagrange</b><br />
<br />
Pour définir ces polynômes en <b>Python</b> et pouvoir réaliser des opérations entre eux, il nous faut donc créer une <a href="https://docs.python.org/fr/3/tutorial/classes.html" target="_blank">classe</a> Polynome_lagrange.<br />
<br />
<div style="text-align: center;"><img src="https://www.developpez.net/forums/attachments/p652052d1710262961/autres-langages/xml-xsl-soap/xsl-xslt-xpath/probleme-xsl-inclure-donnee-xml-balise-html/classe_polynome_lagrange.png/" border="0" alt="Nom : classe_polynome_lagrange.png
Affichages : 7288
Taille : 8,1 Ko"  style="float: CONFIG" /></div><br />
Sa méthode constructeur <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">__init__()</span> va nous permettre de définir les listes de valeurs <b>x</b> et <b>y</b> du polynôme d'interpolation de Lagrange au moment de créer l'objet :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">import</span> numpy <span style="color: #0000ff;">as</span> np
&nbsp;
<span style="color: #0000ff;">class</span> Polynome_lagrange:
&nbsp;
    <span style="color: #0000ff;">def</span> <span style="color: #0080ff;">__init__</span><span class="br0">&#40;</span>self, x, y<span class="br0">&#41;</span>:
        <span style="color: #808080;"># m&eacute;thode constructeur de la classe</span>
&nbsp;
        <span style="color: #808080;"># on d&eacute;finit la liste de valeurs en x permettant d'obtenir la famille de polyn&ocirc;mes (l0, l1, ..., ln) repr&eacute;sentant une base dans &#8477;n[X]</span>
        self.x = x
&nbsp;
        <span style="color: #808080;"># on d&eacute;finit le tableau de valeurs en y repr&eacute;sentant les coordonn&eacute;es du vecteur (tableau numpy)</span>
        self.y = np.array<span class="br0">&#40;</span>y<span class="br0">&#41;</span>
&nbsp;
&nbsp;
    <span style="color: #0000ff;">def</span> __str__<span class="br0">&#40;</span>self<span class="br0">&#41;</span>:
	...</pre></td></tr></table></pre>
</div><br />
En python, les <a href="https://pyspc.readthedocs.io/fr/latest/05-bases/08-tableaux_numpy.html" target="_blank">tableaux</a> de la librairie numpy représentent également des vecteurs sur lesquels on peut réaliser les mêmes opérations (addition, multiplication par un scalaire, etc.) :<br />
<br />
La méthode <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">__str__</span> permet d'afficher un polynôme sous la forme <span class="highlight">y0&#8729;L0(X) + y1&#8729;L1(X) + y2&#8729;L2(X)</span>.<br />
<br />
La classe comporte également deux autres méthodes <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">espace()</span> et <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">base()</span> permettant de connaître l'espace vectoriel du polynôme et sa base. <br />
<br />
Pour tester ces méthodes, nous ajoutons ces quelques lignes au module :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:144px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="26"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #808080;"># cr&eacute;ation de l'objet Polynome_lagrange : 1&#8729;L0(X) + 2&#8729;L1(X) + 5&#8729;L2(X)</span>
p = Polynome_lagrange<span class="br0">&#40;</span>x=<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span>, <span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">2</span><span class="br0">&#93;</span>, y=<span class="br0">&#91;</span><span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">2</span>, <span style="color: #cc66cc;">5</span><span class="br0">&#93;</span><span class="br0">&#41;</span> 
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span>p<span class="br0">&#41;</span> <span style="color: #808080;"># affiche l'expression du polyn&ocirc;me</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche l'appartenance de p &agrave; son espace vectoriel</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;p &isin; &quot;</span> + p.espace<span class="br0">&#40;</span><span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot;, Base = &quot;</span> + p.base<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
Le code affiche :<br />
<br />
<span class="highlight"><font color="#000000">1&#8729;L0(X) + 2&#8729;L1(X) + 5&#8729;L2(X)<br />
<br />
p &#8712; &#8477;2[X], Base = (L0, L1, L2), x = [0, 1, 2]</font></span><br />
<br />
<br />
<b>IV-A-1. Addition de deux polynômes</b><br />
<br />
Pour <a href="https://docs.python.org/fr/3/reference/datamodel.html#emulating-numeric-types" target="_blank">surcharger l'opérateur</a> « <b>+</b> » et pouvoir ainsi réaliser l'addition de <b>2</b> polynômes de même base, nous devons ajouter une méthode <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">__add __ ()</span> à la classe :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">class</span> Polynome_lagrange:
    ... 
    <span style="color: #0000ff;">def</span> <span style="color: #0080ff;">__add__</span><span class="br0">&#40;</span>self, other<span class="br0">&#41;</span>:
        <span style="color: #808080;"># m&eacute;thode permettant de red&eacute;finir l'op&eacute;rateur &laquo; + &raquo; pour 2 polyn&ocirc;mes d'interpolation de Lagrange ou 2 vecteurs</span>
        <span style="color: #808080;"># (y0*L0(X) + ... + yn*Ln(X)) + (z0*L0(X) + ... + zn*Ln(X)) = (y0 + z0)*L0(X) + ... + (yn + zn)*Ln(X)</span>
&nbsp;
        <span style="color: #808080;"># si les 2 vecteurs self et other ont la m&ecirc;me base</span>
        <span style="color: #0000ff;">if</span> self.x==other.x:
&nbsp;
            <span style="color: #808080;"># addition des 2 vecteurs self.y et other.y (2 tableaux numpy)</span>
            y = self.y + other.y
&nbsp;
            <span style="color: #808080;"># renvoie le polyn&ocirc;mes r&eacute;sultat de l'addition des 2 polyn&ocirc;mes self et other</span>
            <span style="color: #0000ff;">return</span> Polynome_lagrange<span class="br0">&#40;</span>self.x, y<span class="br0">&#41;</span>
&nbsp;
        <span style="color: #0000ff;">else</span>: <span style="color: #808080;"># sinon</span>
&nbsp;
            <span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Les 2 polyn&ocirc;mes n'ont pas la m&ecirc;me base !&quot;</span><span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
Cette méthode permet donc de redéfinir l'opération « <b>+</b> » pour les polynômes de même base en les additionnant comme des vecteurs d'un même espace.<br />
<br />
Pour tester l'opérateur d'addition portant sur <b>2</b> objets de la classe Polynome_lagrange, nous ajoutons ces lignes de code :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #808080;"># cr&eacute;ation du 1er objet de la classe Polynome_lagrange</span>
p1 = Polynome_lagrange<span class="br0">&#40;</span>x=<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span>, <span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">2</span><span class="br0">&#93;</span>, y=<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span>, <span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">4</span><span class="br0">&#93;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># cr&eacute;ation du 2e objet de la classe Polynome_lagrange</span>
p2 = Polynome_lagrange<span class="br0">&#40;</span>x=<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span>, <span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">2</span><span class="br0">&#93;</span>, y=<span class="br0">&#91;</span><span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">2</span>, <span style="color: #cc66cc;">5</span><span class="br0">&#93;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche l'expression des polyn&ocirc;mes p1 et p2</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;p1 = &quot;</span> + str<span class="br0">&#40;</span>p1<span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;p2 = &quot;</span> + str<span class="br0">&#40;</span>p2<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche l'appartenance de p1 et p2 &agrave; son espace vectoriel : R2[X], Base = [L0, L1, L2], x = [0, 1, 2]</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;p1 &isin; &quot;</span> + p1.espace<span class="br0">&#40;</span><span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot;, Base = &quot;</span> + p1.base<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;p2 &isin; &quot;</span> + p1.espace<span class="br0">&#40;</span><span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot;, Base = &quot;</span> + p2.base<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;p = p1 + p2&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># addition des 2 polyn&ocirc;mes</span>
p = p1 + p2
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche le r&eacute;sultat de l'addition</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;p = &quot;</span> + str<span class="br0">&#40;</span>p<span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche l'appartenance de p &agrave; son espace vectoriel</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;p &isin; &quot;</span> + p.espace<span class="br0">&#40;</span><span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot;, Base = &quot;</span> + p.base<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
Le code affiche :<br />
<br />
<span class="highlight"><font color="#000000">p1 = 0&#8729;L0(X) + 1&#8729;L1(X) + 4&#8729;L2(X)<br />
p2 = 1&#8729;L0(X) + 2&#8729;L1(X) + 5&#8729;L2(X)<br />
<br />
p1 &#8712; &#8477;2[X], Base = (L0, L1, L2), x = [0, 1, 2]<br />
p2 &#8712; &#8477;2[X], Base = (L0, L1, L2), x = [0, 1, 2]<br />
<br />
p = p1 + p2<br />
<br />
p = 1&#8729;L0(X) + 3&#8729;L1(X) + 9&#8729;L2(X)<br />
<br />
p &#8712; &#8477;2[X], Base = (L0, L1, L2), x = [0, 1, 2]</font></span><br />
<br />
<br />
<b>IV-A-2. Multiplication d'un polynôme par un scalaire</b><br />
<br />
Pour réaliser la multiplication d'un objet Polynome_lagrange par un scalaire, on va ajouter une méthode __mul __ () qui va permettre de surcharger l'opérateur « <b>*</b> » :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:168px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">class</span> Polynome_lagrange:
    ... 
    <span style="color: #0000ff;">def</span> <span style="color: #0080ff;">__mul__</span><span class="br0">&#40;</span>self, s<span class="br0">&#41;</span>:
        <span style="color: #808080;"># m&eacute;thode permettant de multiplier le polyn&ocirc;me self par un scalaire</span>
        <span style="color: #808080;"># : s*(y0*L0(X) + ... + yn*Ln(X)) = s*y0*L0(X) + ... + s*yn*Ln(X)</span>
&nbsp;
        <span style="color: #808080;"># multiplication du vecteur self.y par le scalaire s</span>
        y = s*self.y
&nbsp;
        <span style="color: #808080;"># renvoie le polyn&ocirc;me d'interpolation de Lagrange r&eacute;sultat de la multiplication de self par le scalaire s</span>
        <span style="color: #0000ff;">return</span> Polynome_lagrange<span class="br0">&#40;</span>self.x, y<span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
Le scalaire <b>s</b> est passé comme deuxième argument à la fonction car le premier argument doit obligatoirement être un objet de la classe.<br />
<br />
Pour tester l'opérateur de multiplication d'un objet de la classe Polynome_lagrange par un scalaire <b>s</b>, nous ajoutons maintenant ces lignes :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #808080;"># cr&eacute;ation de l'objet de la classe Polynome_lagrange :</span>
p1 = Polynome_lagrange<span class="br0">&#40;</span>x=<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span>, <span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">2</span><span class="br0">&#93;</span>, y=<span class="br0">&#91;</span><span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">2</span>, <span style="color: #cc66cc;">5</span><span class="br0">&#93;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche l'expression du polyn&ocirc;me p1</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;p1 = &quot;</span> + str<span class="br0">&#40;</span>p1<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche l'appartenance de p1 &agrave; son espace vectoriel</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;p1 &isin; &quot;</span> + p1.espace<span class="br0">&#40;</span><span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot;, Base = &quot;</span> + p1.base<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># d&eacute;finition du scalaire s</span>
s = <span style="color: #cc66cc;">2</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;s = &quot;</span> + str<span class="br0">&#40;</span>s<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;p = p1*s &quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># multiplication du polyn&ocirc;me p1 par le scalaire s</span>
p = p1*s
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche le r&eacute;sultat de la multiplication de p1 par s</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;p = &quot;</span> + str<span class="br0">&#40;</span>p<span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche l'appartenance de p &agrave; son espace vectoriel</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;p &isin; &quot;</span> + p.espace<span class="br0">&#40;</span><span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot;, Base = &quot;</span> + p.base<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
Le code affiche :<br />
<br />
<span class="highlight"><font color="#000000">p1 = 1&#8729;L0(X) + 2&#8729;L1(X) + 5&#8729;L2(X)<br />
<br />
p1 &#8712; &#8477;2[X], Base = (L0, L1, L2), x = [0, 1, 2]<br />
<br />
s = 2<br />
<br />
p = p1*s <br />
<br />
p = 2&#8729;L0(X) + 4&#8729;L1(X) + 10&#8729;L2(X)<br />
<br />
p &#8712; &#8477;2[X], Base = (L0, L1, L2), x = [0, 1, 2]</font></span><br />
<br />
<br />
On peut également imaginer d'effectuer la somme, la moyenne ou toute combinaison linéaire de vecteurs de la même base pour obtenir un nouveau vecteur de cette même base.<br />
<br />
<br />
<b>IV-A-3. Évaluation du polynôme </b><br />
<br />
On souhaite pour terminer évaluer nos polynômes en faisant simplement <span class="highlight">p(2)</span>. <br />
<br />
Pour cela, on va donc rendre nos objets callable en ajoutant une méthode __call__() à notre classe :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">class</span> Polynome_lagrange:
    ... 
    <span style="color: #0000ff;">def</span> <span style="color: #0080ff;">__call__</span><span class="br0">&#40;</span>self, X<span class="br0">&#41;</span>:
        <span style="color: #808080;"># permet d'&eacute;valuer le polyn&ocirc;me d'interpolation de Lagrange en fonction de X et des valeurs de x et y</span>
&nbsp;
        <span style="color: #808080;"># initialisation de la variable Lx</span>
        Lx = <span style="color: #cc66cc;">0</span>
&nbsp;
        <span style="color: #808080;"># parcours des y</span>
        <span style="color: #0000ff;">for</span> j <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span>len<span class="br0">&#40;</span>self.y<span class="br0">&#41;</span><span class="br0">&#41;</span>:
            lj = <span style="color: #cc66cc;">1</span>
            <span style="color: #808080;"># parcours des x</span>
            <span style="color: #0000ff;">for</span> i <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span>len<span class="br0">&#40;</span>self.x<span class="br0">&#41;</span><span class="br0">&#41;</span>:
                <span style="color: #0000ff;">if</span> i!=j:
                    lj *= <span class="br0">&#40;</span>X - self.x<span class="br0">&#91;</span>i<span class="br0">&#93;</span><span class="br0">&#41;</span>/<span class="br0">&#40;</span>self.x<span class="br0">&#91;</span>j<span class="br0">&#93;</span> - self.x<span class="br0">&#91;</span>i<span class="br0">&#93;</span><span class="br0">&#41;</span>
            <span style="color: #808080;"># ajour de la valeur de lj*y[j] &agrave; Lx</span>
            Lx +=self.y<span class="br0">&#91;</span>j<span class="br0">&#93;</span>*lj
&nbsp;
        <span style="color: #808080;"># renvoie la valeur de Lx</span>
        <span style="color: #0000ff;">return</span> Lx</pre></td></tr></table></pre>
</div><br />
Testons maintenant cette méthode :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:132px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="26"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #808080;"># cr&eacute;ation de l'objet de la classe Polynome_lagrange :</span>
p = Polynome_lagrange<span class="br0">&#40;</span>x=<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span>, <span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">2</span><span class="br0">&#93;</span>,y=<span class="br0">&#91;</span><span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">2</span>, <span style="color: #cc66cc;">5</span><span class="br0">&#93;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># valeur de x</span>
x = <span style="color: #cc66cc;">2</span> 
&nbsp;
<span style="color: #808080;"># &eacute;valuation de p(x)</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;p({0}) = &quot;</span>.format<span class="br0">&#40;</span>x<span class="br0">&#41;</span> + str<span class="br0">&#40;</span>p<span class="br0">&#40;</span>x<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
Le code affiche :<br />
<br />
<span class="highlight"><font color="#000000">p(2) = 5.0</font></span><br />
<br />
<br />
<b>IV-B. Module complet</b><br />
<br />
On donne pour finir le code complet du module contenant la classe Polynome_lagrange :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="40"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br />50<br />51<br />52<br />53<br />54<br />55<br />56<br />57<br />58<br />59<br />60<br />61<br />62<br />63<br />64<br />65<br />66<br />67<br />68<br />69<br />70<br />71<br />72<br />73<br />74<br />75<br />76<br />77<br />78<br />79<br />80<br />81<br />82<br />83<br />84<br />85<br />86<br />87<br />88<br />89<br />90<br />91<br />92<br />93<br />94<br />95<br />96<br />97<br />98<br />99<br />100<br />101<br />102<br />103<br />104<br />105<br />106<br />107<br />108<br />109<br />110<br />111<br />112<br />113<br />114<br />115<br />116<br />117<br />118<br />119<br />120<br />121<br />122<br />123<br />124<br />125<br />126<br />127<br />128<br />129<br />130<br />131<br />132<br />133<br />134<br />135<br />136<br />137<br />138<br />139<br />140<br />141<br />142<br />143<br />144<br />145<br />146<br />147<br />148<br />149<br />150<br />151<br />152<br />153<br />154<br />155<br />156<br />157<br />158<br />159<br />160<br />161<br />162<br />163<br />164<br />165<br />166<br />167<br />168<br />169<br />170<br />171<br />172<br />173<br />174<br />175<br />176<br />177<br />178<br />179<br />180<br />181<br />182<br />183<br />184<br />185<br />186<br />187<br />188<br />189<br />190<br />191<br />192<br />193<br />194<br />195<br />196<br />197<br />198<br />199<br />200<br />201<br />202<br />203<br />204<br />205<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">import</span> numpy <span style="color: #0000ff;">as</span> np
&nbsp;
<span style="color: #0000ff;">class</span> Polynome_lagrange<span class="br0">&#40;</span><span class="br0">&#41;</span>:
&nbsp;
    <span style="color: #0000ff;">def</span> <span style="color: #0080ff;">__init__</span><span class="br0">&#40;</span>self, x, y<span class="br0">&#41;</span>:
        <span style="color: #808080;"># m&eacute;thode constructeur de la classe</span>
&nbsp;
        <span style="color: #808080;"># on d&eacute;finit la liste de valeurs en x permettant d'obtenir la famille de polyn&ocirc;mes (l0, l1, ..., ln) repr&eacute;sentant une base dans &#8477;n[X]</span>
        self.x = x
&nbsp;
        <span style="color: #808080;"># on d&eacute;finit le tableau de valeurs en y repr&eacute;sentant les coordonn&eacute;es du vecteur (tableau numpy)</span>
        self.y = np.array<span class="br0">&#40;</span>y<span class="br0">&#41;</span>
&nbsp;
&nbsp;
    <span style="color: #0000ff;">def</span> __str__<span class="br0">&#40;</span>self<span class="br0">&#41;</span>:
        <span style="color: #808080;"># permet d'afficher le polyn&ocirc;me sous la forme y0*L0(X) + ... + yn*Ln(X)</span>
&nbsp;
        Lx = <span style="color: #FF0000;">''</span>
        <span style="color: #808080;"># parcours des y</span>
        <span style="color: #0000ff;">for</span> j <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span>len<span class="br0">&#40;</span>self.y<span class="br0">&#41;</span><span class="br0">&#41;</span>:
            Lx +=  str<span class="br0">&#40;</span>self.y<span class="br0">&#91;</span>j<span class="br0">&#93;</span><span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot;&#8729;L&quot;</span> + str<span class="br0">&#40;</span>j<span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot;(X)&quot;</span> + <span style="color: #FF0000;">&quot; + &quot;</span>
&nbsp;
        <span style="color: #0000ff;">return</span> Lx<span class="br0">&#91;</span>:-<span style="color: #cc66cc;">3</span><span class="br0">&#93;</span>    
&nbsp;
    <span style="color: #0000ff;">def</span> espace<span class="br0">&#40;</span>self<span class="br0">&#41;</span>:
        <span style="color: #808080;"># retourne l'espace vectoriel du polyn&ocirc;me self : R2[X]</span>
&nbsp;
        n = len<span class="br0">&#40;</span>self.x<span class="br0">&#41;</span>-<span style="color: #cc66cc;">1</span>
&nbsp;
        <span style="color: #808080;"># retourne l'espace vectoriel du polyn&ocirc;me d'interpolation de Lagrange</span>
        <span style="color: #0000ff;">return</span> <span style="color: #FF0000;">&quot;&#8477;{0}[X]&quot;</span>.format<span class="br0">&#40;</span>n<span class="br0">&#41;</span>
&nbsp;
&nbsp;
    <span style="color: #0000ff;">def</span> base<span class="br0">&#40;</span>self<span class="br0">&#41;</span>:
        <span style="color: #808080;"># retourne la base de polyn&ocirc;mes de self : (L0, L1, L2), x = [0, 1, 2]</span>
&nbsp;
        n = len<span class="br0">&#40;</span>self.x<span class="br0">&#41;</span>-<span style="color: #cc66cc;">1</span>
        base = <span style="color: #FF0000;">&quot;&quot;</span> 
&nbsp;
        <span style="color: #808080;"># parcours des indices des polyn&ocirc;mes de lagrange Li</span>
        <span style="color: #0000ff;">for</span> i <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span>n+<span style="color: #cc66cc;">1</span><span class="br0">&#41;</span>:
            base += <span style="color: #FF0000;">&quot;L&quot;</span> + str<span class="br0">&#40;</span>i<span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot;, &quot;</span>
&nbsp;
        <span style="color: #808080;"># cr&eacute;ation de la famille : (L0, L1, L2)</span>
        base = <span style="color: #FF0000;">&quot;(&quot;</span> + base<span class="br0">&#91;</span>:-<span style="color: #cc66cc;">2</span><span class="br0">&#93;</span> + <span style="color: #FF0000;">&quot;)&quot;</span>
&nbsp;
        <span style="color: #808080;"># retourne la base du polyn&ocirc;me d'interpolation de Lagrange</span>
        <span style="color: #0000ff;">return</span> <span style="color: #FF0000;">&quot;{0}, x = {1}&quot;</span>.format<span class="br0">&#40;</span>base, self.x<span class="br0">&#41;</span>
&nbsp;
&nbsp;
&nbsp;
    <span style="color: #0000ff;">def</span> <span style="color: #0080ff;">__add__</span><span class="br0">&#40;</span>self, other<span class="br0">&#41;</span>:
        <span style="color: #808080;"># m&eacute;thode permettant de red&eacute;finir l'op&eacute;rateur &laquo; + &raquo; pour 2 polyn&ocirc;mes d'interpolation de Lagrange ou 2 vecteurs</span>
        <span style="color: #808080;"># (y0*L0(X) + ... + yn*Ln(X)) + (z0*L0(X) + ... + zn*Ln(X)) = (y0 + z0)*L0(X) + ... + (yn + zn)*Ln(X)</span>
&nbsp;
        <span style="color: #808080;"># si les 2 vecteurs self et other ont la m&ecirc;me base</span>
        <span style="color: #0000ff;">if</span> self.x==other.x:
&nbsp;
            <span style="color: #808080;"># addition des 2 vecteurs self.y et other.y (2 tableaux numpy)</span>
            y = self.y + other.y
&nbsp;
            <span style="color: #808080;"># renvoie le polyn&ocirc;mes r&eacute;sultat de l'addition des 2 polyn&ocirc;mes self et other</span>
            <span style="color: #0000ff;">return</span> Polynome_lagrange<span class="br0">&#40;</span>self.x, y<span class="br0">&#41;</span>
&nbsp;
        <span style="color: #0000ff;">else</span>: <span style="color: #808080;"># sinon</span>
&nbsp;
            <span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Les 2 polyn&ocirc;mes n'ont pas la m&ecirc;me base !&quot;</span><span class="br0">&#41;</span>
&nbsp;
&nbsp;
    <span style="color: #0000ff;">def</span> <span style="color: #0080ff;">__mul__</span><span class="br0">&#40;</span>self, s<span class="br0">&#41;</span>:
        <span style="color: #808080;"># m&eacute;thode permettant de multiplier le polyn&ocirc;me self par un scalaire</span>
        <span style="color: #808080;"># : s*(y0*L0(X) + ... + yn*Ln(X)) = s*y0*L0(X) + ... + s*yn*Ln(X)</span>
&nbsp;
        <span style="color: #808080;"># multiplication du vecteur self.y par le scalaire s</span>
        y = s*self.y
&nbsp;
        <span style="color: #808080;"># renvoie le polyn&ocirc;me d'interpolation de Lagrange r&eacute;sultat de la multiplication de self par le scalaire s</span>
        <span style="color: #0000ff;">return</span> Polynome_lagrange<span class="br0">&#40;</span>self.x, y<span class="br0">&#41;</span>
&nbsp;
&nbsp;
    <span style="color: #0000ff;">def</span> <span style="color: #0080ff;">__eq__</span><span class="br0">&#40;</span>self, other<span class="br0">&#41;</span>:
        <span style="color: #808080;"># m&eacute;thode permettant de red&eacute;finir l'op&eacute;rateur &laquo; == &raquo; pour 2 polyn&ocirc;mes d'interpolation de Lagrange</span>
&nbsp;
        <span style="color: #808080;"># renvoie True si les bases et les listes de coordonn&eacute;es des vecteurs sont identiques</span>
        <span style="color: #0000ff;">return</span> <span class="br0">&#40;</span>self.x==other.x<span class="br0">&#41;</span> <span style="color: #0000ff;">and</span> np.array_equal<span class="br0">&#40;</span>self.y,other.y<span class="br0">&#41;</span>
&nbsp;
&nbsp;
    <span style="color: #0000ff;">def</span> <span style="color: #0080ff;">__call__</span><span class="br0">&#40;</span>self, X<span class="br0">&#41;</span>:
        <span style="color: #808080;"># permet d'&eacute;valuer le polyn&ocirc;me d'interpolation de Lagrange en fonction de X et des valeurs de x et y</span>
&nbsp;
        <span style="color: #808080;"># initialisation de la variable Lx</span>
        Lx = <span style="color: #cc66cc;">0</span>
&nbsp;
        <span style="color: #808080;"># parcours des y</span>
        <span style="color: #0000ff;">for</span> j <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span>len<span class="br0">&#40;</span>self.y<span class="br0">&#41;</span><span class="br0">&#41;</span>:
            lj = <span style="color: #cc66cc;">1</span>
            <span style="color: #808080;"># parcours des x</span>
            <span style="color: #0000ff;">for</span> i <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span>len<span class="br0">&#40;</span>self.x<span class="br0">&#41;</span><span class="br0">&#41;</span>:
                <span style="color: #0000ff;">if</span> i!=j:
                    lj *= <span class="br0">&#40;</span>X - self.x<span class="br0">&#91;</span>i<span class="br0">&#93;</span><span class="br0">&#41;</span>/<span class="br0">&#40;</span>self.x<span class="br0">&#91;</span>j<span class="br0">&#93;</span> - self.x<span class="br0">&#91;</span>i<span class="br0">&#93;</span><span class="br0">&#41;</span>
            <span style="color: #808080;"># ajour de la valeur de lj*y[j] &agrave; Lx</span>
            Lx +=self.y<span class="br0">&#91;</span>j<span class="br0">&#93;</span>*lj
&nbsp;
        <span style="color: #808080;"># renvoie la valeur de Lx</span>
        <span style="color: #0000ff;">return</span> Lx
&nbsp;
&nbsp;
<span style="color: #808080;"># addition de 2 polyn&ocirc;mes</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;I-A. Addition de 2 polyn&ocirc;mes d'interpolation de Lagrange<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># cr&eacute;ation du 1er objet de la classe Polynome_lagrange</span>
p1 = Polynome_lagrange<span class="br0">&#40;</span>x=<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span>, <span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">2</span><span class="br0">&#93;</span>, y=<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span>, <span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">4</span><span class="br0">&#93;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># cr&eacute;ation du 2e objet de la classe Polynome_lagrange</span>
p2 = Polynome_lagrange<span class="br0">&#40;</span>x=<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span>, <span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">2</span><span class="br0">&#93;</span>, y=<span class="br0">&#91;</span><span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">2</span>, <span style="color: #cc66cc;">5</span><span class="br0">&#93;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche l'expression des polyn&ocirc;mes p1 et p2</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;p1 = &quot;</span> + str<span class="br0">&#40;</span>p1<span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;p2 = &quot;</span> + str<span class="br0">&#40;</span>p2<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche l'appartenance de p1 et p2 &agrave; leur espace vectoriel : R2[X], Base = [L0, L1, L2], x = [0, 1, 2]</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;p1 &isin; &quot;</span> + p1.espace<span class="br0">&#40;</span><span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot;, Base = &quot;</span> + p1.base<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;p2 &isin; &quot;</span> + p1.espace<span class="br0">&#40;</span><span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot;, Base = &quot;</span> + p2.base<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;p = p1 + p2&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># addition des 2 polyn&ocirc;mes</span>
p = p1 + p2
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche le r&eacute;sultat de l'addition</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;p = &quot;</span> + str<span class="br0">&#40;</span>p<span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche l'appartenance de p &agrave; son espace vectoriel</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;p &isin; &quot;</span> + p.espace<span class="br0">&#40;</span><span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot;, Base = &quot;</span> + p.base<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># multiplication d'un polyn&ocirc;me par un scalaire</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;I-B. Multiplication d'un polyn&ocirc;me d'interpolation de Lagrange par un scalaire<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># cr&eacute;ation de l'objet de la classe Polynome_lagrange :</span>
p1 = Polynome_lagrange<span class="br0">&#40;</span>x=<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span>, <span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">2</span><span class="br0">&#93;</span>, y=<span class="br0">&#91;</span><span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">2</span>, <span style="color: #cc66cc;">5</span><span class="br0">&#93;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche l'expression du polyn&ocirc;me p1</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;p1 = &quot;</span> + str<span class="br0">&#40;</span>p1<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche l'appartenance de p1 &agrave; son espace vectoriel</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;p1 &isin; &quot;</span> + p1.espace<span class="br0">&#40;</span><span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot;, Base = &quot;</span> + p1.base<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># d&eacute;finition du scalaire s</span>
s = <span style="color: #cc66cc;">2</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;s = &quot;</span> + str<span class="br0">&#40;</span>s<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;p = p1*s &quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># multiplication du polyn&ocirc;me p1 par le scalaire s</span>
p = p1*s
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche le r&eacute;sultat de la multiplication de p1 par s</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;p = &quot;</span> + str<span class="br0">&#40;</span>p<span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche l'appartenance de p &agrave; son espace vectoriel</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;p &isin; &quot;</span> + p.espace<span class="br0">&#40;</span><span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot;, Base = &quot;</span> + p.base<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;I-C. &Eacute;valuation d'un polyn&ocirc;me d'interpolation de Lagrange<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># cr&eacute;ation de l'objet de la classe Polynome_lagrange :</span>
p = Polynome_lagrange<span class="br0">&#40;</span>x=<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span>, <span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">2</span><span class="br0">&#93;</span>,y=<span class="br0">&#91;</span><span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">2</span>, <span style="color: #cc66cc;">5</span><span class="br0">&#93;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche l'expression du polyn&ocirc;mes p</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;p = &quot;</span> + str<span class="br0">&#40;</span>p<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche l'appartenance de p &agrave; son espace vectoriel</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;p &isin; &quot;</span> + p.espace<span class="br0">&#40;</span><span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot;, Base = &quot;</span> + p.base<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># d&eacute;finition de la valeur de x</span>
x = <span style="color: #cc66cc;">2</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># &eacute;valuation de p(x)</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;p({0}) = &quot;</span>.format<span class="br0">&#40;</span>x<span class="br0">&#41;</span> + str<span class="br0">&#40;</span>p<span class="br0">&#40;</span>x<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
<u>Note :</u> la librairie scipy propose également une classe <a href="https://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.lagrange.html" target="_blank">lagrange</a> permettant de définir ce type de polynôme.<br />
<br />
<br />
<br />
<b>V. Conclusion</b><br />
<br />
Comme on a pu le montrer, l'ensemble des polynômes construits sur la base des polynômes de Lagrange <b>(l<sub>0</sub>, l<sub>1</sub>, …, l<sub>n</sub>)</b> constitue donc un espace vectoriel muni de lois de composition interne et externe, à savoir l'addition et la multiplication par un scalaire. <br />
<br />
Les éléments de cet espace peuvent facilement être représentés en Python afin de pouvoir ensuite réaliser des opérations entre ces objets mathématiques comme on le ferait sur des vecteurs.<br />
<br />
On peut bien sûr imaginer de construire l'ensemble <b>&#8477;<sub>n</sub>[X]</b> des polynômes sur la base usuelle des monômes <b>X<sup>n</sup></b>.<br />
<br />
<br />
<b>Sources :</b><br />
<br />
<a href="https://fr.wikipedia.org/wiki/Espace_vectoriel" target="_blank">https://fr.wikipedia.org/wiki/Espace_vectoriel</a><br />
<a href="https://fr.wikipedia.org/wiki/Corps_commutatif" target="_blank">https://fr.wikipedia.org/wiki/Corps_commutatif</a><br />
<a href="https://fr.wikipedia.org/wiki/Loi_de_composition" target="_blank">https://fr.wikipedia.org/wiki/Loi_de_composition</a><br />
<a href="https://fr.wikipedia.org/wiki/Base_(alg%C3%A8bre_lin%C3%A9aire)" target="_blank">https://fr.wikipedia.org/wiki/Base_(...lin%C3%A9aire)</a><br />
<a href="https://fr.wikipedia.org/wiki/Combinaison_lin%C3%A9aire" target="_blank">https://fr.wikipedia.org/wiki/Combinaison_lin%C3%A9aire</a><br />
<a href="https://fr.wikipedia.org/wiki/Interpolation_lagrangienne" target="_blank">https://fr.wikipedia.org/wiki/Interp...n_lagrangienne</a><br />
<a href="https://pyspc.readthedocs.io/fr/latest/05-bases/08-tableaux_numpy.html" target="_blank">https://pyspc.readthedocs.io/fr/late...aux_numpy.html</a></font></blockquote>

]]></content:encoded>
			<dc:creator>User</dc:creator>
			<guid isPermaLink="true">https://www.developpez.net/forums/blogs/44027-user/b10590/calcul-formel-python-polynomes-d-interpolation-lagrange-vus-vecteurs/</guid>
		</item>
		<item>
			<title><![CDATA[Calcul formel en Python : étendre les opérations sur les nombres entiers à d'autres objets mathématiques]]></title>
			<link>https://www.developpez.net/forums/blogs/44027-user/b10581/calcul-formel-python-etendre-operations-nombres-entiers-d-autres-objets-mathematiques/</link>
			<pubDate>Mon, 04 Mar 2024 07:11:12 GMT</pubDate>
			<description>*I. Introduction* 
 
On...</description>
			<content:encoded><![CDATA[<blockquote class="blogcontent restore"><font size="3"><b>I. Introduction</b><br />
<br />
On souhaite étendre les opérations d'addition et de multiplication effectuées sur les nombres entiers à d'autres objets mathématiques représentant les éléments d'un anneau.<br />
<br />
D'après Wikipedia, en algèbre, un <a href="https://fr.wikipedia.org/wiki/Anneau_(math%C3%A9matiques)" target="_blank">anneau</a> est un ensemble muni de deux <a href="https://fr.wikipedia.org/wiki/Loi_de_composition_interne" target="_blank">lois de composition interne</a> appelées addition et multiplication, qui vérifient des propriétés analogues à celles de ces opérations sur les entiers relatifs.<br />
<br />
Une loi de composition interne est une application qui, à deux éléments d'un ensemble <b>E</b>, associe un élément de <b>E</b>, comme la multiplication ou l'addition dans l'ensemble des naturels.<br />
<br />
On va d'abord montrer brièvement dans ce billet que l'ensemble des nombres complexes et celui des polynômes sont des anneaux.<br />
<br />
Dans un second temps, on va représenter les éléments de ces ensembles à l'aide de classes en Python, puis définir les opérations d'addition et de multiplication entre ces objets mathématiques en utilisant la <a href="https://docs.python.org/fr/3/reference/datamodel.html#emulating-numeric-types" target="_blank">surcharge d'opérateur</a>.<br />
<br />
Enfin, on va tester le code Python en effectuant différentes opérations sur ces nouveaux objets un peu comme on le ferait sur des nombres entiers.<br />
<br />
<br />
<br />
<b>II. Exemples d'anneaux</b><br />
<br />
De façon plus détaillée, un anneau est un ensemble <b>E</b> dans lequel sont données deux lois de composition interne, notées <b>+</b> et <b>×</b>, vérifiant les propriétés suivantes :<br />
<br />
<ol class="decimal"><li style="">La loi <b>+</b> est associative : pour tous <span class="highlight">a, b, c &#8712; E, a + (b + c) = (a + b) + c</span> ;</li><li style="">La loi <b>+</b> est commutative : pour tous <span class="highlight">a, b &#8712; E, a + b = b + a</span> ;</li><li style="">La loi <b>+</b> possède un élément neutre ;</li><li style="">La loi <b>×</b> est associative : pour tous <span class="highlight">a, b, c &#8712; E, a × (b × c) = (a × b) × c</span> ;</li><li style="">La loi <b>×</b> est distributive par rapport à la loi <b>+</b> : pour tout <span class="highlight">a, b, c &#8712; E</span>, on a <span class="highlight">a × (b + c) = a × b + a × c</span> et <span class="highlight">(b + c) × a = b × a + c × a</span> ;</li><li style="">La loi <b>×</b> possède un élément neutre ;</li><li style="">Tout élément <b>a</b> appartenant à l'ensemble <b>E</b> possède un opposé, noté <b>–a</b>.</li></ol><br />
<u>Note :</u> si on veut être précis, on devrait plutôt parler d'<a href="https://fr.wikipedia.org/wiki/Anneau_unitaire" target="_blank">anneau unitaire</a>.<br />
<br />
<br />
Nous allons donc le vérifier maintenant sur deux exemples.<br />
<br />
<br />
<b>II-A. Ensemble &#8450; des nombres complexes</b><br />
<br />
<img src="https://www.developpez.net/forums/attachments/p651319d1708854522/bases-donnees/firebird/sql/alterer-col-null-not-null-int/ensemble_complexes.png/" border="0" alt="Nom : ensemble_complexes.png
Affichages : 17060
Taille : 4,7 Ko"  style="float: CONFIG" /><br />
<br />
En mathématiques, l'ensemble des <a href="https://fr.wikipedia.org/wiki/Nombre_complexe" target="_blank">nombres complexes</a>, noté <b>&#8450;</b>, est créé comme extension de l'ensemble des nombres réels, contenant en particulier un nombre imaginaire noté <b>i</b>, tel que <b>i<sup>2</sup> = &#8722;1</b>. Le carré de <b>(&#8722;i)</b> est aussi égal à <b>&#8722;1</b> : <b>(&#8722;i)<sup>2</sup> = &#8722;1</b>.<br />
<br />
Tout nombre complexe peut s'écrire sous la forme <b>a + ib</b> où <b>a</b> et <b>b</b> sont des nombres réels.<br />
<br />
<b>II-A-1. Addition de nombres complexes</b><br />
<br />
L'addition de <b>2</b> nombres complexes <b>z<sub>1</sub> = a + ib</b> et <b>z<sub>2</sub> = c + id</b> écrits sous forme algébrique, est définie de la manière suivante :<br />
<br />
<span class="highlight">(a + ib) + (c + id) = (a+b) + i(b+d)</span><br />
<br />
Le résultat donne également un nombre complexe et cette opération est donc bien une loi de composition interne dans <b>&#8450;</b>.<br />
<br />
Soient maintenant les trois nombres complexes <b>z<sub>1</sub></b>, <b>z<sub>2</sub></b> et <b>z<sub>3</sub></b><br />
<br />
<b>1) Associativité</b><br />
<br />
On vérifie facilement en utilisant l'égalité précédente la propriété d'associativité de l'addition de nombres complexes :<br />
<br />
<span class="highlight">z<sub>1</sub> + (z<sub>2</sub> + z<sub>3</sub>) = (z<sub>1</sub> + z<sub>2</sub>) + z<sub>3</sub></span><br />
<br />
<br />
<b>2)</b> et <b>3)</b> On peut montrer également que l'addition est commutative et que le complexe nul est l'élément neutre pour l'addition dans <b>&#8450;</b>.<br />
<br />
<br />
<b>II-A-2. Multiplication de nombres complexes</b><br />
<br />
La multiplication de <b>2</b> nombres complexes <b>z<sub>1</sub> = a + ib</b> et <b>z<sub>2</sub> = c + id</b>, est définie par :<br />
<br />
<span class="highlight">(a + ib) × (c + id) = (ac - bd) + i(ad + bc)</span><br />
<br />
Le résultat de la multiplication de deux nombres complexes donne aussi un nombre complexe et cette opération est donc bien une loi de composition interne dans <b>&#8450;</b>.<br />
<br />
<br />
Soient maintenant les nombres complexes <b>z<sub>1</sub></b>, <b>z<sub>2</sub></b> et <b>z<sub>3</sub></b><br />
<br />
<b>4) Associativité</b><br />
<br />
On vérifie facilement en utilisant l'égalité précédente la propriété d'associativité de la multiplication :<br />
<br />
<span class="highlight">z<sub>1</sub> × (z<sub>2</sub> × z<sub>3</sub>) = (z<sub>1</sub> × z<sub>2</sub>) × z<sub>3</sub></span><br />
<br />
<br />
<b>5) Distributivité par rapport à l'addition</b><br />
<br />
De même, on vérifie aisément la propriété de distributivité de la multiplication par rapport à l'addition :<br />
<br />
<span class="highlight">z<sub>1</sub> × (z<sub>2</sub> + z<sub>3</sub>) = z<sub>1</sub> × z<sub>2</sub> + z<sub>1</sub> × z<sub>3</sub></span><br />
<br />
<span class="highlight">(z<sub>2</sub> + z<sub>3</sub>) × z<sub>1</sub> = z<sub>2</sub> × z<sub>1</sub> + z<sub>3</sub> × z<sub>1</sub></span><br />
<br />
<br />
<b>6)</b> et <b>7)</b> On peut montrer enfin que le nombre <b>1</b> est l'élément neutre pour la multiplication dans <b>&#8450;</b> et que tout élément de cet ensemble possède un opposé.<br />
<br />
<br />
En conclusion, les opérations d'addition et de multiplication sont des lois de composition interne dans l'ensemble <b>&#8450;</b> qui vérifient des propriétés analogues à celles de ces opérations sur les entiers relatifs.<br />
<br />
Par conséquent l'ensemble <b>&#8450;</b> constitue un anneau.<br />
<br />
<br />
<b>II-B. Ensemble &#8477;[X] des polynômes</b><br />
<br />
<img src="https://www.developpez.net/forums/attachments/p651320d1708854549/bases-donnees/firebird/sql/alterer-col-null-not-null-int/ensemble_polynomes.png/" border="0" alt="Nom : ensemble_polynomes.png
Affichages : 5132
Taille : 6,4 Ko"  style="float: CONFIG" /><br />
<br />
En mathématiques, un <a href="https://fr.wikipedia.org/wiki/Polyn%C3%B4me" target="_blank">polynôme</a> de la variable <b>X</b> peut s'écrire sous la forme :<br />
<br />
<span class="highlight">P(X) = a<sub>0</sub> + a<sub>1</sub>X + ... + a<sub>n-1</sub>X<sup>n-1</sup> + a<sub>n</sub>X<sup>n</sup></span><br />
<br />
Où <b>X</b> est une variable appelée indéterminée (dans notre cas un réel), les constantes <b>a<sub>0</sub>, a<sub>1</sub>, ..., a<sub>n</sub></b> sont les coefficients réels du polynôme et <b>n</b> est un entier naturel.<br />
<br />
<br />
<b>II-B-1. Addition de polynômes</b><br />
<br />
Soient <b>2</b> polynômes de la forme :<br />
<br />
<span class="highlight">P<sub>1</sub>(X) = a<sub>0</sub> + a<sub>1</sub>X + ... + a<sub>n-1</sub>X<sup>n-1</sup> + a<sub>n</sub>X<sup>n</sup></span><br />
<span class="highlight">P<sub>2</sub>(X) = b<sub>0</sub> + b<sub>1</sub>X + ... + b<sub>m-1</sub>X<sup>m-1</sup> + b<sub>n</sub>X<sup>m</sup></span><br />
<br />
<br />
L'addition de ces <b>2</b> polynômes <b>P<sub>1</sub>(X)</b> et <b>P<sub>2</sub>(X)</b> donne pour <b>n=m</b> :<br />
<br />
<span class="highlight">P<sub>1</sub>(X) + P<sub>2</sub>(X) = (a<sub>0</sub> + b<sub>0</sub>) + (a<sub>1</sub> + b<sub>1</sub>)X + ... + (a<sub>n-1</sub> + b<sub>n-1</sub>)X<sup>n-1</sup> + (a<sub>n</sub> + b<sub>n</sub>)X<sup>n</sup></span><br />
<br />
Et pour <b>n&gt;m</b> :<br />
<br />
<span class="highlight">P<sub>1</sub>(X) + P<sub>2</sub>(X) = (a<sub>0</sub> + b<sub>0</sub>) + (a<sub>1</sub> + b<sub>1</sub>)X + ... + (a<sub>m-1</sub> + b<sub>m-1</sub>)X<sup>m-1</sup> + (a<sub>m</sub> + b<sub>m</sub>)X<sup>m</sup> + ... + a<sub>n</sub>X<sup>n</sup></span><br />
<br />
On additionne donc simplement les coefficients de même degré et on obtient donc un troisième polynôme.<br />
<br />
Par conséquent, cette opération est bien une loi de composition interne dans <b>&#8477;[X]</b>.<br />
<br />
<br />
Soient maintenant les trois polynômes <b>P<sub>1</sub></b>, <b>P<sub>2</sub></b> et <b>P<sub>3</sub></b><br />
<br />
<b>1) Associativité</b><br />
<br />
On vérifie facilement en utilisant le résultat précédent la propriété d'associativité de l'addition de polynômes :<br />
<br />
<span class="highlight">P<sub>1</sub> + (P<sub>2</sub> + P<sub>3</sub>) = (P<sub>1</sub> + P<sub>2</sub>) + P<sub>3</sub></span><br />
<br />
<br />
<b>2)</b> et <b>3)</b> On peut montrer également que l'addition est commutative et que le polynôme nul est l'élément neutre pour l'addition dans <b>&#8477;[X]</b>.<br />
<br />
<br />
<b>II-B-2. Multiplication de polynômes</b><br />
<br />
Soient <b>2</b> polynômes de degré <b>1</b> :<br />
<br />
<span class="highlight">P<sub>1</sub>(X) = a<sub>0</sub> + a<sub>1</sub>X</span><br />
<span class="highlight">P<sub>2</sub>(X) = b<sub>0</sub> + b<sub>1</sub>X</span><br />
<br />
La multiplication étant distributive par rapport à l'addition, le produit de ces <b>2</b> polynômes <b>P<sub>1</sub>(X)</b> et <b>P<sub>2</sub>(X)</b> nous donne :<br />
<br />
<span class="highlight">P<sub>1</sub>(X) <font size="1">X</font> P<sub>2</sub>(X) = (a<sub>0</sub> + a<sub>1</sub>X)(b<sub>0</sub> + b<sub>1</sub>X)</span><br />
<span class="highlight">P<sub>1</sub>(X) <font size="1">X</font> P<sub>2</sub>(X) = a<sub>0</sub>b<sub>0</sub> + a<sub>0</sub>b<sub>1</sub>X + a<sub>1</sub>b<sub>0</sub>X + a<sub>1</sub>b<sub>1</sub>X<sup>2</sup></span><br />
<br />
On obtient donc à nouveau un troisième polynôme, et on peut ainsi généraliser facilement ce résultat à des polynômes de degrés quelconques.<br />
<br />
Par conséquent, cette opération est bien une loi de composition interne dans <b>&#8477;[X]</b>.<br />
<br />
<br />
Soient maintenant les polynômes <b>P<sub>1</sub></b>, <b>P<sub>2</sub></b> et <b>P<sub>3</sub></b><br />
<br />
<b>4) Associativité</b><br />
<br />
On vérifie facilement en utilisant le résultat précédent la propriété d'associativité de la multiplication :<br />
<br />
<span class="highlight">P<sub>1</sub> × (P<sub>2</sub> × P<sub>3</sub>) = (P<sub>1</sub> × P<sub>2</sub>) × P<sub>3</sub></span><br />
<br />
<br />
<b>5) Distributivité par rapport à l'addition</b><br />
<br />
De même, on vérifie aisément la propriété de distributivité de la multiplication de polynômes par rapport à l'addition :<br />
<br />
<span class="highlight">P<sub>1</sub> × (P<sub>2</sub> + P<sub>3</sub>) = P<sub>1</sub> × P<sub>2</sub> + P<sub>1</sub> × P<sub>3</sub></span><br />
<br />
<span class="highlight">(P<sub>2</sub> + P<sub>3</sub>) × P<sub>1</sub> = P<sub>2</sub> × P<sub>1</sub> + P<sub>3</sub> × P<sub>1</sub></span><br />
<br />
<br />
<b>6)</b> et <b>7)</b> On peut montrer enfin que le polynôme constant <b>1</b> est l'élément neutre pour la multiplication dans <b>&#8477;[X]</b> et que tout élément de cet ensemble possède un opposé.<br />
<br />
<br />
En conclusion, les opérations d'addition et de multiplication sont des lois de composition interne dans l'ensemble <b>&#8477;[X]</b> qui vérifient des propriétés analogues à celles de ces opérations sur les entiers relatifs.<br />
<br />
Par conséquent l'ensemble <b>&#8477;[X]</b> constitue un anneau.<br />
<br />
<br />
<br />
<b>III. Implémentation en Python</b><br />
<br />
Les opérations d'addition et de multiplication sur ces objets mathématiques ont donc des propriétés communes avec celles sur les nombres entiers, toutefois elles ont aussi leurs particularités et ne sont pas définies de la même manière (on parle dans ce cas de <a href="https://fr.wikipedia.org/wiki/Polymorphisme_(informatique)" target="_blank">polymorphisme</a>).<br />
<br />
On va maintenant représenter les nombres complexes et les polynômes à l'aide de classes en Python, puis définir les opérations d'addition et de multiplication entre ces objets mathématiques en utilisant la <a href="https://docs.python.org/fr/3/reference/datamodel.html#emulating-numeric-types" target="_blank">surcharge d'opérateur</a>.<br />
<br />
<br />
<b>III-A. Création de la classe Complexe</b><br />
<br />
Pour définir ces nombres complexes en <b>Python</b> et pouvoir réaliser des opérations entre eux, il nous faut créer une <a href="https://docs.python.org/fr/3/tutorial/classes.html" target="_blank">classe</a> Complexe :<br />
<br />
<img src="https://www.developpez.net/forums/attachments/p651443d1709052269/bases-donnees/firebird/sql/alterer-col-null-not-null-int/classe_complexe.png/" border="0" alt="Nom : classe_complexe.png
Affichages : 5099
Taille : 9,0 Ko"  style="float: CONFIG" /><br />
<br />
Notre classe comportera en plus une méthode particulière <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">__init__()</span> dont le code est exécuté quand la classe est instanciée. <br />
<br />
Elle va nous permettre de définir les parties réelle et imaginaire du nombre complexe au moment de créer l'objet : <br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">class</span> Complexe:
&nbsp;
    <span style="color: #0000ff;">def</span> <span style="color: #0080ff;">__init__</span><span class="br0">&#40;</span>self, part_reel=<span style="color: #cc66cc;">0</span>, part_imag=<span style="color: #cc66cc;">0</span><span class="br0">&#41;</span>:
        <span style="color: #808080;"># m&eacute;thode constructeur de la classe</span>
&nbsp;
        <span style="color: #808080;"># on d&eacute;finit la partie r&eacute;elle du nombre complexe</span>
        self.reel = part_reel
&nbsp;
        <span style="color: #808080;"># on d&eacute;finit la partie imaginaire du nombre complexe</span>
        self.imag = part_imag 
&nbsp;
    <span style="color: #0000ff;">def</span> __str__<span class="br0">&#40;</span>self<span class="br0">&#41;</span>: 
	<span style="color: #808080;"># permet d'afficher le nombre complexe sous la forme alg&eacute;brique a + bi</span>
&nbsp;
        <span style="color: #0000ff;">return</span> <span style="color: #FF0000;">&quot;{0} + {1}i&quot;</span>.format<span class="br0">&#40;</span>self.reel, self.imag<span class="br0">&#41;</span> <span style="color: #0000ff;">if</span> self.imag&gt;=<span style="color: #cc66cc;">0</span> <span style="color: #0000ff;">else</span> <span style="color: #FF0000;">&quot;{0} - {1}i&quot;</span>.format<span class="br0">&#40;</span>self.reel, abs<span class="br0">&#40;</span>self.imag<span class="br0">&#41;</span><span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
La méthode <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">__str__</span> permet d'afficher un nombre complexe sous la forme <b>a + bi</b>.<br />
<br />
Pour tester ces méthodes, nous ajoutons simplement deux lignes au module :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:60px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="26"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br /></div></td><td valign="top"><pre style="margin: 0">z = Complexe<span class="br0">&#40;</span><span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">2</span><span class="br0">&#41;</span> <span style="color: #808080;"># cr&eacute;ation de l'objet Complexe : 1 + 2i</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span>z<span class="br0">&#41;</span> <span style="color: #808080;"># affiche le nombre complexe</span></pre></td></tr></table></pre>
</div><br />
Le code affiche :<br />
<br />
<span class="highlight"><font color="#000000">1 + 2i</font></span><br />
<br />
<br />
<b>III-A-1. Surcharge de l'opérateur d'addition</b><br />
<br />
Pour <a href="https://docs.python.org/fr/3/reference/datamodel.html#emulating-numeric-types" target="_blank">surcharger l'opérateur</a> « <b>+</b> » et pouvoir ainsi réaliser l'addition de <b>2</b> nombres complexes, nous devons ajouter une méthode <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">__add __ ()</span> à la classe :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:192px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">class</span> Complexe: 
    ....
&nbsp;
    <span style="color: #0000ff;">def</span> <span style="color: #0080ff;">__add__</span><span class="br0">&#40;</span>self, other<span class="br0">&#41;</span>:
        <span style="color: #808080;"># m&eacute;thode permettant de red&eacute;finir l'op&eacute;rateur &laquo; + &raquo; pour 2 nombres complexes : z1 + z2 = (a + bi) + (c + di) = (a+c) + (b+d)i</span>
&nbsp;
        <span style="color: #808080;"># on &eacute;value la partie r&eacute;elle du nombre complexe r&eacute;sultat de l'addition</span>
        part_reel = self.reel + other.reel
&nbsp;
        <span style="color: #808080;"># on &eacute;value la partie imaginaire du nombre complexe r&eacute;sultat de l'addition</span>
        part_imag = self.imag + other.imag
&nbsp;
        <span style="color: #808080;"># renvoie le nombre complexe r&eacute;sultat de l'addition</span>
        <span style="color: #0000ff;">return</span> Complexe<span class="br0">&#40;</span>part_reel, part_imag<span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
Cette méthode permet donc de redéfinir l'opération « <b>+</b> » pour les nombres complexes en utilisant l'égalité : <br />
<br />
<span class="highlight">(a + bi) + (c + di) = (a+c) + (b+d)i </span><br />
<br />
<br />
Pour tester l'opérateur d'addition portant sur <b>2</b> objets de la classe Complexe, nous ajoutons ces lignes de code :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #808080;"># cr&eacute;ation du 1er objet de la classe Complexe : 1 + 2i</span>
z1 = Complexe<span class="br0">&#40;</span><span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">2</span><span class="br0">&#41;</span> 
&nbsp;
<span style="color: #808080;"># cr&eacute;ation de 2e objet Complexe : 2 + 3i</span>
z2 = Complexe<span class="br0">&#40;</span><span style="color: #cc66cc;">2</span>, <span style="color: #cc66cc;">3</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche l'appartenance de z1 et z2 &agrave; l'ensemble &#8450;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span>str<span class="br0">&#40;</span>z1<span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot; &isin; &quot;</span> + anneau<span class="br0">&#40;</span>z1<span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span>str<span class="br0">&#40;</span>z2<span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot; &isin; &quot;</span> + anneau<span class="br0">&#40;</span>z2<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># addition des 2 nombres complexes</span>
z = z1+z2
&nbsp;
<span style="color: #808080;"># affiche le r&eacute;sultat de l'addition</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;(&quot;</span> + str<span class="br0">&#40;</span>z1<span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot;)&quot;</span> + <span style="color: #FF0000;">&quot; + &quot;</span> + <span style="color: #FF0000;">&quot;(&quot;</span> + str<span class="br0">&#40;</span>z2<span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot;)&quot;</span> + <span style="color: #FF0000;">&quot; = &quot;</span> + str<span class="br0">&#40;</span>z<span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche l'appartenance de z &agrave; l'ensemble &#8450;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span>str<span class="br0">&#40;</span>z<span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot; &isin; &quot;</span> + anneau<span class="br0">&#40;</span>z<span class="br0">&#41;</span><span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
Le code affiche :<br />
<br />
<span class="highlight"><font color="#000000">1 + 2i &#8712; &#8450;<br />
2 + 3i &#8712; &#8450;<br />
<br />
(1 + 2i) + (2 + 3i) = 3 + 5i<br />
<br />
3 + 5i &#8712; &#8450;<br />
</font></span><br />
<br />
La fonction <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">anneau(element)</span> renvoie l'ensemble (&#8450;, &#8477;[X], etc.) auquel appartient l'élément, elle est présente dans le module donné à la fin du billet.<br />
<br />
<br />
On peut également vérifier la propriété d'associativité de l'addition :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br /></div></td><td valign="top"><pre style="margin: 0">...
<span style="color: #808080;"># cr&eacute;ation de 3e objet Complexe : 2 + 2i</span>
z3 = Complexe<span class="br0">&#40;</span><span style="color: #cc66cc;">2</span>, <span style="color: #cc66cc;">2</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche les nombres complexes z1, z2 et z2</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;z1 = &quot;</span> + str<span class="br0">&#40;</span>z1<span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;z2 = &quot;</span> + str<span class="br0">&#40;</span>z2<span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;z3 = &quot;</span> + str<span class="br0">&#40;</span>z3<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># v&eacute;rification de la propri&eacute;t&eacute; d'associativit&eacute; de l'addition dans &#8450;</span>
r1 = z1 + <span class="br0">&#40;</span>z2 + z3<span class="br0">&#41;</span>
r2 = <span class="br0">&#40;</span>z1 + z2<span class="br0">&#41;</span> + z3
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">if</span> r1==r2: <span style="color: #808080;"># si r1=r2</span>
    <span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;z1 + (z2 + z3) = (z1 + z2) + z3&quot;</span><span class="br0">&#41;</span> 
<span style="color: #0000ff;">else</span>:
    <span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;z1 + (z2 + z3) &ne; (z1 + z2) + z3&quot;</span><span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
Le code affiche :<br />
<br />
<span class="highlight"><font color="#000000">z1 = 1 + 2i<br />
z2 = 2 + 3i<br />
z3 = 2 + 2i<br />
<br />
z1 + (z2 + z3) = (z1 + z2) + z3<br />
</font></span><br />
<br />
<br />
<b>III-A-2. Surcharge de l'opérateur de multiplication</b><br />
<br />
Pour surcharger l'opérateur « <b>*</b> » et l'appliquer à <b>2</b> nombres complexes, nous devons également ajouter une méthode __mul __ () à la classe :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:192px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">class</span> Complexe: 
    ...
    <span style="color: #0000ff;">def</span> <span style="color: #0080ff;">__mul__</span><span class="br0">&#40;</span>self, other<span class="br0">&#41;</span>:
        <span style="color: #808080;"># m&eacute;thode permettant de red&eacute;finir l'op&eacute;rateur &laquo; * &raquo; pour 2 nombres complexes : z1 * z2 = (ac - bd) + (ad + bc)*i </span>
&nbsp;
        <span style="color: #808080;"># part_reel = (ac - bd)</span>
        part_reel = self.reel * other.reel - self.imag * other.imag
&nbsp;
        <span style="color: #808080;"># part_imag = (ad + bc)</span>
        part_imag = self.reel * other.imag + self.imag * other.reel
&nbsp;
        <span style="color: #808080;"># renvoie le nombre complexe r&eacute;sultat de la multiplication</span>
        <span style="color: #0000ff;">return</span> Complexe<span class="br0">&#40;</span>part_reel, part_imag<span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
Cette méthode offre donc la possibilité de redéfinir l'opération de multiplication pour <b>2</b> nombres complexes en utilisant l'égalité : <br />
<br />
<span class="highlight">(a + bi) x (c + di) = (ac - bd) + (ad + bc)i</span><br />
<br />
<br />
Pour tester l'opérateur de multiplication portant sur <b>2</b> objets de la classe <b>Complexe</b>, nous ajoutons ces lignes :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #808080;"># cr&eacute;ation du 1er objet de la classe Complexe : 1 + 2i</span>
z1 = Complexe<span class="br0">&#40;</span><span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">2</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># cr&eacute;ation du 2e objet de la classe Complexe : 2 + 3i</span>
z2 = Complexe<span class="br0">&#40;</span><span style="color: #cc66cc;">2</span>, <span style="color: #cc66cc;">3</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche l'appartenance de z1 et z2 &agrave; l'ensemble &#8450;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span>str<span class="br0">&#40;</span>z1<span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot; &isin; &quot;</span> + anneau<span class="br0">&#40;</span>z1<span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span>str<span class="br0">&#40;</span>z2<span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot; &isin; &quot;</span> + anneau<span class="br0">&#40;</span>z2<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># produit des 2 nombres complexes</span>
z = z1*z2
&nbsp;
<span style="color: #808080;"># affiche le r&eacute;sultat du produit</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;(&quot;</span> + str<span class="br0">&#40;</span>z1<span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot;)&quot;</span> + <span style="color: #FF0000;">&quot;(&quot;</span> + str<span class="br0">&#40;</span>z2<span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot;)&quot;</span> + <span style="color: #FF0000;">&quot; = &quot;</span> + str<span class="br0">&#40;</span>z<span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche l'appartenance de z &agrave; l'ensemble &#8450;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span>str<span class="br0">&#40;</span>z<span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot; &isin; &quot;</span> + anneau<span class="br0">&#40;</span>z<span class="br0">&#41;</span><span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
Le code affiche :<br />
<br />
<span class="highlight"><font color="#000000">1 + 2i &#8712; &#8450;<br />
2 + 3i &#8712; &#8450;<br />
<br />
(1 + 2i)(2 + 3i) = -4 + 7i<br />
<br />
-4 + 7i &#8712; &#8450;<br />
</font></span><br />
<br />
On peut également vérifier la propriété d'associativité de la multiplication :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br /></div></td><td valign="top"><pre style="margin: 0">...
<span style="color: #808080;"># cr&eacute;ation de 3e objet Complexe : 2 + 2i</span>
z3 = Complexe<span class="br0">&#40;</span><span style="color: #cc66cc;">2</span>, <span style="color: #cc66cc;">2</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche les nombres complexes z1, z2 et z2</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;z1 = &quot;</span> + str<span class="br0">&#40;</span>z1<span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;z2 = &quot;</span> + str<span class="br0">&#40;</span>z2<span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;z3 = &quot;</span> + str<span class="br0">&#40;</span>z3<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># v&eacute;rification de la propri&eacute;t&eacute; d'associativit&eacute; de la multiplication dans &#8450;</span>
r1 = z1 * <span class="br0">&#40;</span>z2 * z3<span class="br0">&#41;</span>
r2 = <span class="br0">&#40;</span>z1 * z2<span class="br0">&#41;</span> * z3
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">if</span> r1==r2: <span style="color: #808080;"># si r1=r2</span>
    <span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;z1 * (z2 * z3) = (z1 * z2) * z3&quot;</span><span class="br0">&#41;</span> 
<span style="color: #0000ff;">else</span>:
    <span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;z1 * (z2 * z3) &ne; (z1 * z2) * z3&quot;</span><span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
Le code affiche :<br />
<br />
<span class="highlight"><font color="#000000">z1 = 1 + 2i<br />
z2 = 2 + 3i<br />
z3 = 2 + 2i<br />
<br />
z1 * (z2 * z3) = (z1 * z2) * z3<br />
</font></span><br />
<br />
<br />
<b>III-B. Création de la classe Polynome</b><br />
<br />
Pour définir ces polynômes en <b>Python</b> et pouvoir réaliser des opérations entre eux, il nous faut créer une <a href="https://docs.python.org/fr/3/tutorial/classes.html" target="_blank">classe</a> Polynome :<br />
<br />
<img src="https://www.developpez.net/forums/attachments/p651444d1709052299/bases-donnees/firebird/sql/alterer-col-null-not-null-int/classe_polynome.png/" border="0" alt="Nom : classe_polynome.png
Affichages : 5113
Taille : 8,3 Ko"  style="float: CONFIG" /><br />
<br />
Sa méthode constructeur <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">__init__()</span> va nous permettre de définir la liste des coefficients du polynôme au moment de créer l'objet :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:192px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">class</span> Polynome:
&nbsp;
    <span style="color: #0000ff;">def</span> <span style="color: #0080ff;">__init__</span><span class="br0">&#40;</span>self, liste_coefs=<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span><span class="br0">&#93;</span><span class="br0">&#41;</span>:
        <span style="color: #808080;"># m&eacute;thode constructeur de la classe</span>
&nbsp;
         <span style="color: #808080;"># on d&eacute;finit la liste des coefficients du polyn&ocirc;me [a0, a1, ..., an]</span>
        self.coefs = liste_coefs
&nbsp;
        <span style="color: #808080;"># suppression si n&eacute;cessaire des z&eacute;ros en queue de liste de coefficients. Exemple : [2, 3, 1, 0, 0] -&gt; [2, 3, 1]</span>
        self.reduire<span class="br0">&#40;</span><span class="br0">&#41;</span> 
&nbsp;
    <span style="color: #0000ff;">def</span> __str__<span class="br0">&#40;</span>self<span class="br0">&#41;</span>:
	...</pre></td></tr></table></pre>
</div><br />
La méthode <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">__str__</span> permet d'afficher un polynôme sous la forme <b>1 + 2.x + x^2</b>.<br />
<br />
Pour tester ces méthodes, nous ajoutons deux lignes au module :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:60px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="26"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br /></div></td><td valign="top"><pre style="margin: 0">p = Polynome<span class="br0">&#40;</span><span class="br0">&#91;</span><span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">2</span>, <span style="color: #cc66cc;">1</span><span class="br0">&#93;</span><span class="br0">&#41;</span> <span style="color: #808080;"># cr&eacute;ation de l'objet Polynome : 1 + 2x + x^2</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span>p<span class="br0">&#41;</span> <span style="color: #808080;"># affiche l'expression du polyn&ocirc;me</span></pre></td></tr></table></pre>
</div><br />
Le code affiche :<br />
<br />
<span class="highlight"><font color="#000000">1 + 2&#8901;X + X^2</font></span><br />
<br />
<br />
<u>Note importante</u> : la liste de coefficients permettant de créer l'objet Polynome contient également les coefficients nuls.<br />
<br />
Par exemple, le polynôme <b>P(x) = x^2 + 2&#8901;X^4</b> sera représenté par la liste  <b>[0, 0, 1, 0, 2] </b>.<br />
<br />
<br />
<b>III-B-1. Surcharge de l'opérateur d'addition</b><br />
<br />
Pour <a href="https://docs.python.org/fr/3/reference/datamodel.html#emulating-numeric-types" target="_blank">surcharger l'opérateur</a> « <b>+</b> » et pouvoir ainsi réaliser l'addition de <b>2</b> polynômes, nous devons ajouter une méthode <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">__add __ ()</span> à la classe :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">class</span> Polynome:
    ... 
    <span style="color: #0000ff;">def</span> <span style="color: #0080ff;">__add__</span><span class="br0">&#40;</span>self, other<span class="br0">&#41;</span>:
        <span style="color: #808080;"># m&eacute;thode permettant de red&eacute;finir l'op&eacute;rateur &laquo; + &raquo; pour 2 polyn&ocirc;mes : (1 + 2x + x^2) + (1 + x) = 2 + 3x + x^2</span>
&nbsp;
        <span style="color: #808080;"># p1 = self, p2 = other     </span>
        <span style="color: #0000ff;">if</span> len<span class="br0">&#40;</span>other.coefs<span class="br0">&#41;</span> &gt;len<span class="br0">&#40;</span>self.coefs<span class="br0">&#41;</span>: <span style="color: #808080;"># si degr&eacute; de p2 &gt; degr&eacute; de p1</span>
            <span style="color: #808080;"># on copie les coefs du polyn&ocirc;me de degr&eacute; le plus &eacute;lev&eacute; et la longueur de la liste de coefs la plus petite. </span>
            liste_coefs = other.coefs<span class="br0">&#91;</span>:<span class="br0">&#93;</span>; n = len<span class="br0">&#40;</span>self.coefs<span class="br0">&#41;</span> 
        <span style="color: #0000ff;">else</span>: liste_coefs = self.coefs<span class="br0">&#91;</span>:<span class="br0">&#93;</span>; n = len<span class="br0">&#40;</span>other.coefs<span class="br0">&#41;</span> <span style="color: #808080;"># sinon, ...</span>
&nbsp;
        <span style="color: #0000ff;">for</span> i <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span>n<span class="br0">&#41;</span>: <span style="color: #808080;"># parcours des indices de liste_coefs</span>
            liste_coefs<span class="br0">&#91;</span>i<span class="br0">&#93;</span> = self.coefs<span class="br0">&#91;</span>i<span class="br0">&#93;</span> + other.coefs<span class="br0">&#91;</span>i<span class="br0">&#93;</span> <span style="color: #808080;"># addition des coefficients de degr&eacute; i</span>
&nbsp;
        <span style="color: #808080;"># renvoie le polyn&ocirc;me r&eacute;sultat de l'addition</span>
        <span style="color: #0000ff;">return</span> Polynome<span class="br0">&#40;</span>liste_coefs<span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
Cette méthode permet donc de redéfinir l'opération « <b>+</b> » pour les polynômes en additionnant les coefficients de même degré.<br />
<br />
<br />
Pour tester l'opérateur d'addition portant sur <b>2</b> objets de la classe Polynome, nous ajoutons ces lignes de code :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #808080;"># cr&eacute;ation du 1er objet de la classe Polynome : 1 + 2x + x^2</span>
p1 = Polynome<span class="br0">&#40;</span><span class="br0">&#91;</span><span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">2</span>, <span style="color: #cc66cc;">1</span><span class="br0">&#93;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># cr&eacute;ation du 2e objet Polynome : 1 + x</span>
p2 = Polynome<span class="br0">&#40;</span><span class="br0">&#91;</span><span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">1</span><span class="br0">&#93;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche l'appartenance de p1 et p2 &agrave; l'ensemble &#8477;[X]</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span>str<span class="br0">&#40;</span>p1<span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot; &isin; &quot;</span> + anneau<span class="br0">&#40;</span>p1<span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span>str<span class="br0">&#40;</span>p2<span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot; &isin; &quot;</span> + anneau<span class="br0">&#40;</span>p2<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># addition des 2 polyn&ocirc;mes</span>
p = p1+p2
&nbsp;
<span style="color: #808080;"># affiche le r&eacute;sultat de l'addition</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;(&quot;</span> + str<span class="br0">&#40;</span>p1<span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot;)&quot;</span> + <span style="color: #FF0000;">&quot; + &quot;</span> + <span style="color: #FF0000;">&quot;(&quot;</span> + str<span class="br0">&#40;</span>p2<span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot;)&quot;</span> + <span style="color: #FF0000;">&quot; = &quot;</span> + str<span class="br0">&#40;</span>p<span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche l'appartenance de p &agrave; l'ensemble &#8477;[X]</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span>str<span class="br0">&#40;</span>p<span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot; &isin; &quot;</span> + anneau<span class="br0">&#40;</span>p<span class="br0">&#41;</span><span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
Le code affiche :<br />
<br />
<span class="highlight"><font color="#000000">1 + 2&#8901;X + X^2 &#8712; &#8477;[X]<br />
1 + X &#8712; &#8477;[X]<br />
<br />
(1 + 2&#8901;X + X^2) + (1 + X) = 2 + 3&#8901;X + X^2<br />
<br />
2 + 3&#8901;X + X^2 &#8712; &#8477;[X]<br />
</font></span><br />
<br />
<br />
<b>III-B-2. Surcharge de l'opérateur de multiplication</b><br />
<br />
Pour surcharger l'opérateur « <b>*</b> » et l'appliquer à <b>2</b> polynômes, nous devons également ajouter une méthode __mul __ () à la classe :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">class</span> Polynome:
    ... 
    <span style="color: #0000ff;">def</span> <span style="color: #0080ff;">__mul__</span><span class="br0">&#40;</span>self, other<span class="br0">&#41;</span>:
        <span style="color: #808080;"># m&eacute;thode permettant de red&eacute;finir l'op&eacute;rateur &laquo; * &raquo; pour 2 polyn&ocirc;mes : (1 + x) * (1 + 2x) =  1 + 3x + 2x^2</span>
&nbsp;
        <span style="color: #808080;"># initialisation de la liste des coefficients qu'avec des z&eacute;ros</span>
        liste_coefs=<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span><span class="br0">&#93;</span>*<span class="br0">&#40;</span>len<span class="br0">&#40;</span>self.coefs<span class="br0">&#41;</span>+len<span class="br0">&#40;</span>other.coefs<span class="br0">&#41;</span>-<span style="color: #cc66cc;">1</span><span class="br0">&#41;</span> <span style="color: #808080;"># exemple : [0, 0, 0]</span>
        <span style="color: #0000ff;">for</span> i1 <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span>len<span class="br0">&#40;</span>self.coefs<span class="br0">&#41;</span><span class="br0">&#41;</span>: <span style="color: #808080;"># parcours des indices des coefs du polyn&ocirc;me n&deg;1</span>
            <span style="color: #0000ff;">for</span> i2 <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span>len<span class="br0">&#40;</span>other.coefs<span class="br0">&#41;</span><span class="br0">&#41;</span>: <span style="color: #808080;"># parcours des indices des coefs du polyn&ocirc;me n&deg;2</span>
                <span style="color: #808080;"># multiplication des coefficients d'indices i1 et i2</span>
                liste_coefs<span class="br0">&#91;</span>i1+i2<span class="br0">&#93;</span> = liste_coefs<span class="br0">&#91;</span>i1+i2<span class="br0">&#93;</span> + self.coefs<span class="br0">&#91;</span>i1<span class="br0">&#93;</span>*other.coefs<span class="br0">&#91;</span>i2<span class="br0">&#93;</span>
&nbsp;
        <span style="color: #808080;"># cr&eacute;ation de l'objet Polynome bas&eacute; sur la liste</span>
        poly=Polynome<span class="br0">&#40;</span>liste_coefs<span class="br0">&#41;</span> 
&nbsp;
        <span style="color: #0000ff;">return</span> poly <span style="color: #808080;"># renvoie le polyn&ocirc;me r&eacute;sultat de la multiplication</span></pre></td></tr></table></pre>
</div><br />
Cette méthode permet donc de redéfinir l'opération de multiplication pour <b>2</b> polynômes en utilisant la propriété de distributivité de la multiplication par rapport à l'addition.<br />
<br />
<br />
Pour tester l'opérateur de multiplication portant sur <b>2</b> objets de la classe <b>Polynome</b>, nous ajoutons simplement ces lignes :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #808080;"># cr&eacute;ation du 1er objet de la classe Polynome : 1 + x</span>
p1 = Polynome<span class="br0">&#40;</span><span class="br0">&#91;</span><span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">1</span><span class="br0">&#93;</span><span class="br0">&#41;</span> 
&nbsp;
<span style="color: #808080;"># cr&eacute;ation du 2e objet de la classe Polynome : 1 + 2x</span>
p2 = Polynome<span class="br0">&#40;</span><span class="br0">&#91;</span><span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">2</span><span class="br0">&#93;</span><span class="br0">&#41;</span> 
&nbsp;
<span style="color: #808080;"># affiche l'appartenance de p1 et p2 &agrave; l'ensemble &#8477;[X]</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span>str<span class="br0">&#40;</span>p1<span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot; &isin; &quot;</span> + anneau<span class="br0">&#40;</span>p1<span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span>str<span class="br0">&#40;</span>p2<span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot; &isin; &quot;</span> + anneau<span class="br0">&#40;</span>p2<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># produit des 2 polyn&ocirc;mes</span>
p = p1*p2
&nbsp;
<span style="color: #808080;"># affiche le r&eacute;sultat de la multiplication de p1 par p2</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;(&quot;</span> + str<span class="br0">&#40;</span>p1<span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot;)&quot;</span> + <span style="color: #FF0000;">&quot;(&quot;</span> + str<span class="br0">&#40;</span>p2<span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot;)&quot;</span> + <span style="color: #FF0000;">&quot; = &quot;</span> + str<span class="br0">&#40;</span>p<span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche l'appartenance de p &agrave; l'ensemble &#8477;[X]</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span>str<span class="br0">&#40;</span>p<span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot; &isin; &quot;</span> + anneau<span class="br0">&#40;</span>p<span class="br0">&#41;</span><span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
Le code affiche :<br />
<br />
<span class="highlight"><font color="#000000">1 + X &#8712; &#8477;[X]<br />
1 + 2&#8901;X &#8712; &#8477;[X]<br />
<br />
(1 + X)(1 + 2&#8901;X) = 1 + 3&#8901;X + 2&#8901;X^2<br />
<br />
1 + 3&#8901;X + 2&#8901;X^2 &#8712; &#8477;[X]<br />
</font></span><br />
<br />
On peut bien sûr imaginer d'étendre à ces objets mathématiques d'autres opérations effectuées sur les nombres entiers (soustraction, puissance, etc.).<br />
<br />
<br />
<br />
<b>IV. Module complet</b><br />
<br />
On donne pour finir le code complet du module contenant les deux classes :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="40"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br />50<br />51<br />52<br />53<br />54<br />55<br />56<br />57<br />58<br />59<br />60<br />61<br />62<br />63<br />64<br />65<br />66<br />67<br />68<br />69<br />70<br />71<br />72<br />73<br />74<br />75<br />76<br />77<br />78<br />79<br />80<br />81<br />82<br />83<br />84<br />85<br />86<br />87<br />88<br />89<br />90<br />91<br />92<br />93<br />94<br />95<br />96<br />97<br />98<br />99<br />100<br />101<br />102<br />103<br />104<br />105<br />106<br />107<br />108<br />109<br />110<br />111<br />112<br />113<br />114<br />115<br />116<br />117<br />118<br />119<br />120<br />121<br />122<br />123<br />124<br />125<br />126<br />127<br />128<br />129<br />130<br />131<br />132<br />133<br />134<br />135<br />136<br />137<br />138<br />139<br />140<br />141<br />142<br />143<br />144<br />145<br />146<br />147<br />148<br />149<br />150<br />151<br />152<br />153<br />154<br />155<br />156<br />157<br />158<br />159<br />160<br />161<br />162<br />163<br />164<br />165<br />166<br />167<br />168<br />169<br />170<br />171<br />172<br />173<br />174<br />175<br />176<br />177<br />178<br />179<br />180<br />181<br />182<br />183<br />184<br />185<br />186<br />187<br />188<br />189<br />190<br />191<br />192<br />193<br />194<br />195<br />196<br />197<br />198<br />199<br />200<br />201<br />202<br />203<br />204<br />205<br />206<br />207<br />208<br />209<br />210<br />211<br />212<br />213<br />214<br />215<br />216<br />217<br />218<br />219<br />220<br />221<br />222<br />223<br />224<br />225<br />226<br />227<br />228<br />229<br />230<br />231<br />232<br />233<br />234<br />235<br />236<br />237<br />238<br />239<br />240<br />241<br />242<br />243<br />244<br />245<br />246<br />247<br />248<br />249<br />250<br />251<br />252<br />253<br />254<br />255<br />256<br />257<br />258<br />259<br />260<br />261<br />262<br />263<br />264<br />265<br />266<br />267<br />268<br />269<br />270<br />271<br />272<br />273<br />274<br />275<br />276<br />277<br />278<br />279<br />280<br />281<br />282<br />283<br />284<br />285<br />286<br />287<br />288<br />289<br />290<br />291<br />292<br />293<br />294<br />295<br />296<br />297<br />298<br />299<br />300<br />301<br />302<br />303<br />304<br />305<br />306<br />307<br />308<br />309<br />310<br />311<br />312<br />313<br />314<br />315<br />316<br />317<br />318<br />319<br />320<br />321<br />322<br />323<br />324<br />325<br />326<br />327<br />328<br />329<br />330<br />331<br />332<br />333<br />334<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">class</span> Complexe:
&nbsp;
    <span style="color: #0000ff;">def</span> <span style="color: #0080ff;">__init__</span><span class="br0">&#40;</span>self, part_reel=<span style="color: #cc66cc;">0</span>, part_imag=<span style="color: #cc66cc;">0</span><span class="br0">&#41;</span>:
        <span style="color: #808080;"># m&eacute;thode constructeur de la classe</span>
&nbsp;
        <span style="color: #808080;"># on d&eacute;finit la partie r&eacute;elle du nombre complexe</span>
        self.reel = part_reel
&nbsp;
        <span style="color: #808080;"># on d&eacute;finit la partie imaginaire du nombre complexe</span>
        self.imag = part_imag 
&nbsp;
    <span style="color: #0000ff;">def</span> __str__<span class="br0">&#40;</span>self<span class="br0">&#41;</span>:
        <span style="color: #808080;"># permet d'afficher le nombre complexe sous la forme alg&eacute;brique a + bi</span>
&nbsp;
        <span style="color: #0000ff;">return</span> <span style="color: #FF0000;">&quot;{0} + {1}i&quot;</span>.format<span class="br0">&#40;</span>self.reel, self.imag<span class="br0">&#41;</span> <span style="color: #0000ff;">if</span> self.imag&gt;=<span style="color: #cc66cc;">0</span> <span style="color: #0000ff;">else</span> <span style="color: #FF0000;">&quot;{0} - {1}i&quot;</span>.format<span class="br0">&#40;</span>self.reel, abs<span class="br0">&#40;</span>self.imag<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
    <span style="color: #0000ff;">def</span> <span style="color: #0080ff;">__add__</span><span class="br0">&#40;</span>self, other<span class="br0">&#41;</span>:
        <span style="color: #808080;"># m&eacute;thode permettant de red&eacute;finir l'op&eacute;rateur &laquo; + &raquo; pour 2 nombres complexes : z1 + z2 = (a + bi) + (c + di) = (a+c) + (b+d)i</span>
&nbsp;
        <span style="color: #808080;"># on &eacute;value la partie r&eacute;elle du nombre complexe r&eacute;sultat de l'addition</span>
        part_reel = self.reel + other.reel
&nbsp;
        <span style="color: #808080;"># on &eacute;value la partie imaginaire du nombre complexe r&eacute;sultat de l'addition</span>
        part_imag = self.imag + other.imag
&nbsp;
        <span style="color: #808080;"># renvoie le nombre complexe r&eacute;sultat de l'addition</span>
        <span style="color: #0000ff;">return</span> Complexe<span class="br0">&#40;</span>part_reel, part_imag<span class="br0">&#41;</span> 
&nbsp;
    <span style="color: #0000ff;">def</span> <span style="color: #0080ff;">__mul__</span><span class="br0">&#40;</span>self, other<span class="br0">&#41;</span>:
        <span style="color: #808080;"># m&eacute;thode permettant de red&eacute;finir l'op&eacute;rateur &laquo; * &raquo; pour 2 nombres complexes : z1 * z2 = (ac - bd) + (ad + bc)*i </span>
&nbsp;
        <span style="color: #808080;"># part_reel = (ac - bd)</span>
        part_reel = self.reel * other.reel - self.imag * other.imag
&nbsp;
        <span style="color: #808080;"># part_imag = (ad + bc)</span>
        part_imag = self.reel * other.imag + self.imag * other.reel
&nbsp;
        <span style="color: #808080;"># renvoie le nombre complexe r&eacute;sultat de la multiplication</span>
        <span style="color: #0000ff;">return</span> Complexe<span class="br0">&#40;</span>part_reel, part_imag<span class="br0">&#41;</span> 
&nbsp;
    <span style="color: #0000ff;">def</span> __pow__<span class="br0">&#40;</span>self, n<span class="br0">&#41;</span>:
        <span style="color: #808080;"># m&eacute;thode permettant de red&eacute;finir l'op&eacute;rateur de puissance : self ** n</span>
&nbsp;
        <span style="color: #808080;"># on initialise la variable objet z avec la valeur 1 &eacute;l&eacute;ment neutre pour la multiplication de nombres complexes</span>
        z = Complexe<span class="br0">&#40;</span><span style="color: #cc66cc;">1</span>,<span style="color: #cc66cc;">0</span><span class="br0">&#41;</span>
&nbsp;
        <span style="color: #808080;"># nous multiplions n fois z par self &agrave; l'aide de l'op&eacute;rateur *</span>
        <span style="color: #0000ff;">for</span> i <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span>n<span class="br0">&#41;</span>: 
            z = z*self <span style="color: #808080;"># &eacute;quivalent &agrave; : z = z.__mul__(self)</span>
&nbsp;
        <span style="color: #808080;"># renvoie le nombre complexe r&eacute;sultat de l'op&eacute;ration (self ** n)</span>
        <span style="color: #0000ff;">return</span> z 
&nbsp;
    <span style="color: #0000ff;">def</span> <span style="color: #0080ff;">__eq__</span><span class="br0">&#40;</span>self, other<span class="br0">&#41;</span>:
        <span style="color: #808080;"># m&eacute;thode permettant de red&eacute;finir l'op&eacute;rateur &laquo; == &raquo; pour 2 nombres complexes </span>
&nbsp;
        <span style="color: #808080;"># renvoie True si les parties r&eacute;elles et imaginaires des 2 nombres complexes sont &eacute;gales</span>
        <span style="color: #0000ff;">return</span> <span class="br0">&#40;</span>self.reel==other.reel<span class="br0">&#41;</span> <span style="color: #0000ff;">and</span> <span class="br0">&#40;</span>self.imag==other.imag<span class="br0">&#41;</span> 
&nbsp;
&nbsp;
<span style="color: #0000ff;">class</span> Polynome:
&nbsp;
    <span style="color: #0000ff;">def</span> <span style="color: #0080ff;">__init__</span><span class="br0">&#40;</span>self, liste_coefs=<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span><span class="br0">&#93;</span><span class="br0">&#41;</span>:
        <span style="color: #808080;"># m&eacute;thode constructeur de la classe</span>
&nbsp;
         <span style="color: #808080;"># on d&eacute;finit la liste des coefficients du polyn&ocirc;me [a0, a1, ..., an]</span>
        self.coefs = liste_coefs
&nbsp;
        <span style="color: #808080;"># suppression si n&eacute;cessaire des z&eacute;ros en queue de liste de coefficients. Exemple : [2, 3, 1, 0, 0] -&gt; [2, 3, 1]</span>
        self.reduire<span class="br0">&#40;</span><span class="br0">&#41;</span> 
&nbsp;
&nbsp;
    <span style="color: #0000ff;">def</span> __str__<span class="br0">&#40;</span>self<span class="br0">&#41;</span>: <span style="color: #808080;"># permet d'afficher le polyn&ocirc;me sous la forme 1 + 2x + 3x^2</span>
        s=<span style="color: #FF0000;">&quot;&quot;</span> <span style="color: #808080;"># initialisation de la cha&icirc;ne de caract&egrave;res</span>
        <span style="color: #808080;"># on v&eacute;rifie d&#146;abord si le degr&eacute; du polyn&ocirc;me est nul</span>
        <span style="color: #0000ff;">if</span> <span class="br0">&#40;</span>len<span class="br0">&#40;</span>self.coefs<span class="br0">&#41;</span>-<span style="color: #cc66cc;">1</span>==<span style="color: #cc66cc;">0</span><span class="br0">&#41;</span>:
            <span style="color: #0000ff;">return</span> str<span class="br0">&#40;</span>self.coefs<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span><span class="br0">&#93;</span><span class="br0">&#41;</span>
        <span style="color: #0000ff;">else</span>: <span style="color: #808080;"># sinon</span>
            <span style="color: #0000ff;">if</span> self.coefs<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span><span class="br0">&#93;</span>!=<span style="color: #cc66cc;">0</span>:
                s=str<span class="br0">&#40;</span>self.coefs<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span><span class="br0">&#93;</span><span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot; + &quot;</span>
            <span style="color: #0000ff;">for</span> i <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span><span style="color: #cc66cc;">1</span>, len<span class="br0">&#40;</span>self.coefs<span class="br0">&#41;</span><span class="br0">&#41;</span>: <span style="color: #808080;"># parcours des indices des coefficients du polyn&ocirc;me : [a1, a2, ..., an]</span>
                <span style="color: #0000ff;">if</span> self.coefs<span class="br0">&#91;</span>i<span class="br0">&#93;</span>!=<span style="color: #cc66cc;">0</span>: <span style="color: #808080;"># si le coefficient de degr&eacute; i n'est pas nul</span>
                    <span style="color: #0000ff;">if</span> self.coefs<span class="br0">&#91;</span>i<span class="br0">&#93;</span>!=<span style="color: #cc66cc;">1</span>: <span style="color: #808080;"># si le coefficient de degr&eacute; i est diff&eacute;rent de 1</span>
                        s+=<span style="color: #FF0000;">&quot;{}&sdot;X^{} + &quot;</span>.format<span class="br0">&#40;</span>self.coefs<span class="br0">&#91;</span>i<span class="br0">&#93;</span>,i<span class="br0">&#41;</span>
                    <span style="color: #0000ff;">else</span>: s+=<span style="color: #FF0000;">&quot;X^{} + &quot;</span>.format<span class="br0">&#40;</span>i<span class="br0">&#41;</span>  
&nbsp;
            <span style="color: #808080;"># &eacute;limination des caract&egrave;res en trop           </span>
            s = s<span class="br0">&#91;</span>:-<span style="color: #cc66cc;">3</span><span class="br0">&#93;</span>.replace<span class="br0">&#40;</span><span style="color: #FF0000;">&quot;+ -&quot;</span>, <span style="color: #FF0000;">&quot;- &quot;</span><span class="br0">&#41;</span>.replace<span class="br0">&#40;</span><span style="color: #FF0000;">&quot;X^1 &quot;</span>,<span style="color: #FF0000;">&quot;X &quot;</span><span class="br0">&#41;</span>.replace<span class="br0">&#40;</span><span style="color: #FF0000;">&quot; 1&sdot;X&quot;</span>,<span style="color: #FF0000;">&quot; X&quot;</span><span class="br0">&#41;</span>
            <span style="color: #0000ff;">if</span> s<span class="br0">&#91;</span>-<span style="color: #cc66cc;">2</span>:<span class="br0">&#93;</span>==<span style="color: #FF0000;">&quot;^1&quot;</span>: s = s<span class="br0">&#91;</span>:-<span style="color: #cc66cc;">2</span><span class="br0">&#93;</span>
            <span style="color: #0000ff;">if</span> s<span class="br0">&#91;</span>:<span style="color: #cc66cc;">3</span><span class="br0">&#93;</span>==<span style="color: #FF0000;">&quot;1&sdot;X&quot;</span>: s = s<span class="br0">&#91;</span><span style="color: #cc66cc;">3</span>:<span class="br0">&#93;</span>
&nbsp;
            <span style="color: #0000ff;">return</span> s <span style="color: #808080;"># on retourne l'expression du polyn&ocirc;me</span>
&nbsp;
    <span style="color: #0000ff;">def</span> eval_degre<span class="br0">&#40;</span><span class="br0">&#41;</span>: <span style="color: #808080;"># retourne le degr&eacute; du polyn&ocirc;me</span>
        <span style="color: #0000ff;">return</span> <span class="br0">&#40;</span>len<span class="br0">&#40;</span>self.coefs<span class="br0">&#41;</span>-<span style="color: #cc66cc;">1</span><span class="br0">&#41;</span>
&nbsp;
    <span style="color: #0000ff;">def</span> <span style="color: #0080ff;">__add__</span><span class="br0">&#40;</span>self, other<span class="br0">&#41;</span>:
        <span style="color: #808080;"># m&eacute;thode permettant de red&eacute;finir l'op&eacute;rateur &laquo; + &raquo; pour 2 polyn&ocirc;mes : (1 + 2x + x^2) + (1 + x) = 2 + 3x + x^2</span>
&nbsp;
        <span style="color: #808080;"># p1 = self, p2 = other     </span>
        <span style="color: #0000ff;">if</span> len<span class="br0">&#40;</span>other.coefs<span class="br0">&#41;</span> &gt;len<span class="br0">&#40;</span>self.coefs<span class="br0">&#41;</span>: <span style="color: #808080;"># si degr&eacute; de p2 &gt; degr&eacute; de p1</span>
            <span style="color: #808080;"># on copie les coefs du polyn&ocirc;me de degr&eacute; le plus &eacute;lev&eacute; et la longueur de la liste de coefs la plus petite. </span>
            liste_coefs = other.coefs<span class="br0">&#91;</span>:<span class="br0">&#93;</span>; n = len<span class="br0">&#40;</span>self.coefs<span class="br0">&#41;</span> 
        <span style="color: #0000ff;">else</span>: liste_coefs = self.coefs<span class="br0">&#91;</span>:<span class="br0">&#93;</span>; n = len<span class="br0">&#40;</span>other.coefs<span class="br0">&#41;</span> <span style="color: #808080;"># sinon, ...</span>
&nbsp;
        <span style="color: #0000ff;">for</span> i <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span>n<span class="br0">&#41;</span>: <span style="color: #808080;"># parcours des indices de liste_coefs</span>
            liste_coefs<span class="br0">&#91;</span>i<span class="br0">&#93;</span> = self.coefs<span class="br0">&#91;</span>i<span class="br0">&#93;</span> + other.coefs<span class="br0">&#91;</span>i<span class="br0">&#93;</span> <span style="color: #808080;"># addition des coefficients de degr&eacute; i</span>
&nbsp;
        <span style="color: #808080;"># renvoie le polyn&ocirc;me r&eacute;sultat de l'addition</span>
        <span style="color: #0000ff;">return</span> Polynome<span class="br0">&#40;</span>liste_coefs<span class="br0">&#41;</span> 
&nbsp;
    <span style="color: #0000ff;">def</span> reduire<span class="br0">&#40;</span>self<span class="br0">&#41;</span>:
        <span style="color: #808080;"># tant que le dernier &eacute;l&eacute;ment de la liste est nul</span>
       <span style="color: #0000ff;">while</span> self.coefs<span class="br0">&#91;</span>-<span style="color: #cc66cc;">1</span><span class="br0">&#93;</span> == <span style="color: #cc66cc;">0</span> <span style="color: #0000ff;">and</span> len<span class="br0">&#40;</span>self.coefs<span class="br0">&#41;</span>&gt;<span style="color: #cc66cc;">1</span>:
            self.coefs.pop<span class="br0">&#40;</span><span class="br0">&#41;</span> <span style="color: #808080;"># supprimer le dernier &eacute;l&eacute;ment</span>
&nbsp;
    <span style="color: #0000ff;">def</span> <span style="color: #0080ff;">__mul__</span><span class="br0">&#40;</span>self, other<span class="br0">&#41;</span>:
        <span style="color: #808080;"># m&eacute;thode permettant de red&eacute;finir l'op&eacute;rateur &laquo; * &raquo; pour 2 polyn&ocirc;mes : (1 + x) * (1 + 2x) =  1 + 3x + 2x^2</span>
&nbsp;
        <span style="color: #808080;"># initialisation de la liste des coefficients qu'avec des z&eacute;ros</span>
        liste_coefs=<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span><span class="br0">&#93;</span>*<span class="br0">&#40;</span>len<span class="br0">&#40;</span>self.coefs<span class="br0">&#41;</span>+len<span class="br0">&#40;</span>other.coefs<span class="br0">&#41;</span>-<span style="color: #cc66cc;">1</span><span class="br0">&#41;</span> <span style="color: #808080;"># exemple : [0, 0, 0]</span>
        <span style="color: #0000ff;">for</span> i1 <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span>len<span class="br0">&#40;</span>self.coefs<span class="br0">&#41;</span><span class="br0">&#41;</span>: <span style="color: #808080;"># parcours des indices des coefs du polyn&ocirc;me n&deg;1</span>
            <span style="color: #0000ff;">for</span> i2 <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span>len<span class="br0">&#40;</span>other.coefs<span class="br0">&#41;</span><span class="br0">&#41;</span>: <span style="color: #808080;"># parcours des indices des coefs du polyn&ocirc;me n&deg;2</span>
                <span style="color: #808080;"># multiplication des coefficients d'indices i1 et i2</span>
                liste_coefs<span class="br0">&#91;</span>i1+i2<span class="br0">&#93;</span> = liste_coefs<span class="br0">&#91;</span>i1+i2<span class="br0">&#93;</span> + self.coefs<span class="br0">&#91;</span>i1<span class="br0">&#93;</span>*other.coefs<span class="br0">&#91;</span>i2<span class="br0">&#93;</span>
&nbsp;
        <span style="color: #808080;"># cr&eacute;ation de l'objet Polynome bas&eacute; sur la liste</span>
        poly=Polynome<span class="br0">&#40;</span>liste_coefs<span class="br0">&#41;</span> 
&nbsp;
        <span style="color: #0000ff;">return</span> poly <span style="color: #808080;"># renvoie le polyn&ocirc;me r&eacute;sultat de la multiplication</span>
&nbsp;
    <span style="color: #0000ff;">def</span> __pow__<span class="br0">&#40;</span>self, n<span class="br0">&#41;</span>: <span style="color: #808080;"># m&eacute;thode permettant de red&eacute;finir l'op&eacute;rateur de puissance : self ** n</span>
        <span style="color: #808080;"># on cr&eacute;e l'objet poly &agrave; partir d'une liste contenant un seul &eacute;l&eacute;ment 1, &eacute;l&eacute;ment neutre pour la multiplication des polyn&ocirc;mes</span>
        poly = Polynome<span class="br0">&#40;</span><span class="br0">&#91;</span><span style="color: #cc66cc;">1</span><span class="br0">&#93;</span><span class="br0">&#41;</span> 
&nbsp;
        <span style="color: #0000ff;">for</span> i <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span>n<span class="br0">&#41;</span>: <span style="color: #808080;"># on multiplie n fois poly par self &agrave; l'aide de l'op&eacute;rateur *            </span>
            poly = poly*self <span style="color: #808080;"># &eacute;quivalent &agrave; : poly = poly.__mul__(self)</span>
&nbsp;
        <span style="color: #0000ff;">return</span> poly <span style="color: #808080;"># renvoie le polyn&ocirc;me r&eacute;sultat de l'op&eacute;ration (self ** n)</span>
&nbsp;
    <span style="color: #0000ff;">def</span> <span style="color: #0080ff;">__eq__</span><span class="br0">&#40;</span>poly1, other<span class="br0">&#41;</span>: <span style="color: #808080;"># m&eacute;thode permettant de red&eacute;finir l'op&eacute;rateur &laquo; == &raquo; pour 2 polyn&ocirc;mes</span>
&nbsp;
        <span style="color: #0000ff;">return</span> <span class="br0">&#40;</span>poly1.coefs==other.coefs<span class="br0">&#41;</span> <span style="color: #808080;"># renvoie True si les 2 liste de coefficients sont &eacute;gales</span>
&nbsp;
    <span style="color: #0000ff;">def</span> eval<span class="br0">&#40;</span>self,x<span class="br0">&#41;</span>: <span style="color: #808080;"># m&eacute;thode permettant d'&eacute;valuer le polyn&ocirc;me en fonction de x</span>
        <span style="color: #808080;"># intialisation des variables</span>
        valeur_polynome = self.coefs<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span><span class="br0">&#93;</span> <span style="color: #808080;"># valeur_polynome = a0</span>
        power=<span style="color: #cc66cc;">1</span>    
&nbsp;
        <span style="color: #0000ff;">for</span> coef <span style="color: #0000ff;">in</span> self.coefs<span class="br0">&#91;</span><span style="color: #cc66cc;">1</span>:<span class="br0">&#93;</span>: <span style="color: #808080;"># parcours des coefficients du polyn&ocirc;me &agrave; partir de a1 : a1, a2, ..., an</span>
            power = power*x <span style="color: #808080;"># calcul de la puissance de x pour ai : power = x^i</span>
            valeur_polynome += coef*power <span style="color: #808080;"># valeur_polynome = valeur_polynome + ai*x^i</span>
&nbsp;
        <span style="color: #0000ff;">return</span> valeur_polynome <span style="color: #808080;"># renvoie la valeur du polyn&ocirc;me</span>
&nbsp;
    <span style="color: #0000ff;">def</span> eval_horner<span class="br0">&#40;</span>self,x<span class="br0">&#41;</span>: <span style="color: #808080;"># m&eacute;thode permettant d'&eacute;valuer le polyn&ocirc;me en fonction de x</span>
        <span style="color: #808080;"># intialisation de la variable</span>
        valeur_polynome = self.coefs<span class="br0">&#91;</span>-<span style="color: #cc66cc;">1</span><span class="br0">&#93;</span> <span style="color: #808080;"># valeur_polynome = an</span>
&nbsp;
        <span style="color: #0000ff;">for</span> coef <span style="color: #0000ff;">in</span> reversed<span class="br0">&#40;</span>self.coefs<span class="br0">&#91;</span>:-<span style="color: #cc66cc;">1</span><span class="br0">&#93;</span><span class="br0">&#41;</span>: <span style="color: #808080;"># parcours des coefficients du polyn&ocirc;me &agrave; partir de an-1 : an-1, ..., a1, a0</span>
            valeur_polynome = valeur_polynome*x + coef  <span style="color: #808080;"># valeur_polynome = valeur_polynome*x + ai</span>
&nbsp;
        <span style="color: #0000ff;">return</span> valeur_polynome <span style="color: #808080;"># renvoie la valeur du polyn&ocirc;me</span>
&nbsp;
&nbsp;
<span style="color: #0000ff;">def</span> anneau<span class="br0">&#40;</span>element<span class="br0">&#41;</span>:
    <span style="color: #808080;"># retourne l'ensemble ou l'anneau auquel appartient l'&eacute;l&eacute;ment pass&eacute; en argument</span>
&nbsp;
    <span style="color: #808080;"># si c'est un objet Complexe</span>
    <span style="color: #0000ff;">if</span> isinstance<span class="br0">&#40;</span>element, Complexe<span class="br0">&#41;</span>:
        <span style="color: #0000ff;">return</span> <span style="color: #FF0000;">&quot;&#8450;&quot;</span>
    <span style="color: #808080;"># si c'est un objet Polynome</span>
    <span style="color: #0000ff;">elif</span> isinstance<span class="br0">&#40;</span>element, Polynome<span class="br0">&#41;</span>:
        <span style="color: #0000ff;">return</span> <span style="color: #FF0000;">&quot;&#8477;[X]&quot;</span>
    <span style="color: #808080;"># si c'est un entier</span>
    <span style="color: #0000ff;">elif</span> isinstance<span class="br0">&#40;</span>element, int<span class="br0">&#41;</span>:
        <span style="color: #0000ff;">return</span> <span style="color: #FF0000;">&quot;Z&quot;</span>
    <span style="color: #0000ff;">else</span>: <span style="color: #808080;"># sinon</span>
        <span style="color: #0000ff;">return</span> <span style="color: #FF0000;">&quot;&quot;</span>
&nbsp;
&nbsp;
<span style="color: #808080;"># addition de 2 nombres complexes</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;I-A. Addition de 2 nombres complexes<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># cr&eacute;ation du 1er objet de la classe Complexe : 1 + 2i</span>
z1 = Complexe<span class="br0">&#40;</span><span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">2</span><span class="br0">&#41;</span> 
&nbsp;
<span style="color: #808080;"># cr&eacute;ation de 2e objet Complexe : 2 + 3i</span>
z2 = Complexe<span class="br0">&#40;</span><span style="color: #cc66cc;">2</span>, <span style="color: #cc66cc;">3</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche l'appartenance de z1 et z2 &agrave; l'ensemble &#8450;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span>str<span class="br0">&#40;</span>z1<span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot; &isin; &quot;</span> + anneau<span class="br0">&#40;</span>z1<span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span>str<span class="br0">&#40;</span>z2<span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot; &isin; &quot;</span> + anneau<span class="br0">&#40;</span>z2<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># addition des 2 nombres complexes</span>
z = z1+z2
&nbsp;
<span style="color: #808080;"># affiche le r&eacute;sultat de l'addition</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;(&quot;</span> + str<span class="br0">&#40;</span>z1<span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot;)&quot;</span> + <span style="color: #FF0000;">&quot; + &quot;</span> + <span style="color: #FF0000;">&quot;(&quot;</span> + str<span class="br0">&#40;</span>z2<span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot;)&quot;</span> + <span style="color: #FF0000;">&quot; = &quot;</span> + str<span class="br0">&#40;</span>z<span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche l'appartenance de z &agrave; l'ensemble &#8450;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span>str<span class="br0">&#40;</span>z<span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot; &isin; &quot;</span> + anneau<span class="br0">&#40;</span>z<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;V&eacute;rification de l'associativit&eacute; de l'addition dans &#8450;<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># cr&eacute;ation de 3e objet Complexe : 2 + 2i</span>
z3 = Complexe<span class="br0">&#40;</span><span style="color: #cc66cc;">2</span>, <span style="color: #cc66cc;">2</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche les nombres complexes z1, z2 et z2</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;z1 = &quot;</span> + str<span class="br0">&#40;</span>z1<span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;z2 = &quot;</span> + str<span class="br0">&#40;</span>z2<span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;z3 = &quot;</span> + str<span class="br0">&#40;</span>z3<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># v&eacute;rification de la propri&eacute;t&eacute; d'associativit&eacute; de l'addition dans &#8450;</span>
r1 = z1 + <span class="br0">&#40;</span>z2 + z3<span class="br0">&#41;</span>
r2 = <span class="br0">&#40;</span>z1 + z2<span class="br0">&#41;</span> + z3
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">if</span> r1==r2: <span style="color: #808080;"># si r1=r2</span>
    <span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;z1 + (z2 + z3) = (z1 + z2) + z3&quot;</span><span class="br0">&#41;</span> 
<span style="color: #0000ff;">else</span>:
    <span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;z1 + (z2 + z3) &ne; (z1 + z2) + z3&quot;</span><span class="br0">&#41;</span> 
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># multiplication de 2 nombres complexes</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;I-B. Multiplication de 2 nombres complexes<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># cr&eacute;ation du 1er objet de la classe Complexe : 1 + 2i</span>
z1 = Complexe<span class="br0">&#40;</span><span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">2</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># cr&eacute;ation du 2e objet de la classe Complexe : 2 + 3i</span>
z2 = Complexe<span class="br0">&#40;</span><span style="color: #cc66cc;">2</span>, <span style="color: #cc66cc;">3</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche l'appartenance de z1 et z2 &agrave; l'ensemble &#8450;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span>str<span class="br0">&#40;</span>z1<span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot; &isin; &quot;</span> + anneau<span class="br0">&#40;</span>z1<span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span>str<span class="br0">&#40;</span>z2<span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot; &isin; &quot;</span> + anneau<span class="br0">&#40;</span>z2<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># produit des 2 nombres complexes</span>
z = z1*z2
&nbsp;
<span style="color: #808080;"># affiche le r&eacute;sultat du produit</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;(&quot;</span> + str<span class="br0">&#40;</span>z1<span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot;)&quot;</span> + <span style="color: #FF0000;">&quot;(&quot;</span> + str<span class="br0">&#40;</span>z2<span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot;)&quot;</span> + <span style="color: #FF0000;">&quot; = &quot;</span> + str<span class="br0">&#40;</span>z<span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche l'appartenance de z &agrave; l'ensemble &#8450;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span>str<span class="br0">&#40;</span>z<span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot; &isin; &quot;</span> + anneau<span class="br0">&#40;</span>z<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;V&eacute;rification de l'associativit&eacute; de la multiplication dans &#8450;<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche les nombres complexes z1, z2 et z2</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;z1 = &quot;</span> + str<span class="br0">&#40;</span>z1<span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;z2 = &quot;</span> + str<span class="br0">&#40;</span>z2<span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;z3 = &quot;</span> + str<span class="br0">&#40;</span>z3<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># v&eacute;rification de la propri&eacute;t&eacute; d'associativit&eacute; de la multiplication dans &#8450;</span>
r1 = z1 * <span class="br0">&#40;</span>z2 * z3<span class="br0">&#41;</span>
r2 = <span class="br0">&#40;</span>z1 * z2<span class="br0">&#41;</span> * z3
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">if</span> r1==r2: <span style="color: #808080;"># si r1=r2</span>
    <span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;z1 * (z2 * z3) = (z1 * z2) * z3&quot;</span><span class="br0">&#41;</span> 
<span style="color: #0000ff;">else</span>:
    <span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;z1 * (z2 * z3) &ne; (z1 * z2) * z3&quot;</span><span class="br0">&#41;</span> 
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
&nbsp;
<span style="color: #808080;"># addition de 2 polyn&ocirc;mes</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;II-A. Addition de 2 polyn&ocirc;mes<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># cr&eacute;ation du 1er objet de la classe Polynome : 1 + 2x + x^2</span>
p1 = Polynome<span class="br0">&#40;</span><span class="br0">&#91;</span><span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">2</span>, <span style="color: #cc66cc;">1</span><span class="br0">&#93;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># cr&eacute;ation du 2e objet Polynome : 1 + x</span>
p2 = Polynome<span class="br0">&#40;</span><span class="br0">&#91;</span><span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">1</span><span class="br0">&#93;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche l'appartenance de p1 et p2 &agrave; l'ensemble &#8477;[X]</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span>str<span class="br0">&#40;</span>p1<span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot; &isin; &quot;</span> + anneau<span class="br0">&#40;</span>p1<span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span>str<span class="br0">&#40;</span>p2<span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot; &isin; &quot;</span> + anneau<span class="br0">&#40;</span>p2<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># addition des 2 polyn&ocirc;mes</span>
p = p1+p2
&nbsp;
<span style="color: #808080;"># affiche le r&eacute;sultat de l'addition</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;(&quot;</span> + str<span class="br0">&#40;</span>p1<span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot;)&quot;</span> + <span style="color: #FF0000;">&quot; + &quot;</span> + <span style="color: #FF0000;">&quot;(&quot;</span> + str<span class="br0">&#40;</span>p2<span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot;)&quot;</span> + <span style="color: #FF0000;">&quot; = &quot;</span> + str<span class="br0">&#40;</span>p<span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche l'appartenance de p &agrave; l'ensemble &#8477;[X]</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span>str<span class="br0">&#40;</span>p<span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot; &isin; &quot;</span> + anneau<span class="br0">&#40;</span>p<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># multiplication de 2 polyn&ocirc;mes</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;II-B. Multiplication de 2 polyn&ocirc;mes<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># cr&eacute;ation du 1er objet de la classe Polynome : 1 + x</span>
p1 = Polynome<span class="br0">&#40;</span><span class="br0">&#91;</span><span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">1</span><span class="br0">&#93;</span><span class="br0">&#41;</span> 
&nbsp;
<span style="color: #808080;"># cr&eacute;ation du 2e objet de la classe Polynome : 1 + 2x</span>
p2 = Polynome<span class="br0">&#40;</span><span class="br0">&#91;</span><span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">2</span><span class="br0">&#93;</span><span class="br0">&#41;</span> 
&nbsp;
<span style="color: #808080;"># affiche l'appartenance de p1 et p2 &agrave; l'ensemble &#8477;[X]</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span>str<span class="br0">&#40;</span>p1<span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot; &isin; &quot;</span> + anneau<span class="br0">&#40;</span>p1<span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span>str<span class="br0">&#40;</span>p2<span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot; &isin; &quot;</span> + anneau<span class="br0">&#40;</span>p2<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># produit des 2 polyn&ocirc;mes</span>
p = p1*p2
&nbsp;
<span style="color: #808080;"># affiche le r&eacute;sultat de la multiplication de p1 par p2</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;(&quot;</span> + str<span class="br0">&#40;</span>p1<span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot;)&quot;</span> + <span style="color: #FF0000;">&quot;(&quot;</span> + str<span class="br0">&#40;</span>p2<span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot;)&quot;</span> + <span style="color: #FF0000;">&quot; = &quot;</span> + str<span class="br0">&#40;</span>p<span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche l'appartenance de p &agrave; l'ensemble &#8477;[X]</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span>str<span class="br0">&#40;</span>p<span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot; &isin; &quot;</span> + anneau<span class="br0">&#40;</span>p<span class="br0">&#41;</span><span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
<br />
<b>V. Conclusion</b><br />
<br />
Comme on a pu le montrer, l'ensemble des nombres complexes et celui des polynômes constituent donc des anneaux munis de lois de composition interne, à savoir l'addition et la multiplication. <br />
<br />
Les éléments de ces anneaux peuvent facilement être représentés en Python afin de pouvoir ensuite réaliser des opérations entre ces objets mathématiques, un peu comme on le ferait sur des nombres entiers.<br />
<br />
Ces opérations peuvent bien sûr être étendues à d'autres objets mathématiques, comme par exemple les fonctions continues ou les séries formelles.<br />
<br />
<br />
<b>Sources :</b><br />
<br />
<a href="https://fr.wikipedia.org/wiki/Anneau_(math%C3%A9matiques)" target="_blank">https://fr.wikipedia.org/wiki/Anneau...C3%A9matiques)</a><br />
<a href="https://fr.wikipedia.org/wiki/Loi_de_composition_interne" target="_blank">https://fr.wikipedia.org/wiki/Loi_de...sition_interne</a><br />
<a href="https://fr.wikipedia.org/wiki/Nombre_complexe" target="_blank">https://fr.wikipedia.org/wiki/Nombre_complexe</a><br />
<a href="https://fr.wikipedia.org/wiki/Polyn%C3%B4me" target="_blank">https://fr.wikipedia.org/wiki/Polyn%C3%B4me</a><br />
<a href="https://fr.wikipedia.org/wiki/Calcul_formel" target="_blank">https://fr.wikipedia.org/wiki/Calcul_formel</a><br />
<a href="https://docs.python.org/fr/3/tutorial/classes.html" target="_blank">https://docs.python.org/fr/3/tutorial/classes.html</a><br />
<a href="https://docs.python.org/fr/3/reference/datamodel.html#emulating-numeric-types" target="_blank">https://docs.python.org/fr/3/referen...-numeric-types</a></font></blockquote>

]]></content:encoded>
			<dc:creator>User</dc:creator>
			<guid isPermaLink="true">https://www.developpez.net/forums/blogs/44027-user/b10581/calcul-formel-python-etendre-operations-nombres-entiers-d-autres-objets-mathematiques/</guid>
		</item>
		<item>
			<title>Mathématiques et Python : initiation au problème de la somme de sous-ensembles (subset sum problem)</title>
			<link>https://www.developpez.net/forums/blogs/44027-user/b10575/mathematiques-python-initiation-probleme-somme-sous-ensembles-subset-sum-problem/</link>
			<pubDate>Mon, 12 Feb 2024 07:24:34 GMT</pubDate>
			<description><![CDATA[*I. Introduction* 
 
D'après...]]></description>
			<content:encoded><![CDATA[<blockquote class="blogcontent restore"><font size="3"><b>I. Introduction</b><br />
<br />
D'après Wikipedia, le <a href="https://fr.wikipedia.org/wiki/Probl%C3%A8me_de_la_somme_de_sous-ensembles" target="_blank">problème de la somme de sous-ensembles</a> (en anglais : subset sum problem) est un problème de décision important en complexité algorithmique et en cryptologie. <br />
<br />
Il peut être décrit de la manière suivante : étant donné un ensemble <b>E</b> de <b>n</b> entiers, existe-t-il un sous-ensemble de <b>E</b> dont la somme des éléments est nulle ? <br />
<br />
Par exemple, pour l'ensemble <b>{-8, -3, -2, 4, 5}</b>, la réponse est oui car la somme des éléments du sous-ensemble <b>{-3, -2, 5}</b> est nulle, par contre pour <b>{-6, -1, 2, 3, 8}</b> la réponse est non.<br />
<br />
Ce problème est <a href="https://fr.wikipedia.org/wiki/Probl%C3%A8me_NP-complet" target="_blank">NP-complet</a>, c'est-à-dire considéré comme difficile à résoudre efficacement par un algorithme.<br />
<br />
On souhaite dans notre cas montrer comment générer l'<a href="https://fr.wikipedia.org/wiki/Ensemble_des_parties_d%27un_ensemble" target="_blank">ensemble des parties de l'ensemble <b>E</b></a> en économisant la mémoire, puis implémenter cette méthode en Python pour rechercher les combinaisons dont la somme est nulle.<br />
<br />
Dans le même esprit, on va également créer une fonction génératrice qui va permettre d'obtenir les sous-ensembles sans avoir besoin de les stocker dans une liste.<br />
<br />
<br />
<br />
<b>II. Génération des sous-ensembles</b><br />
<br />
<b>II-A. Définition : Ensemble des parties d'un ensemble</b><br />
<br />
En mathématiques, l'<a href="https://fr.wikipedia.org/wiki/Ensemble_des_parties_d%27un_ensemble" target="_blank">ensemble des parties d'un ensemble</a>, parfois appelé ensemble puissance, est l'ensemble de tous les sous-ensembles d'un ensemble donné (y compris cet ensemble lui-même et l'ensemble vide). <br />
<br />
Soit par exemple <b><i>E</i></b> un ensemble de <b>3</b> éléments :<br />
<br />
<span class="highlight"><i>E</i> = {a, b, c}</span><br />
<br />
L'ensemble des parties de cet ensemble donne :<br />
<br />
<span class="highlight">&#119875;(<i>E</i>) = {&#8709;, {a}, {b}, {c}, {a, b}, {a, c}, {b, c}, {a, b, c}}</span><br />
<br />
Il y a donc <b>2<sup>3</sup></b> parties dans <b><i>E</i></b> :<br />
<br />
<span class="highlight">card(&#119875;(<i>E</i>)) = 2<sup>card(<i>E</i>)</sup> = 2<sup>3</sup> = 8</span><br />
<br />
où <b>card(<i>E</i>)</b> représente la cardinalité ou le nombre d'éléments de l'ensemble <b><i>E</i></b>.<br />
<br />
Plus généralement, pour un ensemble à <b>n</b> éléments on a donc <b>2<sup>n</sup></b> parties.<br />
<br />
On retrouve cette formule quand on souhaite calculer la somme des <a href="https://fr.wikipedia.org/wiki/Coefficient_binomial" target="_blank">coefficients binomiaux</a>. <br />
<br />
<br />
<b>II-B. Génération des sous-ensembles : méthode naïve avec les codes binaires</b><br />
<br />
On numérote d'abord les <b>2<sup>n</sup></b> parties d'un ensemble à <b>n</b> éléments de <b>0</b> à <b>2<sup>n</sup>-1</b>, puis on évalue le code binaire de chacun de ces numéros. Enfin, on applique la règle suivante pour obtenir le sous-ensemble à partir du code binaire :<br />
<br />
<ul><li style="">bit à <b>0</b> : on ignore l'élément à la même position dans l'ensemble de départ ;</li><li style="">bit à <b>1</b> : on retient l'élément à cette position dans l'ensemble de départ.</li></ul><br />
Si on part à nouveau de notre ensemble à <b>3</b> éléments :<br />
<br />
<span class="highlight"><i>E</i> = {a, b, c}</span><br />
<br />
On obtient ainsi la liste numérotée des parties de cet ensemble :<br />
<br />
<img src="https://www.developpez.net/forums/attachments/p650479d1707385615/autres-langages/general-visual-basic-6-vbscript/vb-6-anterieur/vb6-winsock-envoi-donn-es/codes_binaires.png/" border="0" alt="Nom : codes_binaires.png
Affichages : 19960
Taille : 10,1 Ko"  style="float: CONFIG" /><br />
<br />
La colonne <b>Nombre d'ajouts</b> correspondant au nombre total d'ajouts d'éléments nécessaires pour composer le sous-ensemble.<br />
<br />
On remarque que pour créer chacune des parties de l'ensemble de départ, on a besoin d'ajouter à chaque fois tous les éléments qui composent ces sous-ensembles.<br />
<br />
<br />
<b>II-C. Génération des sous-ensembles à l'aide du produit cartésien</b><br />
<br />
Comme on a pu le montrer dans un précédent billet, on peut générer les parties d'un ensemble à l'aide du produit cartésien de deux ensembles.<br />
<br />
Reprenons notre ensemble <b><i>E</i></b> à <b>3</b> éléments :<br />
<br />
<span class="highlight"><i>E</i> = {a, b, c}</span><br />
<br />
Soit maintenant le produit cartésien des <b>3</b> sous-ensembles :<br />
<br />
<span class="highlight">&#119875; = {(), a}&#8727;{(), b}&#8727;{(), c}</span><br />
<br />
Qui donne après regroupement des sous-ensembles de même taille :<br />
<br />
<span class="highlight">&#119875; = {(), a, b, c, (a, b), (a, c), (b, c), (a, b, c)}</span><br />
<br />
On reconnaît là l'ensemble des parties de l'ensemble <b><i>E</i></b> que l'on peut réécrire plus proprement :<br />
<br />
<span class="highlight">&#119875;(<i>E</i>) = {&#8709;, {a}, {b}, {c}, {a, b}, {a, c}, {b, c}, {a, b, c}}</span><br />
<br />
Un peu comme si on souhaitait développer le produit de facteurs :<br />
<br />
<span class="highlight">&#119875; = (1+a)(1+b)(1+c)</span><br />
<span class="highlight"><font color="#D3D3D3">&#119875; </font>= &#8206;(1 + a + b + ab)(1+c) = 1 + a + b + ab + c + ac + bc + abc</span><br />
<span class="highlight"><font color="#D3D3D3">&#119875; </font>= 1 + a + b + c + ab + ac + bc + abc</span><br />
<br />
<br />
On peut modéliser ce problème à l'aide d'un arbre binaire sur lequel on génère les sous-ensembles de <b>E</b> :<br />
<br />
<img src="https://www.developpez.net/forums/attachments/p651150d1708500832/autres-langages/general-visual-basic-6-vbscript/vb-6-anterieur/vb6-winsock-envoi-donn-es/arbre_binaire1.png/" border="0" alt="Nom : arbre_binaire1.png
Affichages : 4652
Taille : 21,0 Ko"  style="float: CONFIG" /><br />
<br />
On remarque cette fois que pour créer chacune des parties de l'ensemble de départ, on a juste besoin d'ajouter le nouvel élément au sous-ensemble du niveau supérieur en descendant à droite dans l'arbre.<br />
<br />
Il s'agit d'un principe utilisé en <a href="https://fr.wikipedia.org/wiki/Programmation_dynamique" target="_blank">programmation dynamique</a>.<br />
<br />
<br />
<br />
<b>III. Problème de la somme de sous-ensembles</b><br />
<br />
Prenons maintenant l'ensemble de départ <b>E = {-5, 1, 2, 3}</b> dans lequel on souhaite rechercher un sous-ensemble dont la somme des nombres entiers soit nulle.<br />
<br />
On peut à nouveau modéliser ce problème à l'aide d'un arbre binaire sur lequel on génère les sous-ensembles de <b>E</b> :<br />
<br />
<img src="https://www.developpez.net/forums/attachments/p651151d1708500861/autres-langages/general-visual-basic-6-vbscript/vb-6-anterieur/vb6-winsock-envoi-donn-es/arbre_binaire2.png/" border="0" alt="Nom : arbre_binaire2.png
Affichages : 4620
Taille : 21,7 Ko"  style="float: CONFIG" /><br />
<br />
On peut maintenant compter le nombre d'ajouts nécessaires avant d'obtenir une combinaison d'entiers dont la somme est nulle :<br />
<br />
<img src="https://www.developpez.net/forums/attachments/p651152d1708500900/autres-langages/general-visual-basic-6-vbscript/vb-6-anterieur/vb6-winsock-envoi-donn-es/tableau_arbre.png/" border="0" alt="Nom : tableau_arbre.png
Affichages : 4625
Taille : 15,3 Ko"  style="float: CONFIG" /><br />
<br />
On a donc besoin de réaliser seulement <b>13</b> ajouts avant de trouver la bonne combinaison, et <b>15</b> sont nécessaires pour générer la totalité des sous-ensembles. <br />
<br />
Alors que dans la version avec les code binaires, on aurait eu besoin de <b>20</b> ajouts pour identifier la première somme nulle et <b>32</b> au total :<br />
<br />
<img src="https://www.developpez.net/forums/attachments/p650610d1707589083/autres-langages/general-visual-basic-6-vbscript/vb-6-anterieur/vb6-winsock-envoi-donn-es/tableau_codes_binaires.png/" border="0" alt="Nom : tableau_codes_binaires.png
Affichages : 5318
Taille : 15,9 Ko"  style="float: CONFIG" /><br />
<br />
Il existe bien sûr d'autres moyens pour optimiser l'algorithme, mais notre objectif sera donc avant tout de chercher à économiser la mémoire.<br />
<br />
<br />
<b>IV. Implémentation en Python</b><br />
<br />
Un <a href="https://docs.python.org/fr/3/tutorial/datastructures.html#sets" target="_blank">ensemble ou Set</a> forme un type de données Python. Il s'agit d'une collection non ordonnée sans élément en double.<br />
<br />
Toutefois, on souhaite dans notre cas pouvoir conserver l'ordre d'ajout des éléments et pouvoir éventuellement les trier. C'est pourquoi, par commodité, on ajoutera les éléments à une liste plutôt qu'à un Set.<br />
<br />
<br />
<b>IV-A. Génération des sous-ensembles à partir de leur code binaire</b><br />
<br />
On présente maintenant la fonction qui génère les parties d'un ensemble de nombres entiers à partir de leur code binaire et retient celles à somme nulle :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">def</span> subset_sum_v1<span class="br0">&#40;</span>elements<span class="br0">&#41;</span>:
    <span style="color: #808080;"># fonction permettant de g&eacute;n&eacute;rer l'ensemble des parties de la liste d'&eacute;l&eacute;ments</span>
&nbsp;
    <span style="color: #808080;"># nombre d'&eacute;l&eacute;ments de l'ensemble</span>
    nombre_elements=len<span class="br0">&#40;</span>elements<span class="br0">&#41;</span> 
&nbsp;
    <span style="color: #808080;"># nombre total de parties de l'ensemble : 2^card(E)</span>
    nombre_parties=<span style="color: #cc66cc;">2</span>**nombre_elements
&nbsp;
    <span style="color: #808080;"># initialisation de la liste des parties</span>
    parties = <span class="br0">&#91;</span><span class="br0">&#93;</span>
    resultats = <span class="br0">&#91;</span><span class="br0">&#93;</span>
&nbsp;
    <span style="color: #808080;"># parcours des num&eacute;ros ou indices des parties : 0 -&gt; nombre_parties-1</span>
    <span style="color: #0000ff;">for</span> indice_partie <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span>nombre_parties<span class="br0">&#41;</span>:
        <span style="color: #808080;"># conversion du num&eacute;ro ou de l'indice en code binaire : 1 -&gt; 001</span>
        code_binaire = <span style="color: #FF0000;">&quot;{0:0{1}b}&quot;</span>.format<span class="br0">&#40;</span>indice_partie, nombre_elements<span class="br0">&#41;</span>
&nbsp;
        <span style="color: #808080;"># cr&eacute;ation du sous-ensemble &agrave; partir du code binaire et de l'ensemble de d&eacute;part : 001 et {a,b,c} -&gt; {c}</span>
        partie = tuple<span class="br0">&#40;</span><span class="br0">&#91;</span>element <span style="color: #0000ff;">for</span> element, bit <span style="color: #0000ff;">in</span> zip<span class="br0">&#40;</span>elements, code_binaire<span class="br0">&#41;</span> <span style="color: #0000ff;">if</span> bit==<span style="color: #FF0000;">'1'</span><span class="br0">&#93;</span><span class="br0">&#41;</span>
&nbsp;
        <span style="color: #808080;"># ajout de la partie &agrave; la liste</span>
        parties.append<span class="br0">&#40;</span>partie<span class="br0">&#41;</span>
&nbsp;
        <span style="color: #0000ff;">if</span> partie!=<span class="br0">&#40;</span><span class="br0">&#41;</span> <span style="color: #0000ff;">and</span> sum<span class="br0">&#40;</span>partie<span class="br0">&#41;</span>==<span style="color: #cc66cc;">0</span>:
            resultats.append<span class="br0">&#40;</span>partie<span class="br0">&#41;</span>
&nbsp;
&nbsp;
    <span style="color: #808080;"># renvoi la liste des parties et les sous-ensembles &agrave; somme nulle</span>
    <span style="color: #0000ff;">return</span> <span class="br0">&#40;</span>parties, resultats<span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
Testons maintenant la fonction :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #808080;"># cr&eacute;ation de l'ensemble E = {-5, 1, 2, 3}</span>
E = Ensemble<span class="br0">&#40;</span><span class="br0">&#91;</span>-<span style="color: #cc66cc;">5</span>, <span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">2</span>, <span style="color: #cc66cc;">3</span><span class="br0">&#93;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;E = &quot;</span> + str<span class="br0">&#40;</span>E<span class="br0">&#41;</span>+ <span style="color: #FF0000;">&quot;<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># g&eacute;n&egrave;re l'ensemble des parties de E dans P</span>
P = E.subset_sum<span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche les parties</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;P(E) = &quot;</span> + str<span class="br0">&#40;</span>P<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche les sous-ensembles dont la somme est nulle</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Sommes nulles = &quot;</span> + str<span class="br0">&#40;</span>P.resultats<span class="br0">&#41;</span>+ <span style="color: #FF0000;">&quot;<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
Le code affiche :<br />
<br />
<span class="highlight"><font color="#000080">P(E) = {{}, {3}, {2}, {2, 3}, {1}, {1, 3}, {1, 2}, {1, 2, 3}, {-5}, {-5, 3}, {-5, 2}, {-5, 2, 3}, {-5, 1}, {-5, 1, 3}, {-5, 1, 2}, {-5, 1, 2, 3}}<br />
<br />
Sommes nulles = [(-5, 2, 3)]<br />
</font></span><br />
<br />
<br />
<b>IV-B. Génération des sous-ensembles à l'aide du produit cartésien</b><br />
<br />
Pour représenter ces ensembles en <b>Python</b> et pouvoir réaliser des opérations entre eux, il nous faut utiliser notre classe <a href="https://python.developpez.com/actu/349152/Python-generer-l-ensemble-des-parties-d-un-ensemble-un-billet-blog-de-Denis-Hulo/" target="_blank">classe Ensemble</a> :<br />
<br />
<img src="https://www.developpez.net/forums/attachments/p650443d1707325723/autres-langages/general-visual-basic-6-vbscript/vb-6-anterieur/vb6-winsock-envoi-donn-es/classe_ensemble.png/" border="0" alt="Nom : classe_ensemble.png
Affichages : 5298
Taille : 9,1 Ko"  style="float: CONFIG" /><br />
<br />
On va en plus initialiser la liste des résultats du problème de subset sum au moment de la création de l'objet :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:192px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br /></div></td><td valign="top"><pre style="margin: 0">class Ensemble:
 
    def __init__(self, elements, contient_parties=False, resultats=[]):
        # méthode constructeur de la classe
 
        # on définit la liste des éléments uniques de l'ensemble en conservant l'ordre. Exemple : [&quot;a&quot;, &quot;b&quot;, &quot;b&quot;, &quot;c&quot;] -&gt; [&quot;a&quot;, &quot;b&quot;, &quot;c&quot;] -&gt; {a, b, c}
        self.elements = [ei for i,ei in enumerate(elements) if ei not in elements[:i]]
 
        # on indique s'il s'agit de parties d'un ensemble
        self.contient_parties = contient_parties

        # on initialise l'attribut résultats
        self.resultats = resultats</pre></td></tr></table></pre>
</div><br />
<br />
<b>IV-B-1. Surcharge de l'opérateur « <b>*</b> »</b><br />
<br />
Nous devons également modifier légèrement la méthode <b><font color="#696969">__mul__()</font></b> de notre classe :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">class</span> Ensemble:
    ....
    <span style="color: #0000ff;">def</span> <span style="color: #0080ff;">__mul__</span><span class="br0">&#40;</span>self, other<span class="br0">&#41;</span>:
        <span style="color: #808080;"># m&eacute;thode permettant de red&eacute;finir l'op&eacute;rateur &laquo; * &raquo; pour 2 ensembles d'&eacute;l&eacute;ments : E1 * E2 = {a, b} * {c, d} = {(a,c), (a,d), (b,c), (b,d)}</span>
&nbsp;
        <span style="color: #808080;"># initialisation de la liste d'&eacute;l&eacute;ments</span>
        E = Ensemble<span class="br0">&#40;</span><span class="br0">&#91;</span><span class="br0">&#93;</span>, self.resultats<span class="br0">&#91;</span>:<span class="br0">&#93;</span><span class="br0">&#41;</span>
&nbsp;
        <span style="color: #808080;"># parcours de la liste d'&eacute;l&eacute;ments de self</span>
        <span style="color: #0000ff;">for</span> ei <span style="color: #0000ff;">in</span> self.elements:
            <span style="color: #0000ff;">if</span> <span style="color: #0000ff;">not</span> isinstance<span class="br0">&#40;</span>ei, tuple<span class="br0">&#41;</span>: ei=<span class="br0">&#40;</span>ei,<span class="br0">&#41;</span> <span style="color: #808080;"># si ei n'est pas un tuple on en cr&eacute;e un.</span>
            <span style="color: #808080;"># parcours de la liste d'&eacute;l&eacute;ments de other</span>
            <span style="color: #0000ff;">for</span> ej <span style="color: #0000ff;">in</span> other.elements:
&nbsp;
                <span style="color: #0000ff;">if</span> <span style="color: #0000ff;">not</span> isinstance<span class="br0">&#40;</span>ej, tuple<span class="br0">&#41;</span>: ej=<span class="br0">&#40;</span>ej,<span class="br0">&#41;</span> <span style="color: #808080;"># si ej n'est pas un tuple on en cr&eacute;e un.</span>
&nbsp;
                <span style="color: #0000ff;">if</span> len<span class="br0">&#40;</span>ej<span class="br0">&#41;</span>&lt;=<span style="color: #cc66cc;">1</span>: <span style="color: #808080;"># si le tuple ej contient 0 ou 1 &eacute;l&eacute;ment</span>
                    subset = ei + ej <span style="color: #808080;"># cr&eacute;ation du sous-ensemble</span>
                <span style="color: #0000ff;">else</span>: <span style="color: #808080;"># sinon, si le tuple ej contient plus de 1 &eacute;l&eacute;ment</span>
                    subset = ei + <span class="br0">&#40;</span>ej,<span class="br0">&#41;</span> <span style="color: #808080;"># cr&eacute;ation du sous-ensemble</span>
&nbsp;
                <span style="color: #808080;"># si le sous-ensemble contient des entiers dont la somme est nulle</span>
                <span style="color: #0000ff;">if</span> ej!=<span class="br0">&#40;</span><span class="br0">&#41;</span> <span style="color: #0000ff;">and</span> sum<span class="br0">&#40;</span>subset<span class="br0">&#41;</span>==<span style="color: #cc66cc;">0</span>:
                    E.resultats.append<span class="br0">&#40;</span>subset<span class="br0">&#41;</span>
&nbsp;
                <span style="color: #808080;"># ajout du couple d'&eacute;l&eacute;ments &agrave; la liste. Exemple : E.elements = E.elements + [(ei,ej)]  </span>
                E.elements.append<span class="br0">&#40;</span>subset<span class="br0">&#41;</span>
&nbsp;
        <span style="color: #808080;"># renvoie l'ensemble produit des 2 autres ensembles pass&eacute;s en argument</span>
        <span style="color: #0000ff;">return</span> E</pre></td></tr></table></pre>
</div><br />
Cette méthode permet donc d'obtenir le produit de <b>2</b> ensembles : <br />
<br />
<span class="highlight">E1 * E2 = {1, 2} * {3, 4} = {(1, 3), (1, 4), (2, 3), (2, 4)}</span><br />
<br />
On a juste besoin de vérifier en plus si la somme des entiers du sous-ensemble obtenu est nulle pour l'ajouter ou pas aux résultats.<br />
<br />
Testons maintenant l'opérateur « * » portant sur <b>2</b> objets de la classe <b>Ensemble</b> :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:156px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #808080;"># cr&eacute;ation du 1er objet Ensemble : E1 = {1, 2}</span>
E1 = Ensemble<span class="br0">&#40;</span><span class="br0">&#91;</span><span style="color: #cc66cc;">1</span>,<span style="color: #cc66cc;">2</span><span class="br0">&#93;</span><span class="br0">&#41;</span> 
&nbsp;
<span style="color: #808080;"># cr&eacute;ation du 2e objet Ensemble : E2 = {3, 4}</span>
E1 = Ensemble<span class="br0">&#40;</span><span class="br0">&#91;</span><span style="color: #cc66cc;">3</span>,<span style="color: #cc66cc;">4</span><span class="br0">&#93;</span><span class="br0">&#41;</span>  
&nbsp;
E = E1 * E2 <span style="color: #808080;"># produit des 2 ensembles : E = E1 &times; E2</span>
&nbsp;
<span style="color: #808080;"># affiche le r&eacute;sultat</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;E = &quot;</span> + str<span class="br0">&#40;</span>E<span class="br0">&#41;</span><span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
Le code affiche :<br />
<br />
<span class="highlight"><font color="#000080">E = {(1, 3), (1, 4), (2, 3), (2, 4)}</font></span><br />
<br />
<br />
<b>IV-B-2. Méthode permettant de générer les sous-ensembles</b><br />
<br />
Nous allons finalement ajouter une méthode <b><font color="#696969">subset_sum</font></b> à la classe :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">class</span> Ensemble:
    ....
    <span style="color: #0000ff;">def</span> subset_sum<span class="br0">&#40;</span>self<span class="br0">&#41;</span>:
        <span style="color: #808080;"># m&eacute;thode permettant de g&eacute;n&eacute;rer l'ensemble des parties de self</span>
&nbsp;
        P = Ensemble<span class="br0">&#40;</span><span class="br0">&#91;</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#93;</span><span class="br0">&#41;</span> <span style="color: #808080;"># on part d'un ensemble contenant un tuple vide : P = {()}</span>
&nbsp;
        elements = sorted<span class="br0">&#40;</span>self.elements<span class="br0">&#41;</span>
&nbsp;
        <span style="color: #808080;"># on effectue le produit P = {(), e1}*{(), e2}* ... *{(), en}</span>
        <span style="color: #0000ff;">for</span> ei <span style="color: #0000ff;">in</span> elements:
            Ei = Ensemble<span class="br0">&#40;</span><span class="br0">&#91;</span><span class="br0">&#40;</span><span class="br0">&#41;</span>,ei<span class="br0">&#93;</span><span class="br0">&#41;</span> <span style="color: #808080;"># cr&eacute;ation de l'ensemble {(), ei}</span>
            P = P*Ei <span style="color: #808080;"># &eacute;quivalent &agrave; : P = P*{(), ei}</span>
&nbsp;
        <span style="color: #808080;"># renvoie l'ensemble des parties de self</span>
        <span style="color: #0000ff;">return</span> P</pre></td></tr></table></pre>
</div><br />
Elle permet donc de générer les combinaisons de nombres entiers en retenant celles dont la somme est nulle.<br />
<br />
On ajoute maintenant ces lignes pour tester la méthode :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #808080;"># cr&eacute;ation de l'ensemble E = {-5, 1, 2, 3}</span>
E = Ensemble<span class="br0">&#40;</span><span class="br0">&#91;</span>-<span style="color: #cc66cc;">5</span>, <span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">2</span>, <span style="color: #cc66cc;">3</span><span class="br0">&#93;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;E = &quot;</span> + str<span class="br0">&#40;</span>E<span class="br0">&#41;</span>+ <span style="color: #FF0000;">&quot;<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># g&eacute;n&egrave;re l'ensemble des parties de E dans P</span>
P = E.subset_sum<span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche les parties de E</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;P(E) = &quot;</span> + str<span class="br0">&#40;</span>P<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche les sous-ensembles dont la somme est nulle</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Sommes nulles = &quot;</span> + str<span class="br0">&#40;</span>P.resultats<span class="br0">&#41;</span>+ <span style="color: #FF0000;">&quot;<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
Le code affiche :<br />
<br />
<span class="highlight"><font color="#000080">P(E) = {{}, {3}, {2}, {2, 3}, {1}, {1, 3}, {1, 2}, {1, 2, 3}, {-5}, {-5, 3}, {-5, 2}, {-5, 2, 3}, {-5, 1}, {-5, 1, 3}, {-5, 1, 2}, {-5, 1, 2, 3}}<br />
<br />
Sommes nulles = [(-5, 2, 3)]<br />
</font></span><br />
<br />
<br />
<b>IV-C. Fonction génératrice des sous-ensembles avec yield</b><br />
<br />
Comme on a pu le constater précédemment, si la taille <b>n</b> de l'ensemble de départ augmente, le nombre de parties générées (<b><i>2</i><sup>n</sup></b>) peut très vite devenir important, ce qui risque d'entrainer des problèmes de mémoire insuffisante (MemoryError). <br />
<br />
Pour éviter ces débordements, on peut utiliser à la place une <a href="https://gayerie.dev/docs/python/python3/iterateur_generateur.html#les-fonctions-generatrices-avec-yield" target="_blank">fonction génératrice</a> qui va créer à la demande le sous-ensemble suivant sans avoir besoin de le stocker en mémoire dans une liste ou une autre structure de données.<br />
<br />
Pour cela, Python dispose du mot-clé <i>yield</i> qui permet de créer une fonction génératrice.<br />
<br />
On peut maintenant écrire la fonction permettant de générer les sous-ensembles après ajout du nouvel élément :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:192px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">def</span> gen_subsets<span class="br0">&#40;</span>sous_ensembles, element<span class="br0">&#41;</span>:
    <span style="color: #808080;"># fonction permettant de g&eacute;n&eacute;rer les nouveaux sous-ensembles apr&egrave;s ajout de l'&eacute;l&eacute;ment</span>
&nbsp;
    <span style="color: #808080;"># parcours des sous-ensembles (subset)</span>
    <span style="color: #0000ff;">for</span> subset <span style="color: #0000ff;">in</span> sous_ensembles:
&nbsp;
        <span style="color: #808080;"># ordre de renvoyer le sous-ensemble : descente &agrave; gauche dans l'arbre binaire</span>
        <span style="color: #0000ff;">yield</span> subset
&nbsp;
        <span style="color: #808080;"># cr&eacute;ation du nouveau sous-ensemble avec ajout du nouvel &eacute;l&eacute;ment</span>
        new_subset = tuple<span class="br0">&#40;</span>subset<span class="br0">&#41;</span> + <span class="br0">&#40;</span>element,<span class="br0">&#41;</span>
&nbsp;
        <span style="color: #808080;"># ordre de renvoyer le nouveau sous-ensemble  : descente &agrave; droite dans l'arbre binaire</span>
        <span style="color: #0000ff;">yield</span> new_subset</pre></td></tr></table></pre>
</div><br />
Comme les éléments de l'ensemble de départ sont triés, on peut également choisir de ne générer le nouveau sous-ensemble (new_subset) que si la somme de ses entiers est inférieure ou égale à zéro :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:72px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="26"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br /></div></td><td valign="top"><pre style="margin: 0">        <span style="color: #808080;"># on g&eacute;n&egrave;re le nouveau sous-ensemble que si la somme de ses entiers est inf&eacute;rieure ou &eacute;gale &agrave; z&eacute;ro</span>
        <span style="color: #0000ff;">if</span> sum<span class="br0">&#40;</span>new_subset<span class="br0">&#41;</span>&lt;=<span style="color: #cc66cc;">0</span>:
            <span style="color: #0000ff;">yield</span> new_subset</pre></td></tr></table></pre>
</div><br />
Enfin, on crée la fonction principale permettant de générer les sous-ensembles :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">def</span> generateur_subsets<span class="br0">&#40;</span>elements<span class="br0">&#41;</span>:
    <span style="color: #808080;"># permet de g&eacute;n&egrave;rer les sous-ensembles &agrave; partir de l'ensemble de d&eacute;part</span>
&nbsp;
    <span style="color: #808080;"># tri des &eacute;l&eacute;ments de l'ensemble de d&eacute;part</span>
    elements.sort<span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
    <span style="color: #808080;"># initialisation de la variable sous_ensembles avec un &eacute;l&eacute;ment vide : {{}}</span>
    sous_ensembles = iter<span class="br0">&#40;</span><span class="br0">&#91;</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#93;</span><span class="br0">&#41;</span>
&nbsp;
    <span style="color: #808080;"># parcours des &eacute;l&eacute;ments de la liste de d&eacute;part</span>
    <span style="color: #0000ff;">for</span> ei <span style="color: #0000ff;">in</span> elements:
        <span style="color: #808080;"># on g&eacute;n&egrave;re les nouveaux sous-ensembles apr&egrave;s ajout de ei</span>
        sous_ensembles = gen_subsets<span class="br0">&#40;</span>sous_ensembles, ei<span class="br0">&#41;</span>
&nbsp;
    <span style="color: #808080;"># renvoie la g&eacute;n&eacute;rateur permettant de parcourir les sous-ensembles obtenus</span>
    <span style="color: #0000ff;">return</span> sous_ensembles</pre></td></tr></table></pre>
</div><br />
Testons maintenant notre fonction afin de rechercher les sous-ensembles à sommes nulles :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #808080;"># cr&eacute;ation de l'ensemble E = {-5, 1, 2, 3}</span>
E = <span class="br0">&#91;</span>-<span style="color: #cc66cc;">5</span>, <span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">2</span>, <span style="color: #cc66cc;">3</span><span class="br0">&#93;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;E = &quot;</span> + str<span class="br0">&#40;</span>E<span class="br0">&#41;</span>+ <span style="color: #FF0000;">&quot;<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># cr&eacute;ation du  g&eacute;n&eacute;rateur des sous-ensembles de E</span>
gen_subsets = generateur_subsets<span class="br0">&#40;</span>E<span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># parcours des sous-ensembles</span>
<span style="color: #0000ff;">for</span> subset <span style="color: #0000ff;">in</span> gen_subsets:
&nbsp;
    <span style="color: #808080;"># si la somme des entiers du sous-ensemble subset est nulle</span>
    <span style="color: #0000ff;">if</span> subset!=<span class="br0">&#40;</span><span class="br0">&#41;</span> <span style="color: #0000ff;">and</span> sum<span class="br0">&#40;</span>subset<span class="br0">&#41;</span>==<span style="color: #cc66cc;">0</span>:
        <span style="color: #808080;"># afffiche le sous-ensemble d'entiers</span>
        <span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Somme nulle : &quot;</span> + str<span class="br0">&#40;</span>subset<span class="br0">&#41;</span><span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
Le code affiche :<br />
<br />
<span class="highlight"><font color="#000080">E = [-5, 1, 2, 3]<br />
<br />
Somme nulle : (-5, 2, 3)<br />
</font></span><br />
<br />
Cette fonction génératrice est d'ailleurs disponible dans le module présenté par la suite.<br />
<br />
<br />
<b>IV-D. Module complet</b><br />
<br />
On donne enfin le code complet du module pour effectuer les tests :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="40"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br />50<br />51<br />52<br />53<br />54<br />55<br />56<br />57<br />58<br />59<br />60<br />61<br />62<br />63<br />64<br />65<br />66<br />67<br />68<br />69<br />70<br />71<br />72<br />73<br />74<br />75<br />76<br />77<br />78<br />79<br />80<br />81<br />82<br />83<br />84<br />85<br />86<br />87<br />88<br />89<br />90<br />91<br />92<br />93<br />94<br />95<br />96<br />97<br />98<br />99<br />100<br />101<br />102<br />103<br />104<br />105<br />106<br />107<br />108<br />109<br />110<br />111<br />112<br />113<br />114<br />115<br />116<br />117<br />118<br />119<br />120<br />121<br />122<br />123<br />124<br />125<br />126<br />127<br />128<br />129<br />130<br />131<br />132<br />133<br />134<br />135<br />136<br />137<br />138<br />139<br />140<br />141<br />142<br />143<br />144<br />145<br />146<br />147<br />148<br />149<br />150<br />151<br />152<br />153<br />154<br />155<br />156<br />157<br />158<br />159<br />160<br />161<br />162<br />163<br />164<br />165<br />166<br />167<br />168<br />169<br />170<br />171<br />172<br />173<br />174<br />175<br />176<br />177<br />178<br />179<br />180<br />181<br />182<br />183<br />184<br />185<br />186<br />187<br />188<br />189<br />190<br />191<br />192<br />193<br />194<br />195<br />196<br />197<br />198<br />199<br />200<br />201<br />202<br />203<br />204<br />205<br />206<br />207<br />208<br />209<br />210<br />211<br />212<br />213<br />214<br />215<br />216<br />217<br />218<br />219<br />220<br />221<br />222<br />223<br />224<br />225<br />226<br />227<br />228<br />229<br />230<br />231<br />232<br />233<br />234<br />235<br />236<br />237<br />238<br />239<br />240<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">class</span> Ensemble:
&nbsp;
    <span style="color: #0000ff;">def</span> <span style="color: #0080ff;">__init__</span><span class="br0">&#40;</span>self, elements, contient_parties=<span style="color: #339933;">False</span>, resultats=<span class="br0">&#91;</span><span class="br0">&#93;</span><span class="br0">&#41;</span>:
        <span style="color: #808080;"># m&eacute;thode constructeur de la classe</span>
&nbsp;
        <span style="color: #808080;"># on d&eacute;finit la liste des &eacute;l&eacute;ments uniques de l'ensemble en conservant l'ordre. Exemple : [&quot;a&quot;, &quot;b&quot;, &quot;b&quot;, &quot;c&quot;] -&gt; [&quot;a&quot;, &quot;b&quot;, &quot;c&quot;] -&gt; {a, b, c}</span>
        self.elements = <span class="br0">&#91;</span>ei <span style="color: #0000ff;">for</span> i,ei <span style="color: #0000ff;">in</span> enumerate<span class="br0">&#40;</span>elements<span class="br0">&#41;</span> <span style="color: #0000ff;">if</span> ei <span style="color: #0000ff;">not</span> <span style="color: #0000ff;">in</span> elements<span class="br0">&#91;</span>:i<span class="br0">&#93;</span><span class="br0">&#93;</span>
&nbsp;
        <span style="color: #808080;"># on indique s'il s'agit de parties d'un ensemble</span>
        self.contient_parties = contient_parties
&nbsp;
        <span style="color: #808080;"># on initialise l'attribut r&eacute;sultats</span>
        self.resultats = resultats
&nbsp;
&nbsp;
    <span style="color: #0000ff;">def</span> __str__<span class="br0">&#40;</span>self<span class="br0">&#41;</span>:
        <span style="color: #808080;"># permet d'afficher l'ensemble des &eacute;l&eacute;ments ou des parties :</span>
        <span style="color: #808080;"># E = {(a,c), (a,d), (b,c), (b,d)}</span>
        <span style="color: #808080;"># E = {{}, {a}, {b}, {a,b}}</span>
&nbsp;
        <span style="color: #808080;"># suppression des apostrophes (') et copie dans une cha&icirc;ne : [('a','c'), ('a','d'), ('b','c'), ('b','d')] -&gt; [(a,c), (a,d), (b,c), (b,d)]</span>
        s = str<span class="br0">&#40;</span>self.elements<span class="br0">&#41;</span>.replace<span class="br0">&#40;</span><span style="color: #FF0000;">&quot;'&quot;</span>,<span style="color: #FF0000;">&quot;&quot;</span><span class="br0">&#41;</span>
&nbsp;
        <span style="color: #808080;"># remplacement des crochets par des accolades pour repr&eacute;senter l'ensemble : [(a,c), (a,d), (b,c), (b,d)] -&gt; {(a,c), (a,d), (b,c), (b,d)}</span>
        s = s.replace<span class="br0">&#40;</span><span style="color: #FF0000;">&quot;[&quot;</span>,<span style="color: #FF0000;">&quot;{&quot;</span><span class="br0">&#41;</span>.replace<span class="br0">&#40;</span><span style="color: #FF0000;">&quot;]&quot;</span>,<span style="color: #FF0000;">&quot;}&quot;</span><span class="br0">&#41;</span>
        s = s.replace<span class="br0">&#40;</span><span style="color: #FF0000;">&quot;,)&quot;</span>,<span style="color: #FF0000;">&quot;)&quot;</span><span class="br0">&#41;</span>
&nbsp;
        <span style="color: #0000ff;">if</span> self.contient_parties: <span style="color: #808080;"># si l'ensemble contient des parties</span>
            <span style="color: #808080;"># remplacement des parenth&egrave;ses par des accolades : {(), (a), (b), (a,b)} -&gt; {{}, {a}, {b}, {a,b}}</span>
            s = s.replace<span class="br0">&#40;</span><span style="color: #FF0000;">&quot;(&quot;</span>,<span style="color: #FF0000;">&quot;{&quot;</span><span class="br0">&#41;</span>.replace<span class="br0">&#40;</span><span style="color: #FF0000;">&quot;)&quot;</span>,<span style="color: #FF0000;">&quot;}&quot;</span><span class="br0">&#41;</span>
&nbsp;
        <span style="color: #808080;"># retourne la cha&icirc;ne de caract&egrave;res repr&eacute;sentant l'ensemble des &eacute;l&eacute;ments ou des parties</span>
        <span style="color: #0000ff;">return</span> s
&nbsp;
&nbsp;
    <span style="color: #0000ff;">def</span> __or__<span class="br0">&#40;</span>self, other<span class="br0">&#41;</span>:
        <span style="color: #808080;"># m&eacute;thode permettant de red&eacute;finir l'op&eacute;rateur d'union &laquo; | &raquo; pour 2 ensembles : E1 | E2 = {a, b} + {c, d} = {a, b, c, d}</span>
&nbsp;
        <span style="color: #808080;"># concat&eacute;nation des deux listes d'&eacute;l&eacute;ments</span>
        elements = self.elements + other.elements
&nbsp;
        <span style="color: #808080;"># renvoie l'ensenble r&eacute;sultat de la r&eacute;union des 2 autres ensembles pass&eacute;s en argument</span>
        <span style="color: #0000ff;">return</span> Ensemble<span class="br0">&#40;</span>elements<span class="br0">&#41;</span> 
&nbsp;
&nbsp;
    <span style="color: #0000ff;">def</span> <span style="color: #0080ff;">__mul__</span><span class="br0">&#40;</span>self, other<span class="br0">&#41;</span>:
        <span style="color: #808080;"># m&eacute;thode permettant de red&eacute;finir l'op&eacute;rateur &laquo; * &raquo; pour 2 ensembles d'&eacute;l&eacute;ments : E1 * E2 = {a, b} * {c, d} = {(a,c), (a,d), (b,c), (b,d)}</span>
&nbsp;
        <span style="color: #808080;"># initialisation de la liste d'&eacute;l&eacute;ments</span>
        E = Ensemble<span class="br0">&#40;</span><span class="br0">&#91;</span><span class="br0">&#93;</span>, self.resultats<span class="br0">&#91;</span>:<span class="br0">&#93;</span><span class="br0">&#41;</span>
&nbsp;
        <span style="color: #808080;"># parcours de la liste d'&eacute;l&eacute;ments de self</span>
        <span style="color: #0000ff;">for</span> ei <span style="color: #0000ff;">in</span> self.elements:
            <span style="color: #0000ff;">if</span> <span style="color: #0000ff;">not</span> isinstance<span class="br0">&#40;</span>ei, tuple<span class="br0">&#41;</span>: ei=<span class="br0">&#40;</span>ei,<span class="br0">&#41;</span> <span style="color: #808080;"># si ei n'est pas un tuple on en cr&eacute;e un.</span>
            <span style="color: #808080;"># parcours de la liste d'&eacute;l&eacute;ments de other</span>
            <span style="color: #0000ff;">for</span> ej <span style="color: #0000ff;">in</span> other.elements:
&nbsp;
                <span style="color: #0000ff;">if</span> <span style="color: #0000ff;">not</span> isinstance<span class="br0">&#40;</span>ej, tuple<span class="br0">&#41;</span>: ej=<span class="br0">&#40;</span>ej,<span class="br0">&#41;</span> <span style="color: #808080;"># si ej n'est pas un tuple on en cr&eacute;e un.</span>
&nbsp;
                <span style="color: #0000ff;">if</span> len<span class="br0">&#40;</span>ej<span class="br0">&#41;</span>&lt;=<span style="color: #cc66cc;">1</span>: <span style="color: #808080;"># si le tuple ej contient 0 ou 1 &eacute;l&eacute;ment</span>
                    subset = ei + ej <span style="color: #808080;"># cr&eacute;ation du sous-ensemble</span>
                <span style="color: #0000ff;">else</span>: <span style="color: #808080;"># sinon, si le tuple ej contient plus de 1 &eacute;l&eacute;ment</span>
                    subset = ei + <span class="br0">&#40;</span>ej,<span class="br0">&#41;</span> <span style="color: #808080;"># cr&eacute;ation du sous-ensemble</span>
&nbsp;
                <span style="color: #808080;"># si le sous-ensemble contient des entiers dont la somme est nulle</span>
                <span style="color: #0000ff;">if</span> ej!=<span class="br0">&#40;</span><span class="br0">&#41;</span> <span style="color: #0000ff;">and</span> sum<span class="br0">&#40;</span>subset<span class="br0">&#41;</span>==<span style="color: #cc66cc;">0</span>:
                    E.resultats.append<span class="br0">&#40;</span>subset<span class="br0">&#41;</span>
&nbsp;
                <span style="color: #808080;"># ajout du couple d'&eacute;l&eacute;ments &agrave; la liste. Exemple : E.elements = E.elements + [(ei,ej)]  </span>
                E.elements.append<span class="br0">&#40;</span>subset<span class="br0">&#41;</span>
&nbsp;
        <span style="color: #808080;"># renvoie l'ensemble produit des 2 autres ensembles pass&eacute;s en argument</span>
        <span style="color: #0000ff;">return</span> E
&nbsp;
&nbsp;
    <span style="color: #0000ff;">def</span> __pow__<span class="br0">&#40;</span>self, n<span class="br0">&#41;</span>:
        <span style="color: #808080;"># m&eacute;thode permettant de red&eacute;finir l'op&eacute;rateur de puissance : self ** n</span>
&nbsp;
        E = Ensemble<span class="br0">&#40;</span><span class="br0">&#91;</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#93;</span><span class="br0">&#41;</span> <span style="color: #808080;"># on part d'un ensemble contenant un tuple vide : E = {()}</span>
&nbsp;
        <span style="color: #808080;"># on multiplie n fois E par self &agrave; l'aide de l'op&eacute;rateur *</span>
        <span style="color: #0000ff;">for</span> i <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span>n<span class="br0">&#41;</span>: 
            E = E*self <span style="color: #808080;"># &eacute;quivalent &agrave; : E = E.__mul__(self)</span>
&nbsp;
        <span style="color: #808080;"># renvoie l'ensemble r&eacute;sultat de l'op&eacute;ration (self ** n)</span>
        <span style="color: #0000ff;">return</span> E 
&nbsp;
    <span style="color: #0000ff;">def</span> subset_sum<span class="br0">&#40;</span>self<span class="br0">&#41;</span>:
        <span style="color: #808080;"># m&eacute;thode permettant de g&eacute;n&eacute;rer l'ensemble des parties de self</span>
&nbsp;
        P = Ensemble<span class="br0">&#40;</span><span class="br0">&#91;</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#93;</span><span class="br0">&#41;</span> <span style="color: #808080;"># on part d'un ensemble contenant un tuple vide : P = {()}</span>
&nbsp;
        elements = self.elements
&nbsp;
        <span style="color: #808080;"># on effectue le produit P = {(), e1}*{(), e2}* ... *{(), en}</span>
        <span style="color: #0000ff;">for</span> ei <span style="color: #0000ff;">in</span> elements:
            Ei = Ensemble<span class="br0">&#40;</span><span class="br0">&#91;</span><span class="br0">&#40;</span><span class="br0">&#41;</span>,ei<span class="br0">&#93;</span><span class="br0">&#41;</span> <span style="color: #808080;"># cr&eacute;ation de l'ensemble {(), ei}</span>
            P = P*Ei <span style="color: #808080;"># &eacute;quivalent &agrave; : P = P*{(), ei}</span>
&nbsp;
        <span style="color: #808080;"># renvoie l'ensemble des parties de self</span>
        <span style="color: #0000ff;">return</span> P
&nbsp;
&nbsp;
    <span style="color: #0000ff;">def</span> <span style="color: #0080ff;">__eq__</span><span class="br0">&#40;</span>self, other<span class="br0">&#41;</span>:
        <span style="color: #808080;"># m&eacute;thode permettant de red&eacute;finir l'op&eacute;rateur &laquo; == &raquo; pour 2 ensembles</span>
&nbsp;
        <span style="color: #808080;"># renvoie True si les 2 ensembles d'&eacute;l&eacute;ments sont &eacute;gaux</span>
        <span style="color: #0000ff;">return</span> <span class="br0">&#40;</span>sorted<span class="br0">&#40;</span>self.elements<span class="br0">&#41;</span>==sorted<span class="br0">&#40;</span>other.elements<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
&nbsp;
<span style="color: #0000ff;">def</span> subset_sum_v1<span class="br0">&#40;</span>elements<span class="br0">&#41;</span>:
    <span style="color: #808080;"># fonction permettant de g&eacute;n&eacute;rer l'ensemble des parties de la liste d'&eacute;l&eacute;ments</span>
&nbsp;
    <span style="color: #808080;"># nombre d'&eacute;l&eacute;ments de l'ensemble</span>
    nombre_elements=len<span class="br0">&#40;</span>elements<span class="br0">&#41;</span> 
&nbsp;
    <span style="color: #808080;"># nombre total de parties de l'ensemble : 2^card(E)</span>
    nombre_parties=<span style="color: #cc66cc;">2</span>**nombre_elements
&nbsp;
    <span style="color: #808080;"># initialisation de la liste des parties</span>
    parties = <span class="br0">&#91;</span><span class="br0">&#93;</span>
    resultats = <span class="br0">&#91;</span><span class="br0">&#93;</span>
&nbsp;
    <span style="color: #808080;"># parcours des num&eacute;ros ou indices des parties : 0 -&gt; nombre_parties-1</span>
    <span style="color: #0000ff;">for</span> indice_partie <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span>nombre_parties<span class="br0">&#41;</span>:
        <span style="color: #808080;"># conversion du num&eacute;ro ou de l'indice en code binaire : 1 -&gt; 001</span>
        code_binaire = <span style="color: #FF0000;">&quot;{0:0{1}b}&quot;</span>.format<span class="br0">&#40;</span>indice_partie, nombre_elements<span class="br0">&#41;</span>
&nbsp;
        <span style="color: #808080;"># cr&eacute;ation du sous-ensemble &agrave; partir du code binaire et de l'ensemble de d&eacute;part : 001 et {a,b,c} -&gt; {c}</span>
        partie = tuple<span class="br0">&#40;</span><span class="br0">&#91;</span>element <span style="color: #0000ff;">for</span> element, bit <span style="color: #0000ff;">in</span> zip<span class="br0">&#40;</span>elements, code_binaire<span class="br0">&#41;</span> <span style="color: #0000ff;">if</span> bit==<span style="color: #FF0000;">'1'</span><span class="br0">&#93;</span><span class="br0">&#41;</span>
&nbsp;
        <span style="color: #808080;"># ajout de la partie &agrave; la liste</span>
        parties.append<span class="br0">&#40;</span>partie<span class="br0">&#41;</span>
&nbsp;
        <span style="color: #0000ff;">if</span> partie!=<span class="br0">&#40;</span><span class="br0">&#41;</span> <span style="color: #0000ff;">and</span> sum<span class="br0">&#40;</span>partie<span class="br0">&#41;</span>==<span style="color: #cc66cc;">0</span>:
            resultats.append<span class="br0">&#40;</span>partie<span class="br0">&#41;</span>
&nbsp;
&nbsp;
    <span style="color: #808080;"># renvoi la liste des parties et les sous-ensembles &agrave; somme nulle</span>
    <span style="color: #0000ff;">return</span> <span class="br0">&#40;</span>parties, resultats<span class="br0">&#41;</span>
&nbsp;
&nbsp;
<span style="color: #0000ff;">def</span> gen_subsets<span class="br0">&#40;</span>sous_ensembles, element<span class="br0">&#41;</span>:
    <span style="color: #808080;"># fonction permettant de g&eacute;n&eacute;rer les nouveaux sous-ensembles apr&egrave;s ajout de l'&eacute;l&eacute;ment</span>
&nbsp;
    <span style="color: #808080;"># parcours des sous-ensembles (subset)</span>
    <span style="color: #0000ff;">for</span> subset <span style="color: #0000ff;">in</span> sous_ensembles:
&nbsp;
        <span style="color: #808080;"># ordre de renvoyer le sous-ensemble : descente &agrave; gauche dans l'arbre binaire</span>
        <span style="color: #0000ff;">yield</span> subset
&nbsp;
        <span style="color: #808080;"># cr&eacute;ation du nouveau sous-ensemble avec ajout du nouvel &eacute;l&eacute;ment</span>
        new_subset = tuple<span class="br0">&#40;</span>subset<span class="br0">&#41;</span> + <span class="br0">&#40;</span>element,<span class="br0">&#41;</span>
&nbsp;
        <span style="color: #808080;"># on g&eacute;n&egrave;re le nouveau sous-ensemble que si la somme de ses entiers est inf&eacute;rieure ou &eacute;gale &agrave; z&eacute;ro :</span>
        <span style="color: #0000ff;">if</span> sum<span class="br0">&#40;</span>new_subset<span class="br0">&#41;</span>&lt;=<span style="color: #cc66cc;">0</span>:
            <span style="color: #0000ff;">yield</span> new_subset
&nbsp;
&nbsp;
<span style="color: #0000ff;">def</span> generateur_subsets<span class="br0">&#40;</span>elements<span class="br0">&#41;</span>:
    <span style="color: #808080;"># permet de g&eacute;n&egrave;rer les sous-ensembles &agrave; partir de l'ensemble de d&eacute;part</span>
&nbsp;
    <span style="color: #808080;"># tri des &eacute;l&eacute;ments de l'ensemble de d&eacute;part</span>
    elements.sort<span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
    <span style="color: #808080;"># initialisation de la variable sous_ensembles avec un &eacute;l&eacute;ment vide : {{}}</span>
    sous_ensembles = iter<span class="br0">&#40;</span><span class="br0">&#91;</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#93;</span><span class="br0">&#41;</span>
&nbsp;
    <span style="color: #808080;"># parcours des &eacute;l&eacute;ments de la liste de d&eacute;part</span>
    <span style="color: #0000ff;">for</span> ei <span style="color: #0000ff;">in</span> elements:
        <span style="color: #808080;"># on g&eacute;n&egrave;re les nouveaux sous-ensembles apr&egrave;s ajout de ei</span>
        sous_ensembles = gen_subsets<span class="br0">&#40;</span>sous_ensembles, ei<span class="br0">&#41;</span>
&nbsp;
    <span style="color: #808080;"># renvoie la g&eacute;n&eacute;rateur permettant de parcourir les sous-ensembles obtenus</span>
    <span style="color: #0000ff;">return</span> sous_ensembles
&nbsp;
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;I. Somme de sous-ensembles : m&eacute;thode avec les codes binaires <span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
E = Ensemble<span class="br0">&#40;</span><span class="br0">&#91;</span>-<span style="color: #cc66cc;">5</span>, <span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">2</span>, <span style="color: #cc66cc;">3</span><span class="br0">&#93;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;E = &quot;</span> + str<span class="br0">&#40;</span>E<span class="br0">&#41;</span>+ <span style="color: #FF0000;">&quot;<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># g&eacute;n&egrave;re l'ensemble des parties de E</span>
parties, resultats = subset_sum_v1<span class="br0">&#40;</span>E.elements<span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># cr&eacute;ation de l'ensemble &agrave; partir de la liste des parties</span>
P = Ensemble<span class="br0">&#40;</span>parties, contient_parties=<span style="color: #339933;">True</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche la liste des sous-ensembles de E</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;P(E) = &quot;</span> + str<span class="br0">&#40;</span>P<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche les sous-ensembles dont la somme des entiers est nulle</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Sommes nulles = &quot;</span> + str<span class="br0">&#40;</span>resultats<span class="br0">&#41;</span>+ <span style="color: #FF0000;">&quot;<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;=======================================================================<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;II. Somme de sous-ensembles : produit cart&eacute;sien et arbre binaire<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># cr&eacute;ation de l'ensemble E = {-5, 1, 2, 3}</span>
E = Ensemble<span class="br0">&#40;</span><span class="br0">&#91;</span>-<span style="color: #cc66cc;">5</span>, <span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">2</span>, <span style="color: #cc66cc;">3</span><span class="br0">&#93;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;E = &quot;</span> + str<span class="br0">&#40;</span>E<span class="br0">&#41;</span>+ <span style="color: #FF0000;">&quot;<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># g&eacute;n&egrave;re l'ensemble des parties de E dans P et les sous-ensembles dont la somme des entiers est nulle</span>
P = E.subset_sum<span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche les parties</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;P(E) = &quot;</span> + str<span class="br0">&#40;</span>P<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche les sous-ensembles dont la somme des entiers est nulle</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Sommes nulles = &quot;</span> + str<span class="br0">&#40;</span>P.resultats<span class="br0">&#41;</span>+ <span style="color: #FF0000;">&quot;<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;=======================================================================<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;III. Somme de sous-ensembles : fonction g&eacute;n&eacute;ratrice et arbre binaire<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># cr&eacute;ation de l'ensemble E = {-5, 1, 2, 3}</span>
E = Ensemble<span class="br0">&#40;</span><span class="br0">&#91;</span>-<span style="color: #cc66cc;">5</span>, <span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">2</span>, <span style="color: #cc66cc;">3</span><span class="br0">&#93;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;E = &quot;</span> + str<span class="br0">&#40;</span>E<span class="br0">&#41;</span>+ <span style="color: #FF0000;">&quot;<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># cr&eacute;ation du g&eacute;n&eacute;rateur des sous-ensembles de E</span>
gen_subsets = generateur_subsets<span class="br0">&#40;</span>E.elements<span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># parcours des sous-ensembles</span>
<span style="color: #0000ff;">for</span> subset <span style="color: #0000ff;">in</span> gen_subsets:
    <span style="color: #808080;"># si la somme des entiers du sous-ensemble subset est nulle</span>
    <span style="color: #0000ff;">if</span> subset!=<span class="br0">&#40;</span><span class="br0">&#41;</span> <span style="color: #0000ff;">and</span> sum<span class="br0">&#40;</span>subset<span class="br0">&#41;</span>==<span style="color: #cc66cc;">0</span>:
        <span style="color: #808080;"># afffiche le sous-ensemble d'entiers</span>
        <span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Somme nulle : &quot;</span> + str<span class="br0">&#40;</span>subset<span class="br0">&#41;</span><span class="br0">&#41;</span>
        <span style="color: #808080;"># break</span></pre></td></tr></table></pre>
</div><br />
<br />
<b>V. Conclusion</b><br />
<br />
Comme on a pu le constater, la génération des sous-ensembles sur un arbre binaire permet de conserver les éléments précédents, et donc de limiter le nombre total d'ajouts dans les sous-ensembles.<br />
<br />
Ces algorithmes ont toutefois un temps d'exécution exponentiel en fonction de la taille de l'ensemble de départ, et sont donc exploitables en pratique uniquement pour des ensembles de dimension modeste. <br />
<br />
Il existe bien sûr des algorithmes plus efficaces, utilisant notamment la programmation dynamique, mais comme on l'a déjà dit, ce type de problème est de toute façon considéré comme difficile à résoudre efficacement.<br />
<br />
<br />
<b>Sources :</b><br />
<br />
<a href="https://fr.wikipedia.org/wiki/Probl%C3%A8me_de_la_somme_de_sous-ensembles" target="_blank">https://fr.wikipedia.org/wiki/Probl%...sous-ensembles</a><br />
<a href="https://fr.wikipedia.org/wiki/Probl%C3%A8me_NP-complet" target="_blank">https://fr.wikipedia.org/wiki/Probl%C3%A8me_NP-complet</a><br />
<a href="https://fr.wikipedia.org/wiki/Ensemble_des_parties_d%27un_ensemble" target="_blank">https://fr.wikipedia.org/wiki/Ensemb...%27un_ensemble</a><br />
<a href="https://fr.wikipedia.org/wiki/Programmation_dynamique" target="_blank">https://fr.wikipedia.org/wiki/Programmation_dynamique</a><br />
<a href="https://gayerie.dev/docs/python/python3/iterateur_generateur.html" target="_blank">https://gayerie.dev/docs/python/pyth...enerateur.html</a><br />
<a href="https://fr.wikipedia.org/wiki/Lettrage_comptable" target="_blank">https://fr.wikipedia.org/wiki/Lettrage_comptable</a><br />
<a href="https://www.developpez.net/forums/d2100724/general-developpement/algorithme-mathematiques/algorithmes-structures-donnees/sous-ensemble-valeurs-dont-somme-nulle" target="_blank">https://www.developpez.net/forums/d2...nt-somme-nulle</a></font></blockquote>

]]></content:encoded>
			<dc:creator>User</dc:creator>
			<guid isPermaLink="true">https://www.developpez.net/forums/blogs/44027-user/b10575/mathematiques-python-initiation-probleme-somme-sous-ensembles-subset-sum-problem/</guid>
		</item>
		<item>
			<title>Exponentiation rapide de nombres réels et de polynômes en Python</title>
			<link>https://www.developpez.net/forums/blogs/44027-user/b10570/exponentiation-rapide-nombres-reels-polynomes-python/</link>
			<pubDate>Wed, 24 Jan 2024 08:47:25 GMT</pubDate>
			<description>*I. Introduction* 
 
Dans un...</description>
			<content:encoded><![CDATA[<blockquote class="blogcontent restore"><b>I. Introduction</b><br />
<br />
Dans un <a href="https://python.developpez.com/actu/352973/Mathematiques-et-Python-moins-Produit-de-polynomes-en-Python-principe-du-diviser-pour-regner-un-billet-blog-de-Denis-Hulo/<br />" target="_blank">précédent billet</a>, on a parlé des avantages du « diviser pour régner » dans le développement d'un produit de petits polynômes, on souhaite maintenant montrer comment réaliser une <a href="https://fr.wikipedia.org/wiki/Exponentiation_rapide" target="_blank">exponentiation rapide</a> de nombres réels et de polynômes.<br />
<br />
Pour cela, on va d'abord décrire cette méthode à l'aide d'exemples simples, pour ensuite l'implémenter en Python.<br />
<br />
<br />
<b>II. Principe de l'exponentiation rapide</b><br />
<br />
<img src="https://www.developpez.net/forums/attachment.php?attachmentid=649485&amp;d=1705747974" border="0" alt="Nom : exponentiation_rapide1.png
Affichages : 28071
Taille : 4,9 Ko"  style="float: CONFIG" /><br />
<br />
<br />
<b>II-A. Nombres réels</b><br />
<br />
Si on souhaite calculer <b>a<sup>n</sup></b>, on peut naïvement effectuer <b>n&#8722;1</b> multiplications en réalisant le produit :<br />
<br />
<b>a<sup>n</sup> = a × a × ... × a</b><br />
<br />
Cependant, l'exemple suivant montre que l'on peut calculer <b>a<sup>32</sup></b> en effectuant seulement <b>5</b> multiplications au lieu de <b>31</b> :<br />
<br />
<b>a<sup>32</sup> = a<sup>2<sup>5</sup></sup> = ((((a<sup>2</sup>)<sup>2</sup>)<sup>2</sup>)<sup>2</sup>)<sup>2</sup></b><br />
<br />
Si l'exposant est différent d'une puissance de <b>2</b>, avec par exemple <b>a<sup>41</sup></b>, on peut alors écrire :<br />
<br />
<b>a<sup>41</sup> = a × a<sup>8</sup> × a<sup>32</sup> = a × a<sup>2<sup>3</sup></sup> × a<sup>2<sup>5</sup></sup></b><br />
<br />
En remarquant que <b>a<sup>8</sup></b> est également calculé dans <b>a<sup>32</sup></b>, et en conservant sa valeur, on a en fait besoin de seulement <b>7</b> multiplications au lieu de <b>40</b>.<br />
<br />
Alors que l'algorithme naïf demande de l'ordre de <b>n</b> multiplications pour calculer <b>a<sup>n</sup></b>, l'algorithme d'exponentiation rapide a besoin seulement de l'ordre de <b>log2(n)</b> multiplications.<br />
<br />
<br />
<b>II-B. Polynômes</b><br />
<br />
Une multiplication entre deux polynômes nécessite de multiplier chaque terme du multiplicateur par chaque terme du multiplicande. <br />
<br />
Si ces deux polynômes ont <b>n</b> termes, cela exige <b>n<sup>2</sup></b> produits. La multiplication <b>(X + 2) <font size="1">×</font> (X + 2)</b> nécessite ainsi <b>4</b> multiplications entre termes.<br />
 <br />
Si on prend maintenant :<br />
<br />
<b>(X + 2)<sup>8</sup> = (X + 2) <font size="1">×</font> (X + 2) <font size="1">×</font> (X + 2) <font size="1">×</font> (X + 2) <font size="1">×</font> (X + 2) <font size="1">×</font> (X + 2) <font size="1">×</font> (X + 2) <font size="1">×</font> (X + 2)</b><br />
<br />
En développant le produit de gauche à droite, on obtient successivement :<br />
<br />
<b>(X + 2)<sup>8</sup> = ((X + 2) <font size="1">×</font> (X + 2)) <font size="1">×</font> (X + 2) <font size="1">×</font> (X + 2) <font size="1">×</font> (X + 2) <font size="1">×</font> (X + 2) <font size="1">×</font> (X + 2) <font size="1">×</font> (X + 2)</b><br />
<br />
La <b>1<sup>re</sup></b> multiplication nécessite donc <b>4</b> opérations de multiplication entre termes.<br />
<br />
En poursuivant le développement :<br />
<br />
<b>(X + 2)<sup>8</sup> = ((X<sup>2</sup> + 4X + 4) <font size="1">×</font> (X + 2)) <font size="1">×</font> (X + 2) <font size="1">×</font> (X + 2) <font size="1">×</font> (X + 2) <font size="1">×</font> (X + 2) <font size="1">×</font> (X + 2)</b><br />
<br />
On a ainsi besoin jusque là de <b>4 + 6</b> opérations de multiplication.<br />
<br />
etc..<br />
<br />
On obtient finalement <b>4 + 6 + 8 + 10 + 12 + 14 + 16 = 70</b> opérations de multiplication en tout pour ce produit.<br />
<br />
<br />
Considérons maintenant la même puissance de <b>(X + 2)</b> réarrangée :<br />
<br />
<b>(X + 2)<sup>8</sup> = (X + 2)<sup>2<sup>3</sup></sup> = (((X + 2)<sup>2</sup>)<sup>2</sup>)<sup>2</sup></b><br />
<br />
Si on effectue le développement en respectant la règle de priorité des parenthèses, on obtient successivement :<br />
<br />
<b>(X + 2)<sup>8</sup> = (((X + 2)<sup>2</sup>)<sup>2</sup>)<sup>2</sup></b><br />
<br />
<b>2×2=4</b> opérations de multiplication entre termes pour la <b>1<sup>re</sup></b> produit.<br />
<br />
Puis :<br />
<br />
<b>(X + 2)<sup>8</sup> = ((X<sup>2</sup> + 4X + 4))<sup>2</sup>)<sup>2</sup></b><br />
<br />
<b>3×3=9</b> opérations de multiplication pour le <b>2<sup>e</sup></b> produit.<br />
<br />
Et enfin :<br />
<br />
<b>(X + 2)<sup>8</sup> = (X<sup>4</sup> + 8X<sup>3</sup> + 24X<sup>2</sup> + 32X + 16)<sup>2</sup></b><br />
<br />
<b>5×5=25</b> opérations pour le dernier produit.<br />
<br />
Ce qui nous fait au total <b>4 + 9 + 25 = 38</b> opérations de multiplication entre termes au lieu de <b>70</b>.<br />
<br />
<br />
<b>III. Implémentation en Python</b><br />
<br />
<br />
<b>III-A. Exponentiation rapide de nombres réels</b><br />
<br />
L'algorithme est décrit sur la <a href="https://fr.wikipedia.org/wiki/Exponentiation_rapide#Algorithme" target="_blank">page Wikipedia</a> :<br />
<br />
Soit <b>n</b> un entier strictement supérieur à <b>1</b>, supposons que l'on sache calculer, pour chaque réel <b>x</b>, toutes les puissances <b>x<sup>k</sup></b> de <b>x</b>, pour tout <b>k</b>, tel que <b>1 &#8804; k &lt; n</b>.<br />
<br />
<ul><li style="">Si <b>n</b> est pair alors <b>x<sup>n</sup> = (x<sup>2</sup>)<sup>n/2</sup></b>. Il suffit alors de calculer <b>y<sup>n/2</sup></b> pour <b>y = x<sup>2</sup></b>.</li><li style="">Si <b>n</b> est impair et <b>n &gt; 1</b>, alors <b>x<sup>n</sup> = x(x<sup>2</sup>)<sup>(n – 1)/2</sup></b>. Il suffit de calculer <b>y<sup>(n – 1)/2</sup></b> pour <b>y = x<sup>2</sup></b> et de multiplier le résultat par <b>x</b>.</li></ul><br />
<br />
Cette remarque nous amène à l'algorithme récursif suivant qui calcule <b>x<sup>n</sup></b> pour un entier strictement positif <b>n</b> : <br />
<br />
<img src="https://www.developpez.net/forums/attachment.php?attachmentid=649490&amp;d=1705748411" border="0" alt="Nom : algo_exponentiation1.png
Affichages : 8589
Taille : 7,1 Ko"  style="float: CONFIG" /><br />
<br />
On obtient ainsi la fonction d'exponentiation rapide de nombres réels :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:192px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">def</span> puissance<span class="br0">&#40;</span>x,n<span class="br0">&#41;</span>:
    <span style="color: #808080;"># exponentiation rapide de x^n</span>
&nbsp;
    <span style="color: #808080;"># si n=1 alors on renvoie x</span>
    <span style="color: #0000ff;">if</span> n==<span style="color: #cc66cc;">1</span>:
        <span style="color: #0000ff;">return</span> x
    <span style="color: #0000ff;">else</span>: <span style="color: #808080;"># sinon</span>
        <span style="color: #808080;"># si n est pair</span>
        <span style="color: #0000ff;">if</span> <span class="br0">&#40;</span>n % <span style="color: #cc66cc;">2</span> == <span style="color: #cc66cc;">0</span><span class="br0">&#41;</span>:
            <span style="color: #808080;"># appel r&eacute;cursif : puissance(x^2,n/2)</span>
            <span style="color: #0000ff;">return</span> puissance<span class="br0">&#40;</span>x**<span style="color: #cc66cc;">2</span>,n//<span style="color: #cc66cc;">2</span><span class="br0">&#41;</span>
        <span style="color: #0000ff;">else</span>: <span style="color: #808080;"># sinon si n est impair</span>
            <span style="color: #808080;"># appel r&eacute;cursif : x*puissance(x^2,(n-1)/2)</span>
            <span style="color: #0000ff;">return</span> x*puissance<span class="br0">&#40;</span>x**<span style="color: #cc66cc;">2</span>,n//<span style="color: #cc66cc;">2</span><span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
Testons maintenant notre fonction avec ces quelques lignes :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #808080;"># nombre r&eacute;el</span>
x = <span style="color: #cc66cc;">12</span>
&nbsp;
<span style="color: #808080;"># exposant</span>
n = <span style="color: #cc66cc;">8</span>
&nbsp;
<span style="color: #808080;"># exponentiation du polyn&ocirc;me</span>
xn =  puissance<span class="br0">&#40;</span>x,n<span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;x^n = {0}^{1}&quot;</span>.format<span class="br0">&#40;</span>x,n<span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;x^n = &quot;</span> + str<span class="br0">&#40;</span>xn<span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;nombre de multiplications de l'ordre de log2({0})&quot;</span>.format<span class="br0">&#40;</span>n<span class="br0">&#41;</span><span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
Le code affiche :<br />
<br />
<span class="highlight">x^n = 12^8<br />
<br />
x^n = 429981696<br />
<br />
nombre de multiplications de l'ordre de log2(8)<br />
</span><br />
<br />
<br />
<b>III-B. Puissance de polynômes</b><br />
<br />
On utilise à nouveau notre <a href="https://algo.developpez.com/actu/339249/Mathematiques-et-Python-moins-apprendre-a-creer-une-classe-Polynome-en-Python-avec-la-surcharge-des-operateurs-un-billet-blog-de-Denis-Hulo/" target="_blank">classe Polynome</a>, comme dans le billet précédent, en ajoutant un attribut permettant de compter le nombre d'opérations de multiplication entre termes nécessaires pour développer le produit de polynômes :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:192px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">class</span> Polynome:
&nbsp;
    <span style="color: #0000ff;">def</span> <span style="color: #0080ff;">__init__</span><span class="br0">&#40;</span>self, liste_coefs=<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span><span class="br0">&#93;</span>, nbre_operations=<span style="color: #cc66cc;">0</span><span class="br0">&#41;</span>: <span style="color: #808080;"># m&eacute;thode constructeur de la classe</span>
&nbsp;
	<span style="color: #808080;"># on d&eacute;finit la liste des coefficients du polyn&ocirc;me [a0, a1, ..., an]</span>
        self.coefs = liste_coefs
&nbsp;
        <span style="color: #808080;"># on initialise le nombre d'op&eacute;rations de multiplication entre termes</span>
        self.nombre_operations = nbre_operations
&nbsp;
	<span style="color: #808080;"># suppression si n&eacute;cessaire des z&eacute;ros en queue de liste de coefficients. Exemple : [2, 3, 1, 0, 0] -&gt; [2, 3, 1]</span>
        self.reduire<span class="br0">&#40;</span><span class="br0">&#41;</span> 
&nbsp;
    ...</pre></td></tr></table></pre>
</div><br />
Le code de la méthode permettant de multiplier deux polynômes devient alors :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">class</span> Polynome:
&nbsp;
    ...    
&nbsp;
    <span style="color: #0000ff;">def</span> <span style="color: #0080ff;">__mul__</span><span class="br0">&#40;</span>self, other<span class="br0">&#41;</span>: <span style="color: #808080;"># m&eacute;thode permettant de red&eacute;finir l'op&eacute;rateur &laquo; * &raquo; pour 2 polyn&ocirc;mes : (2 + X) * (1 + 2x) =  1 + 3x + 2x^2</span>
&nbsp;
        <span style="color: #808080;"># initialisation de la liste des coefficients qu'avec des z&eacute;ros</span>
        liste_coefs=<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span><span class="br0">&#93;</span>*<span class="br0">&#40;</span>len<span class="br0">&#40;</span>self.coefs<span class="br0">&#41;</span>+len<span class="br0">&#40;</span>other.coefs<span class="br0">&#41;</span>-<span style="color: #cc66cc;">1</span><span class="br0">&#41;</span> <span style="color: #808080;"># exemple : [0, 0, 0]</span>
        <span style="color: #0000ff;">for</span> i1 <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span>len<span class="br0">&#40;</span>self.coefs<span class="br0">&#41;</span><span class="br0">&#41;</span>: <span style="color: #808080;"># parcours des indices des coefs du polyn&ocirc;me n&deg;1</span>
            <span style="color: #0000ff;">for</span> i2 <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span>len<span class="br0">&#40;</span>other.coefs<span class="br0">&#41;</span><span class="br0">&#41;</span>: <span style="color: #808080;"># parcours des indices des coefs du polyn&ocirc;me n&deg;2</span>
                <span style="color: #808080;"># multiplication des coefficients d'indices i1 et i2</span>
                liste_coefs<span class="br0">&#91;</span>i1+i2<span class="br0">&#93;</span> = liste_coefs<span class="br0">&#91;</span>i1+i2<span class="br0">&#93;</span> + self.coefs<span class="br0">&#91;</span>i1<span class="br0">&#93;</span>*other.coefs<span class="br0">&#91;</span>i2<span class="br0">&#93;</span>
&nbsp;
        poly = Polynome<span class="br0">&#40;</span>liste_coefs<span class="br0">&#41;</span> <span style="color: #808080;"># cr&eacute;ation de l'objet Polynome bas&eacute; sur la liste</span>
&nbsp;
        <span style="color: #808080;"># ajout du nombre d'op&eacute;rations de multiplication entre termes effectu&eacute;es lors de la multiplication entre polyn&ocirc;mes</span>
        poly.compteur_operations = self.compteur_operations + other.compteur_operations +  len<span class="br0">&#40;</span>self.coefs<span class="br0">&#41;</span>*len<span class="br0">&#40;</span>other.coefs<span class="br0">&#41;</span>
&nbsp;
        <span style="color: #0000ff;">return</span> poly <span style="color: #808080;"># renvoie le polyn&ocirc;me r&eacute;sultat de la multiplication</span></pre></td></tr></table></pre>
</div><br />
<u>Rappel important :</u> les objets Polynome de notre classe sont représentés par une liste de coefficients dont la longueur est égale au degré du polynôme + <b>1</b>: <br />
<br />
Par exemple le polynôme <b>X<sup>3</sup> + 2 = 2 + 0.X + 0.X<sup>2</sup> + X<sup>3</sup></b> sera représenté par <b>[2, 0, 0, 1]</b>.<br />
<br />
<br />
<b>III-B-1. Méthode classique</b><br />
<br />
On doit d'abord réécrire le code de la méthode permettant de développer une puissance de polynôme afin de pouvoir comptabiliser le nombre de multiplications entre termes :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">class</span> Polynome:
&nbsp;
    ...    
&nbsp;
    <span style="color: #0000ff;">def</span> __pow__<span class="br0">&#40;</span>self, n<span class="br0">&#41;</span>: <span style="color: #808080;"># m&eacute;thode permettant de red&eacute;finir l'op&eacute;rateur de puissance : self ** n</span>
&nbsp;
        <span style="color: #0000ff;">if</span> n==<span style="color: #cc66cc;">0</span>: <span style="color: #808080;"># si n=0</span>
            <span style="color: #0000ff;">return</span> Polynome<span class="br0">&#40;</span><span class="br0">&#91;</span><span style="color: #cc66cc;">1</span><span class="br0">&#93;</span><span class="br0">&#41;</span> <span style="color: #808080;"># on renvoie le polyn&ocirc;me &eacute;gal &agrave; 1</span>
&nbsp;
        <span style="color: #808080;"># copie de self initialis&eacute; avec le m&ecirc;me nombre d'op&eacute;rations de multiplication entre termes </span>
        poly = Polynome<span class="br0">&#40;</span>self.coefs, self.nombre_operations<span class="br0">&#41;</span>
&nbsp;
        <span style="color: #808080;"># copie de self avec un nombre d'op&eacute;rations de multiplication &agrave; 0</span>
        pol = Polynome<span class="br0">&#40;</span>self.coefs<span class="br0">&#41;</span> 
&nbsp;
        <span style="color: #0000ff;">for</span> i <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span>n-<span style="color: #cc66cc;">1</span><span class="br0">&#41;</span>: <span style="color: #808080;"># on multiplie n fois poly par pol &agrave; l'aide de l'op&eacute;rateur *            </span>
            poly = poly*pol <span style="color: #808080;"># &eacute;quivalent &agrave; : poly = poly.__mul__(pol)</span>
&nbsp;
        <span style="color: #0000ff;">return</span> poly <span style="color: #808080;"># renvoie le polyn&ocirc;me r&eacute;sultat de l'op&eacute;ration (self ** n)</span></pre></td></tr></table></pre>
</div><br />
Testons maintenant l'opérateur de puissance « ** » pour les polynômes avec la méthode classique :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #808080;"># cr&eacute;ation du polyn&ocirc;me p = 2 + X = X + 2</span>
p = Polynome<span class="br0">&#40;</span><span class="br0">&#91;</span><span style="color: #cc66cc;">2</span>,<span style="color: #cc66cc;">1</span><span class="br0">&#93;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># exposant</span>
n = <span style="color: #cc66cc;">8</span>
&nbsp;
<span style="color: #808080;"># exponentiation du polyn&ocirc;me</span>
pn = p**n
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;p^n = ({0})^{1}&quot;</span>.format<span class="br0">&#40;</span>p,n<span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;p^n = &quot;</span> + str<span class="br0">&#40;</span>pn<span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;nombre d'op&eacute;rations = &quot;</span> + str<span class="br0">&#40;</span>pn.nombre_operations<span class="br0">&#41;</span><span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
<br />
Le code affiche :<br />
<br />
<span class="highlight">p^n = (2 + X)^8<br />
<br />
p^n = 256 + 1024&#8901;X + 1792&#8901;X^2 + 1792&#8901;X^3 + 1120&#8901;X^4 + 448&#8901;X^5 + 112&#8901;X^6 + 16&#8901;X^7 + X^8<br />
<br />
nombre d'opérations = 70</span><br />
<br />
<br />
<b>III-B-2. Exponentiation rapide de polynômes</b><br />
<br />
L'algorithme d'exponentiation rapide de polynômes est le même que celui décrit sur la <a href="https://fr.wikipedia.org/wiki/Exponentiation_rapide#Algorithme" target="_blank">page Wikipedia</a> pour les nombres réels :<br />
<br />
Soit <b>n</b> un entier strictement supérieur à <b>1</b>, supposons que l'on sache développer, pour chaque polynôme <b>p</b>, toutes les puissances <b>p<sup>k</sup></b> de <b>p</b>, pour tout <b>k</b>, tel que <b>1 &#8804; k &lt; n</b>.<br />
<br />
<ul><li style="">Si <b>n</b> est pair alors <b>p<sup>n</sup> = (p<sup>2</sup>)<sup>n/2</sup></b>. Il suffit alors de développer <b>q<sup>n/2</sup></b> pour <b>q = p<sup>2</sup></b>.</li><li style="">Si <b>n</b> est impair et <b>n &gt; 1</b>, alors <b>p<sup>n</sup> = p(p<sup>2</sup>)<sup>(n – 1)/2</sup></b>. Il suffit de développer <b>q<sup>(n – 1)/2</sup></b> pour <b>q = p<sup>2</sup></b> et de multiplier le résultat par <b>p</b>.</li></ul><br />
<br />
Cette remarque nous amène à l'algorithme récursif suivant qui développe <b>p<sup>n</sup></b> pour un entier strictement positif <b>n</b> : <br />
<br />
<img src="https://www.developpez.net/forums/attachment.php?attachmentid=649489&amp;d=1705748363" border="0" alt="Nom : algo_exponentiation2.png
Affichages : 8586
Taille : 7,8 Ko"  style="float: CONFIG" /><br />
<br />
On peut alors écrire en Python la fonction d'exponentiation rapide de polynômes :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:192px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">def</span> puissance_polynome<span class="br0">&#40;</span>p,n<span class="br0">&#41;</span>:
    <span style="color: #808080;"># exponentiation rapide de p^n</span>
&nbsp;
    <span style="color: #808080;"># si n=1 alors on renvoie p</span>
    <span style="color: #0000ff;">if</span> n==<span style="color: #cc66cc;">1</span>:
        <span style="color: #0000ff;">return</span> p
    <span style="color: #0000ff;">else</span>: <span style="color: #808080;"># sinon</span>
        <span style="color: #808080;"># si n est pair</span>
        <span style="color: #0000ff;">if</span> <span class="br0">&#40;</span>n % <span style="color: #cc66cc;">2</span> == <span style="color: #cc66cc;">0</span><span class="br0">&#41;</span>:
            <span style="color: #808080;"># appel r&eacute;cursif : puissance_polynome(p^2,n/2)</span>
            <span style="color: #0000ff;">return</span> puissance_polynome<span class="br0">&#40;</span>p**<span style="color: #cc66cc;">2</span>,n//<span style="color: #cc66cc;">2</span><span class="br0">&#41;</span>
        <span style="color: #0000ff;">else</span>: <span style="color: #808080;"># sinon si n est impair</span>
            <span style="color: #808080;"># appel r&eacute;cursif : p*puissance_polynome(p^2,(n-1)/2)</span>
            <span style="color: #0000ff;">return</span> p*puissance_polynome<span class="br0">&#40;</span>p**<span style="color: #cc66cc;">2</span>,n//<span style="color: #cc66cc;">2</span><span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
Testons notre fonction avec ces quelques lignes :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #808080;"># cr&eacute;ation du polyn&ocirc;me p = 2 + X = X + 2</span>
p = Polynome<span class="br0">&#40;</span><span class="br0">&#91;</span><span style="color: #cc66cc;">2</span>,<span style="color: #cc66cc;">1</span><span class="br0">&#93;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># exposant</span>
n = <span style="color: #cc66cc;">8</span>
&nbsp;
<span style="color: #808080;"># exponentiation du polyn&ocirc;me</span>
pn = puissance_polynome<span class="br0">&#40;</span>p,n<span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;p^n = ({0})^{1}&quot;</span>.format<span class="br0">&#40;</span>p,n<span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;p^n = &quot;</span> + str<span class="br0">&#40;</span>pn<span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;nombre d'op&eacute;rations = &quot;</span> + str<span class="br0">&#40;</span>pn.nombre_operations<span class="br0">&#41;</span><span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
<br />
Le code affiche :<br />
<br />
<span class="highlight">p^n = (2 + X)^8<br />
<br />
p^n = 256 + 1024&#8901;X + 1792&#8901;X^2 + 1792&#8901;X^3 + 1120&#8901;X^4 + 448&#8901;X^5 + 112&#8901;X^6 + 16&#8901;X^7 + X^8<br />
<br />
nombre d'opérations = 38</span><br />
<br />
<br />
<b>III-C. Module complet</b><br />
<br />
On donne pour finir le contenu du module complet :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="40"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br />50<br />51<br />52<br />53<br />54<br />55<br />56<br />57<br />58<br />59<br />60<br />61<br />62<br />63<br />64<br />65<br />66<br />67<br />68<br />69<br />70<br />71<br />72<br />73<br />74<br />75<br />76<br />77<br />78<br />79<br />80<br />81<br />82<br />83<br />84<br />85<br />86<br />87<br />88<br />89<br />90<br />91<br />92<br />93<br />94<br />95<br />96<br />97<br />98<br />99<br />100<br />101<br />102<br />103<br />104<br />105<br />106<br />107<br />108<br />109<br />110<br />111<br />112<br />113<br />114<br />115<br />116<br />117<br />118<br />119<br />120<br />121<br />122<br />123<br />124<br />125<br />126<br />127<br />128<br />129<br />130<br />131<br />132<br />133<br />134<br />135<br />136<br />137<br />138<br />139<br />140<br />141<br />142<br />143<br />144<br />145<br />146<br />147<br />148<br />149<br />150<br />151<br />152<br />153<br />154<br />155<br />156<br />157<br />158<br />159<br />160<br />161<br />162<br />163<br />164<br />165<br />166<br />167<br />168<br />169<br />170<br />171<br />172<br />173<br />174<br />175<br />176<br />177<br />178<br />179<br />180<br />181<br />182<br />183<br />184<br />185<br />186<br />187<br />188<br />189<br />190<br />191<br />192<br />193<br />194<br />195<br />196<br />197<br />198<br />199<br />200<br />201<br />202<br />203<br />204<br />205<br />206<br />207<br />208<br />209<br />210<br />211<br />212<br />213<br />214<br />215<br />216<br />217<br />218<br />219<br />220<br />221<br />222<br />223<br />224<br />225<br />226<br />227<br />228<br />229<br />230<br />231<br />232<br />233<br />234<br />235<br />236<br />237<br />238<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">class</span> Polynome:
&nbsp;
    <span style="color: #0000ff;">def</span> <span style="color: #0080ff;">__init__</span><span class="br0">&#40;</span>self, liste_coefs=<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span><span class="br0">&#93;</span>, nbre_operations=<span style="color: #cc66cc;">0</span><span class="br0">&#41;</span>: <span style="color: #808080;"># m&eacute;thode constructeur de la classe</span>
&nbsp;
	<span style="color: #808080;"># on d&eacute;finit la liste des coefficients du polyn&ocirc;me [a0, a1, ..., an]</span>
        self.coefs = liste_coefs
&nbsp;
        <span style="color: #808080;"># on initialise le nombre d'op&eacute;rations de multiplication entre termes</span>
        self.nombre_operations = nbre_operations
&nbsp;
	<span style="color: #808080;"># suppression si n&eacute;cessaire des z&eacute;ros en queue de liste de coefficients. Exemple : [2, 3, 1, 0, 0] -&gt; [2, 3, 1]</span>
        self.reduire<span class="br0">&#40;</span><span class="br0">&#41;</span> 
&nbsp;
    <span style="color: #0000ff;">def</span> __str__<span class="br0">&#40;</span>self<span class="br0">&#41;</span>: <span style="color: #808080;"># permet d'afficher le polyn&ocirc;me sous la forme 1 + 2x + 3x^2</span>
        s=<span style="color: #FF0000;">&quot;&quot;</span> <span style="color: #808080;"># initialisation de la cha&icirc;ne de caract&egrave;res</span>
        <span style="color: #808080;"># on v&eacute;rifie d&#146;abord si le degr&eacute; du polyn&ocirc;me est nul</span>
        <span style="color: #0000ff;">if</span> <span class="br0">&#40;</span>len<span class="br0">&#40;</span>self.coefs<span class="br0">&#41;</span>-<span style="color: #cc66cc;">1</span>==<span style="color: #cc66cc;">0</span><span class="br0">&#41;</span>:
            <span style="color: #0000ff;">return</span> str<span class="br0">&#40;</span>self.coefs<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span><span class="br0">&#93;</span><span class="br0">&#41;</span>
        <span style="color: #0000ff;">else</span>: <span style="color: #808080;"># sinon</span>
            <span style="color: #0000ff;">if</span> self.coefs<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span><span class="br0">&#93;</span>!=<span style="color: #cc66cc;">0</span>:
                s=str<span class="br0">&#40;</span>self.coefs<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span><span class="br0">&#93;</span><span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot; + &quot;</span>
            <span style="color: #0000ff;">for</span> i <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span><span style="color: #cc66cc;">1</span>, len<span class="br0">&#40;</span>self.coefs<span class="br0">&#41;</span><span class="br0">&#41;</span>: <span style="color: #808080;"># parcours des indices des coefficients du polyn&ocirc;me : [a1, a2, ..., an]</span>
                <span style="color: #0000ff;">if</span> self.coefs<span class="br0">&#91;</span>i<span class="br0">&#93;</span>!=<span style="color: #cc66cc;">0</span>: <span style="color: #808080;"># si le coefficient de degr&eacute; i n'est pas nul</span>
                    <span style="color: #0000ff;">if</span> self.coefs<span class="br0">&#91;</span>i<span class="br0">&#93;</span>!=<span style="color: #cc66cc;">1</span>: <span style="color: #808080;"># si le coefficient de degr&eacute; i est diff&eacute;rent de 1</span>
                        s+=<span style="color: #FF0000;">&quot;{}&sdot;X^{} + &quot;</span>.format<span class="br0">&#40;</span>self.coefs<span class="br0">&#91;</span>i<span class="br0">&#93;</span>,i<span class="br0">&#41;</span>
                    <span style="color: #0000ff;">else</span>: s+=<span style="color: #FF0000;">&quot;X^{} + &quot;</span>.format<span class="br0">&#40;</span>i<span class="br0">&#41;</span>  
&nbsp;
            <span style="color: #808080;"># &eacute;limination des caract&egrave;res en trop           </span>
            s = s<span class="br0">&#91;</span>:-<span style="color: #cc66cc;">3</span><span class="br0">&#93;</span>.replace<span class="br0">&#40;</span><span style="color: #FF0000;">&quot;+ -&quot;</span>, <span style="color: #FF0000;">&quot;- &quot;</span><span class="br0">&#41;</span>.replace<span class="br0">&#40;</span><span style="color: #FF0000;">&quot;X^1 &quot;</span>,<span style="color: #FF0000;">&quot;X &quot;</span><span class="br0">&#41;</span>.replace<span class="br0">&#40;</span><span style="color: #FF0000;">&quot; 1&sdot;X&quot;</span>,<span style="color: #FF0000;">&quot; X&quot;</span><span class="br0">&#41;</span>
            <span style="color: #0000ff;">if</span> s<span class="br0">&#91;</span>-<span style="color: #cc66cc;">2</span>:<span class="br0">&#93;</span>==<span style="color: #FF0000;">&quot;^1&quot;</span>: s = s<span class="br0">&#91;</span>:-<span style="color: #cc66cc;">2</span><span class="br0">&#93;</span>
            <span style="color: #0000ff;">if</span> s<span class="br0">&#91;</span>:<span style="color: #cc66cc;">3</span><span class="br0">&#93;</span>==<span style="color: #FF0000;">&quot;1&sdot;X&quot;</span>: s = s<span class="br0">&#91;</span><span style="color: #cc66cc;">3</span>:<span class="br0">&#93;</span>
&nbsp;
            <span style="color: #0000ff;">return</span> s <span style="color: #808080;"># on retourne l'expression du polyn&ocirc;me</span>
&nbsp;
&nbsp;
    <span style="color: #0000ff;">def</span> degre<span class="br0">&#40;</span>self<span class="br0">&#41;</span>: <span style="color: #808080;"># retourne le degr&eacute; du polyn&ocirc;me</span>
        <span style="color: #0000ff;">return</span> <span class="br0">&#40;</span>len<span class="br0">&#40;</span>self.coefs<span class="br0">&#41;</span>-<span style="color: #cc66cc;">1</span><span class="br0">&#41;</span>
&nbsp;
&nbsp;
    <span style="color: #0000ff;">def</span> <span style="color: #0080ff;">__add__</span><span class="br0">&#40;</span>self, other<span class="br0">&#41;</span>: <span style="color: #808080;"># m&eacute;thode permettant de red&eacute;finir l'op&eacute;rateur &laquo; + &raquo; pour 2 polyn&ocirc;mes : (1 + 2x + x^2) + (2 + X) = 2 + 3x + x^2</span>
        <span style="color: #808080;"># p1 = self, p2 = other     </span>
        <span style="color: #0000ff;">if</span> len<span class="br0">&#40;</span>other.coefs<span class="br0">&#41;</span> &gt;len<span class="br0">&#40;</span>self.coefs<span class="br0">&#41;</span>: <span style="color: #808080;"># si degr&eacute; de p2 &gt; degr&eacute; de p1 </span>
            liste_coefs = other.coefs<span class="br0">&#91;</span>:<span class="br0">&#93;</span>; n = len<span class="br0">&#40;</span>self.coefs<span class="br0">&#41;</span> <span style="color: #808080;"># on copie les coefs du polyn&ocirc;me de degr&eacute; le plus &eacute;lev&eacute; et la longueur de la liste de coefs la plus petite. </span>
        <span style="color: #0000ff;">else</span>: liste_coefs = self.coefs<span class="br0">&#91;</span>:<span class="br0">&#93;</span>; n = len<span class="br0">&#40;</span>other.coefs<span class="br0">&#41;</span> <span style="color: #808080;"># sinon, ...</span>
&nbsp;
        <span style="color: #0000ff;">for</span> i <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span>n<span class="br0">&#41;</span>: <span style="color: #808080;"># parcours des indices de liste_coefs</span>
            liste_coefs<span class="br0">&#91;</span>i<span class="br0">&#93;</span> = self.coefs<span class="br0">&#91;</span>i<span class="br0">&#93;</span> + other.coefs<span class="br0">&#91;</span>i<span class="br0">&#93;</span> <span style="color: #808080;"># addition des coefficients de degr&eacute; i</span>
&nbsp;
        <span style="color: #0000ff;">return</span> Polynome<span class="br0">&#40;</span>liste_coefs<span class="br0">&#41;</span> <span style="color: #808080;"># renvoie le polyn&ocirc;me r&eacute;sultat de l'addition</span>
&nbsp;
&nbsp;
    <span style="color: #0000ff;">def</span> __sub__<span class="br0">&#40;</span>self, other<span class="br0">&#41;</span>: <span style="color: #808080;"># m&eacute;thode permettant de red&eacute;finir l'op&eacute;rateur &laquo; + &raquo; pour 2 polyn&ocirc;mes : (1 + 2x + x^2) + (2 + X) = 2 + 3x + x^2</span>
        <span style="color: #808080;"># p1 = self, p2 = other     </span>
        <span style="color: #0000ff;">if</span> len<span class="br0">&#40;</span>other.coefs<span class="br0">&#41;</span> &gt;len<span class="br0">&#40;</span>self.coefs<span class="br0">&#41;</span>: <span style="color: #808080;"># si degr&eacute; de p2 &gt; degr&eacute; de p1 </span>
            liste_coefs = other.coefs<span class="br0">&#91;</span>:<span class="br0">&#93;</span>; n = len<span class="br0">&#40;</span>self.coefs<span class="br0">&#41;</span> <span style="color: #808080;"># on copie les coefs du polyn&ocirc;me de degr&eacute; le plus &eacute;lev&eacute; et la longueur de la liste de coefs la plus petite. </span>
        <span style="color: #0000ff;">else</span>: liste_coefs = self.coefs<span class="br0">&#91;</span>:<span class="br0">&#93;</span>; n = len<span class="br0">&#40;</span>other.coefs<span class="br0">&#41;</span> <span style="color: #808080;"># sinon, ...</span>
&nbsp;
        <span style="color: #0000ff;">for</span> i <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span>n<span class="br0">&#41;</span>: <span style="color: #808080;"># parcours des indices de liste_coefs</span>
            liste_coefs<span class="br0">&#91;</span>i<span class="br0">&#93;</span> = self.coefs<span class="br0">&#91;</span>i<span class="br0">&#93;</span> - other.coefs<span class="br0">&#91;</span>i<span class="br0">&#93;</span> <span style="color: #808080;"># addition des coefficients de degr&eacute; i</span>
&nbsp;
        <span style="color: #0000ff;">return</span> Polynome<span class="br0">&#40;</span>liste_coefs<span class="br0">&#41;</span> <span style="color: #808080;"># renvoie le polyn&ocirc;me r&eacute;sultat de l'addition</span>
&nbsp;
&nbsp;
    <span style="color: #0000ff;">def</span> reduire<span class="br0">&#40;</span>self<span class="br0">&#41;</span>:
        <span style="color: #808080;"># tant que le dernier &eacute;l&eacute;ment de la liste est nul</span>
        <span style="color: #0000ff;">while</span> round<span class="br0">&#40;</span>self.coefs<span class="br0">&#91;</span>-<span style="color: #cc66cc;">1</span><span class="br0">&#93;</span>,<span style="color: #cc66cc;">12</span><span class="br0">&#41;</span> == <span style="color: #cc66cc;">0</span> <span style="color: #0000ff;">and</span> len<span class="br0">&#40;</span>self.coefs<span class="br0">&#41;</span>&gt;<span style="color: #cc66cc;">1</span>:
            self.coefs.pop<span class="br0">&#40;</span><span class="br0">&#41;</span> <span style="color: #808080;"># supprimer le dernier &eacute;l&eacute;ment</span>
&nbsp;
        <span style="color: #0000ff;">for</span> i <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span>len<span class="br0">&#40;</span>self.coefs<span class="br0">&#41;</span><span class="br0">&#41;</span>:
            self.coefs<span class="br0">&#91;</span>i<span class="br0">&#93;</span> = round<span class="br0">&#40;</span>self.coefs<span class="br0">&#91;</span>i<span class="br0">&#93;</span>,<span style="color: #cc66cc;">12</span><span class="br0">&#41;</span>
&nbsp;
&nbsp;
    <span style="color: #0000ff;">def</span> <span style="color: #0080ff;">__mul__</span><span class="br0">&#40;</span>self, other<span class="br0">&#41;</span>: <span style="color: #808080;"># m&eacute;thode permettant de red&eacute;finir l'op&eacute;rateur &laquo; * &raquo; pour 2 polyn&ocirc;mes : (2 + X) * (1 + 2x) =  1 + 3x + 2x^2</span>
&nbsp;
        <span style="color: #808080;"># initialisation de la liste des coefficients qu'avec des z&eacute;ros</span>
        liste_coefs=<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span><span class="br0">&#93;</span>*<span class="br0">&#40;</span>len<span class="br0">&#40;</span>self.coefs<span class="br0">&#41;</span>+len<span class="br0">&#40;</span>other.coefs<span class="br0">&#41;</span>-<span style="color: #cc66cc;">1</span><span class="br0">&#41;</span> <span style="color: #808080;"># exemple : [0, 0, 0]</span>
        <span style="color: #0000ff;">for</span> i1 <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span>len<span class="br0">&#40;</span>self.coefs<span class="br0">&#41;</span><span class="br0">&#41;</span>: <span style="color: #808080;"># parcours des indices des coefs du polyn&ocirc;me n&deg;1</span>
            <span style="color: #0000ff;">for</span> i2 <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span>len<span class="br0">&#40;</span>other.coefs<span class="br0">&#41;</span><span class="br0">&#41;</span>: <span style="color: #808080;"># parcours des indices des coefs du polyn&ocirc;me n&deg;2</span>
                <span style="color: #808080;"># multiplication des coefficients d'indices i1 et i2</span>
                liste_coefs<span class="br0">&#91;</span>i1+i2<span class="br0">&#93;</span> = liste_coefs<span class="br0">&#91;</span>i1+i2<span class="br0">&#93;</span> + self.coefs<span class="br0">&#91;</span>i1<span class="br0">&#93;</span>*other.coefs<span class="br0">&#91;</span>i2<span class="br0">&#93;</span>
&nbsp;
        poly = Polynome<span class="br0">&#40;</span>liste_coefs<span class="br0">&#41;</span> <span style="color: #808080;"># cr&eacute;ation de l'objet Polynome bas&eacute; sur la liste</span>
&nbsp;
        <span style="color: #808080;"># ajout du nombre d'op&eacute;rations de multiplication entre termes effectu&eacute;es lors de la multiplication entre polyn&ocirc;mes</span>
        poly.nombre_operations = self.nombre_operations + other.nombre_operations +  len<span class="br0">&#40;</span>self.coefs<span class="br0">&#41;</span>*len<span class="br0">&#40;</span>other.coefs<span class="br0">&#41;</span> <span style="color: #808080;"># </span>
&nbsp;
        <span style="color: #0000ff;">return</span> poly <span style="color: #808080;"># renvoie le polyn&ocirc;me r&eacute;sultat de la multiplication</span>
&nbsp;
&nbsp;
    <span style="color: #0000ff;">def</span> __pow__<span class="br0">&#40;</span>self, n<span class="br0">&#41;</span>: <span style="color: #808080;"># m&eacute;thode permettant de red&eacute;finir l'op&eacute;rateur de puissance : self ** n</span>
&nbsp;
        <span style="color: #0000ff;">if</span> n==<span style="color: #cc66cc;">0</span>: <span style="color: #808080;"># si n=0</span>
            <span style="color: #0000ff;">return</span> Polynome<span class="br0">&#40;</span><span class="br0">&#91;</span><span style="color: #cc66cc;">1</span><span class="br0">&#93;</span><span class="br0">&#41;</span> <span style="color: #808080;"># on renvoie le polyn&ocirc;me &eacute;gal &agrave; 1</span>
&nbsp;
        <span style="color: #808080;"># copie de self initialis&eacute; avec le m&ecirc;me nombre d'op&eacute;rations de multiplication entre termes </span>
        poly = Polynome<span class="br0">&#40;</span>self.coefs, self.nombre_operations<span class="br0">&#41;</span>
&nbsp;
        <span style="color: #808080;"># copie de self avec un nombre d'op&eacute;rations de multiplication &agrave; 0</span>
        pol = Polynome<span class="br0">&#40;</span>self.coefs<span class="br0">&#41;</span> 
&nbsp;
        <span style="color: #0000ff;">for</span> i <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span>n-<span style="color: #cc66cc;">1</span><span class="br0">&#41;</span>: <span style="color: #808080;"># on multiplie n fois poly par pol &agrave; l'aide de l'op&eacute;rateur *            </span>
            poly = poly*pol <span style="color: #808080;"># &eacute;quivalent &agrave; : poly = poly.__mul__(pol)</span>
&nbsp;
        <span style="color: #0000ff;">return</span> poly <span style="color: #808080;"># renvoie le polyn&ocirc;me r&eacute;sultat de l'op&eacute;ration (self ** n)</span>
&nbsp;
&nbsp;
    <span style="color: #0000ff;">def</span> <span style="color: #0080ff;">__eq__</span><span class="br0">&#40;</span>poly1, other<span class="br0">&#41;</span>: <span style="color: #808080;"># m&eacute;thode permettant de red&eacute;finir l'op&eacute;rateur &laquo; == &raquo; pour 2 polyn&ocirc;mes</span>
&nbsp;
        <span style="color: #0000ff;">return</span> <span class="br0">&#40;</span>poly1.coefs==other.coefs<span class="br0">&#41;</span> <span style="color: #808080;"># renvoie True si les 2 listes de coefficients sont &eacute;gales</span>
&nbsp;
&nbsp;
    <span style="color: #0000ff;">def</span> eval<span class="br0">&#40;</span>self,x<span class="br0">&#41;</span>: <span style="color: #808080;"># m&eacute;thode permettant d'&eacute;valuer le polyn&ocirc;me en fonction de x</span>
        <span style="color: #808080;"># intialisation des variables</span>
        valeur_polynome = self.coefs<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span><span class="br0">&#93;</span> <span style="color: #808080;"># valeur_polynome = a0</span>
        power=<span style="color: #cc66cc;">1</span>    
&nbsp;
        <span style="color: #0000ff;">for</span> coef <span style="color: #0000ff;">in</span> self.coefs<span class="br0">&#91;</span><span style="color: #cc66cc;">1</span>:<span class="br0">&#93;</span>: <span style="color: #808080;"># parcours des coefficients du polyn&ocirc;me &agrave; partir de a1 : a1, a2, ..., an</span>
            power = power*x <span style="color: #808080;"># calcul de la puissance de x pour ai : power = x^i</span>
            valeur_polynome += coef*power <span style="color: #808080;"># valeur_polynome = valeur_polynome + ai*x^i</span>
&nbsp;
        <span style="color: #0000ff;">return</span> valeur_polynome <span style="color: #808080;"># renvoie la valeur du polyn&ocirc;me</span>
&nbsp;
    <span style="color: #0000ff;">def</span> eval_horner<span class="br0">&#40;</span>self,x<span class="br0">&#41;</span>: <span style="color: #808080;"># m&eacute;thode permettant d'&eacute;valuer le polyn&ocirc;me en fonction de x</span>
        <span style="color: #808080;"># intialisation de la variable</span>
        valeur_polynome = self.coefs<span class="br0">&#91;</span>-<span style="color: #cc66cc;">1</span><span class="br0">&#93;</span> <span style="color: #808080;"># valeur_polynome = an</span>
&nbsp;
        <span style="color: #0000ff;">for</span> coef <span style="color: #0000ff;">in</span> reversed<span class="br0">&#40;</span>self.coefs<span class="br0">&#91;</span>:-<span style="color: #cc66cc;">1</span><span class="br0">&#93;</span><span class="br0">&#41;</span>: <span style="color: #808080;"># parcours des coefficients du polyn&ocirc;me &agrave; partir de an-1 : an-1, ..., a1, a0</span>
            valeur_polynome = valeur_polynome*x + coef  <span style="color: #808080;"># valeur_polynome = valeur_polynome*x + ai</span>
&nbsp;
        <span style="color: #0000ff;">return</span> valeur_polynome <span style="color: #808080;"># renvoie la valeur du polyn&ocirc;me</span>
&nbsp;
<span style="color: #0000ff;">def</span> puissance<span class="br0">&#40;</span>x,n<span class="br0">&#41;</span>:
    <span style="color: #808080;"># exponentiation rapide de x^n</span>
&nbsp;
    <span style="color: #808080;"># si n=1 alors on renvoie x</span>
    <span style="color: #0000ff;">if</span> n==<span style="color: #cc66cc;">1</span>:
        <span style="color: #0000ff;">return</span> x
    <span style="color: #0000ff;">else</span>: <span style="color: #808080;"># sinon</span>
        <span style="color: #808080;"># si n est pair</span>
        <span style="color: #0000ff;">if</span> <span class="br0">&#40;</span>n % <span style="color: #cc66cc;">2</span> == <span style="color: #cc66cc;">0</span><span class="br0">&#41;</span>:
            <span style="color: #808080;"># appel r&eacute;cursif : puissance(x^2,n/2)</span>
            <span style="color: #0000ff;">return</span> puissance<span class="br0">&#40;</span>x**<span style="color: #cc66cc;">2</span>,n//<span style="color: #cc66cc;">2</span><span class="br0">&#41;</span>
        <span style="color: #0000ff;">else</span>: <span style="color: #808080;"># sinon si n est impair</span>
            <span style="color: #808080;"># appel r&eacute;cursif : x*puissance(x^2,(n-1)/2)</span>
            <span style="color: #0000ff;">return</span> x*puissance<span class="br0">&#40;</span>x**<span style="color: #cc66cc;">2</span>,n//<span style="color: #cc66cc;">2</span><span class="br0">&#41;</span>
&nbsp;
&nbsp;
<span style="color: #0000ff;">def</span> puissance_polynome<span class="br0">&#40;</span>p,n<span class="br0">&#41;</span>:
    <span style="color: #808080;"># exponentiation rapide de p^n</span>
&nbsp;
    <span style="color: #808080;"># si n=1 alors on renvoie p</span>
    <span style="color: #0000ff;">if</span> n==<span style="color: #cc66cc;">1</span>:
        <span style="color: #0000ff;">return</span> p
    <span style="color: #0000ff;">else</span>: <span style="color: #808080;"># sinon</span>
        <span style="color: #808080;"># si n est pair</span>
        <span style="color: #0000ff;">if</span> <span class="br0">&#40;</span>n % <span style="color: #cc66cc;">2</span> == <span style="color: #cc66cc;">0</span><span class="br0">&#41;</span>:
            <span style="color: #808080;"># appel r&eacute;cursif : puissance_polynome(p^2,n/2)</span>
            <span style="color: #0000ff;">return</span> puissance_polynome<span class="br0">&#40;</span>p**<span style="color: #cc66cc;">2</span>,n//<span style="color: #cc66cc;">2</span><span class="br0">&#41;</span>
        <span style="color: #0000ff;">else</span>: <span style="color: #808080;"># sinon si n est impair</span>
            <span style="color: #808080;"># appel r&eacute;cursif : p*puissance_polynome(p^2,(n-1)/2)</span>
            <span style="color: #808080;"># return p*puissance_polynome(p**2,n//2)</span>
            <span style="color: #0000ff;">return</span> Polynome<span class="br0">&#40;</span>p.coefs<span class="br0">&#41;</span>*puissance_polynome<span class="br0">&#40;</span>p**<span style="color: #cc66cc;">2</span>,n//<span style="color: #cc66cc;">2</span><span class="br0">&#41;</span> <span style="color: #808080;"># pour calculer le nombre d'op&eacute;rations de mult.</span>
&nbsp;
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;I-A. Exponentiation de nombres r&eacute;els&quot;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># nombre entier </span>
x = <span style="color: #cc66cc;">12</span>
&nbsp;
<span style="color: #808080;"># exposant </span>
n = <span style="color: #cc66cc;">8</span>
&nbsp;
<span style="color: #808080;"># exponentiation du polyn&ocirc;me</span>
xn =  x**n
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;x^n = {0}^{1}&quot;</span>.format<span class="br0">&#40;</span>x,n<span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;x^n = &quot;</span> + str<span class="br0">&#40;</span>xn<span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;nombre de multiplications = &quot;</span> + str<span class="br0">&#40;</span>n-<span style="color: #cc66cc;">1</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;I-B. Exponentiation rapide de nombres r&eacute;els&quot;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># exponentiation du polyn&ocirc;me</span>
xn =  puissance<span class="br0">&#40;</span>x,n<span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;x^n = {0}^{1}&quot;</span>.format<span class="br0">&#40;</span>x,n<span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;x^n = &quot;</span> + str<span class="br0">&#40;</span>xn<span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;nombre de multiplications de l'ordre de log2({0})&quot;</span>.format<span class="br0">&#40;</span>n<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;II-A. Exponentiation de polyn&ocirc;mes&quot;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># cr&eacute;ation du polyn&ocirc;me p = 2 + X = X + 2</span>
p = Polynome<span class="br0">&#40;</span><span class="br0">&#91;</span><span style="color: #cc66cc;">2</span>,<span style="color: #cc66cc;">1</span><span class="br0">&#93;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># exposant</span>
n = <span style="color: #cc66cc;">8</span>
&nbsp;
<span style="color: #808080;"># exponentiation du polyn&ocirc;me</span>
pn = p**n
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;p^n = ({0})^{1}&quot;</span>.format<span class="br0">&#40;</span>p,n<span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;p^n = &quot;</span> + str<span class="br0">&#40;</span>pn<span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;nombre d'op&eacute;rations = &quot;</span> + str<span class="br0">&#40;</span>pn.nombre_operations<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;II-B. Exponentiation rapide de polyn&ocirc;mes&quot;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># exponentiation rapide de polyn&ocirc;mes</span>
<span style="color: #808080;"># pn = ((p**2)**2)**2</span>
pn = puissance_polynome<span class="br0">&#40;</span>p,n<span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;p^n = ({0})^{1}&quot;</span>.format<span class="br0">&#40;</span>p,n<span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;p^n = &quot;</span> + str<span class="br0">&#40;</span>pn<span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;nombre d'op&eacute;rations = &quot;</span> + str<span class="br0">&#40;</span>pn.nombre_operations<span class="br0">&#41;</span><span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
<br />
<b>IV. Complément : Formule du multinôme de Newton</b><br />
<br />
On peut également se baser sur la <a href="https://fr.wikipedia.org/wiki/Formule_du_multin%C3%B4me_de_Newton" target="_blank">formule du multinôme</a> pour développer une puissance de polynômes.<br />
<br />
Par exemple, on peut réaliser plus rapidement le développement de <b>(X + 2)<sup>n</sup></b> en utilisant la <a href="https://fr.wikipedia.org/wiki/Formule_du_bin%C3%B4me_de_Newton" target="_blank">formule du binôme de Newton</a> :<br />
<br />
<img src="https://www.developpez.net/forums/attachment.php?attachmentid=649647&amp;d=1706025076" border="0" alt="Nom : formule_binome.png
Affichages : 8361
Taille : 3,9 Ko"  style="float: CONFIG" /><br />
<br />
Libre à chacun d'écrire la fonction Python basée sur cette formule.<br />
<br />
<br />
<b>V. Conclusion</b><br />
<br />
Nous avons donc pu montrer les avantages de l'exponentiation rapide dans le calcul de puissances de nombres réels, puis dans le développement de puissances de polynômes, pour enfin le vérifier en Python à l'aide de la classe Polynome.<br />
<br />
<br />
<b>Sources : </b><br />
<br />
<a href="https://fr.wikipedia.org/wiki/Exponentiation_rapide" target="_blank">https://fr.wikipedia.org/wiki/Exponentiation_rapide</a><br />
<a href="https://www.bibmath.net/dico/index.php?action=affiche&amp;quoi=./e/exponentiationrapide.html" target="_blank">https://www.bibmath.net/dico/index.p...ionrapide.html</a></blockquote>

]]></content:encoded>
			<dc:creator>User</dc:creator>
			<guid isPermaLink="true">https://www.developpez.net/forums/blogs/44027-user/b10570/exponentiation-rapide-nombres-reels-polynomes-python/</guid>
		</item>
		<item>
			<title>Produit de polynômes en Python : principe du « diviser pour régner »</title>
			<link>https://www.developpez.net/forums/blogs/44027-user/b10566/produit-polynomes-python-principe-diviser-regner/</link>
			<pubDate>Wed, 10 Jan 2024 07:39:54 GMT</pubDate>
			<description>*I. Introduction* 
 
On...</description>
			<content:encoded><![CDATA[<blockquote class="blogcontent restore"><b>I. Introduction</b><br />
<br />
On souhaite montrer comment utiliser le principe du « <a href="https://fr.wikipedia.org/wiki/Diviser_pour_r%C3%A9gner_(informatique)" target="_blank">diviser pour régner</a> » afin de développer un produit de petits polynômes avec un minimum d'opérations de multiplication entre termes.<br />
<br />
Pour cela, on va d'abord décrire cette méthode à l'aide d'un exemple simple de multiplication de nombre entiers, puis de petits polynômes, pour ensuite l'implémenter en Python.<br />
<br />
<br />
<b>II. Principe du « diviser pour régner »</b><br />
<br />
Une multiplication entre deux nombres entiers nécessite de multiplier chaque chiffre du multiplicateur par chaque chiffre du multiplicande. <br />
<br />
Si ces deux nombres ont <b>n</b> chiffres, cela exige <b>n<sup>2</sup></b> produits. La multiplication <b>10*10</b> nécessite ainsi <b>4</b> multiplications de chiffre.<br />
 <br />
On dit que le calcul a une complexité en temps quadratique, ou en <b>O(n<sup>2</sup>)</b>.<br />
<br />
Si on prend maintenant le produit de nombres entiers :<br />
<br />
<b>p = 10 × 10 × 11 × 11 × 12 × 12 × 13 × 13</b><br />
<br />
En effectuant les calculs de gauche à droite, on obtient successivement :<br />
<br />
<b>p = (10×10) × 11 × 11 × 12 × 12 × 13 × 13</b><br />
<br />
La <b>1<sup>re</sup></b> multiplication nécessite donc <b>4</b> opérations de multiplication entre chiffres.<br />
<br />
En poursuivant les calculs :<br />
<br />
<b>p = 100 × 11 × 11 × 12 × 12 × 13 × 13</b><br />
<br />
<b>p = (100 × 11) × 11 × 12 × 12 × 13 × 13</b><br />
<br />
On a ainsi besoin jusque là de <b>4 + 6</b> opérations de multiplication.<br />
<br />
Puis :<br />
<br />
<b>p = (1100 × 11) × 12 × 12 × 13 × 13</b><br />
<br />
Ce qui fait alors au total <b>4 + 6 + 8</b> opérations.<br />
<br />
etc..<br />
<br />
En poursuivant les calculs vers la droite, on obtient finalement <b>4 + 6 + 8 + 10 + 12 + 14 + 16 = 70</b> opérations de multiplication en tout pour ce produit.<br />
<br />
<br />
Considérons maintenant le même produit réarrangé :<br />
<br />
<b>p = ((10 × 10) × (11 × 11)) × ((12 × 12) × (13 × 13))</b><br />
<br />
Si on effectue les calculs en respectant la règle de priorité des parenthèses, on peut alors les représenter sur un <a href="https://fr.wikipedia.org/wiki/Arbre_de_produits" target="_blank">arbre de produits</a> :<br />
<br />
<div style="text-align: center;"><img src="https://www.developpez.net/forums/attachments/p648991d1704824903/autres-langages/xml-xsl-soap/xsl-xslt-xpath/probleme-xsl-inclure-donnee-xml-balise-html/produit_entiers.png/" border="0" alt="Nom : produit_entiers.png
Affichages : 22415
Taille : 14,2 Ko"  style="float: CONFIG" /></div><br />
On a donc besoin dans ce cas de seulement <b>59</b> opérations de multiplication entre chiffres au lieu de <b>70</b> précédemment.<br />
<br />
Il s'agit du principe du « <a href="https://fr.wikipedia.org/wiki/Diviser_pour_r%C3%A9gner_(informatique)" target="_blank">diviser pour régner</a> »  :<br />
<br />
<ul><li style="">Diviser : découper un problème initial en sous-problèmes ;</li><li style="">Régner : résoudre les sous-problèmes (récursivement ou directement s'ils sont assez petits) ;</li><li style="">Combiner : calculer une solution au problème initial à partir des solutions des sous-problèmes.</li></ul><br />
<br />
On peut également appliquer ce même principe pour la multiplication de petits polynômes :<br />
<br />
<div style="text-align: center;"><img src="https://www.developpez.net/forums/attachments/p648992d1704824918/autres-langages/xml-xsl-soap/xsl-xslt-xpath/probleme-xsl-inclure-donnee-xml-balise-html/produit_polynomes.png/" border="0" alt="Nom : produit_polynomes.png
Affichages : 7145
Taille : 15,2 Ko"  style="float: CONFIG" /></div><br />
<br />
<u>Important :</u> L'intérêt principal des arbres de produits est en fait de tirer parti des algorithmes de multiplication rapide d'entiers ou de polynômes. <br />
<br />
La situation la plus simple est celle où l'on cherche à calculer le produit d'un grand nombre de « petits » entiers ou polynômes. <br />
<br />
Dans ce contexte, et pourvu que l'on dispose d'une multiplication rapide, l'algorithme diviser pour régner est plus efficace que la méthode classique.<br />
<br />
Dans notre cas, on va déjà montrer ses avantages dans le développement d'un produit de petits polynômes sans parler de multiplication rapide.<br />
<br />
<br />
<br />
<b>III. Implémenter le développement d'un produit de polynômes</b><br />
<br />
On utilise à nouveau notre <a href="https://algo.developpez.com/actu/339249/Mathematiques-et-Python-moins-apprendre-a-creer-une-classe-Polynome-en-Python-avec-la-surcharge-des-operateurs-un-billet-blog-de-Denis-Hulo/" target="_blank">classe Polynome</a> à laquelle on ajoute un attribut permettant de compter le nombre d'opérations de multiplication entre termes nécessaires pour développer un produit de polynômes :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:192px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">class</span> Polynome:
&nbsp;
    <span style="color: #0000ff;">def</span> <span style="color: #0080ff;">__init__</span><span class="br0">&#40;</span>self, liste_coefs=<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span><span class="br0">&#93;</span><span class="br0">&#41;</span>: <span style="color: #808080;"># m&eacute;thode constructeur de la classe</span>
&nbsp;
	<span style="color: #808080;"># on d&eacute;finit la liste des coefficients du polyn&ocirc;me [a0, a1, ..., an]</span>
        self.coefs = liste_coefs
&nbsp;
        <span style="color: #808080;"># on initialise le nombre d'op&eacute;rations de multiplication entre termes</span>
        self.nombre_operations = <span style="color: #cc66cc;">0</span>
&nbsp;
	<span style="color: #808080;"># suppression si n&eacute;cessaire des z&eacute;ros en queue de liste de coefficients. Exemple : [2, 3, 1, 0, 0] -&gt; [2, 3, 1]</span>
        self.reduire<span class="br0">&#40;</span><span class="br0">&#41;</span> 
&nbsp;
    ...</pre></td></tr></table></pre>
</div><br />
Le code de la méthode permettant de multiplier deux polynômes devient alors :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">class</span> Polynome:
&nbsp;
    ...    
&nbsp;
    <span style="color: #0000ff;">def</span> <span style="color: #0080ff;">__mul__</span><span class="br0">&#40;</span>self, other<span class="br0">&#41;</span>: <span style="color: #808080;"># m&eacute;thode permettant de red&eacute;finir l'op&eacute;rateur &laquo; * &raquo; pour 2 polyn&ocirc;mes : (1 + x) * (1 + 2x) =  1 + 3x + 2x^2</span>
&nbsp;
        <span style="color: #808080;"># initialisation de la liste des coefficients qu'avec des z&eacute;ros</span>
        liste_coefs=<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span><span class="br0">&#93;</span>*<span class="br0">&#40;</span>len<span class="br0">&#40;</span>self.coefs<span class="br0">&#41;</span>+len<span class="br0">&#40;</span>other.coefs<span class="br0">&#41;</span>-<span style="color: #cc66cc;">1</span><span class="br0">&#41;</span> <span style="color: #808080;"># exemple : [0, 0, 0]</span>
        <span style="color: #0000ff;">for</span> i1 <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span>len<span class="br0">&#40;</span>self.coefs<span class="br0">&#41;</span><span class="br0">&#41;</span>: <span style="color: #808080;"># parcours des indices des coefs du polyn&ocirc;me n&deg;1</span>
            <span style="color: #0000ff;">for</span> i2 <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span>len<span class="br0">&#40;</span>other.coefs<span class="br0">&#41;</span><span class="br0">&#41;</span>: <span style="color: #808080;"># parcours des indices des coefs du polyn&ocirc;me n&deg;2</span>
                <span style="color: #808080;"># multiplication des coefficients d'indices i1 et i2</span>
                liste_coefs<span class="br0">&#91;</span>i1+i2<span class="br0">&#93;</span> = liste_coefs<span class="br0">&#91;</span>i1+i2<span class="br0">&#93;</span> + self.coefs<span class="br0">&#91;</span>i1<span class="br0">&#93;</span>*other.coefs<span class="br0">&#91;</span>i2<span class="br0">&#93;</span>
&nbsp;
        poly = Polynome<span class="br0">&#40;</span>liste_coefs<span class="br0">&#41;</span> <span style="color: #808080;"># cr&eacute;ation de l'objet Polynome bas&eacute; sur la liste</span>
&nbsp;
        <span style="color: #808080;"># ajout du nombre d'op&eacute;rations de multiplication entre termes effectu&eacute;es lors de la multiplication entre polyn&ocirc;mes</span>
        poly.compteur_operations = self.compteur_operations + other.compteur_operations +  len<span class="br0">&#40;</span>self.coefs<span class="br0">&#41;</span>*len<span class="br0">&#40;</span>other.coefs<span class="br0">&#41;</span>
&nbsp;
        <span style="color: #0000ff;">return</span> poly <span style="color: #808080;"># renvoie le polyn&ocirc;me r&eacute;sultat de la multiplication</span></pre></td></tr></table></pre>
</div><br />
<u>Rappel important :</u> les objets Polynome de notre classe sont représentés par une liste de coefficients dont la longueur est égale au degré du polynôme + <b>1</b> : <br />
<br />
Par exemple, le polynôme <b>X<sup>3</sup> + 2 = 2 + 0.X + 0.X<sup>2</sup> + X<sup>3</sup></b> sera représenté par la liste de coefficients <b>[2, 0, 0, 1]</b>.<br />
<br />
Par conséquent, le développement du produit <b>(X<sup>3</sup> + 2)(X<sup>3</sup> + 2)</b> nécessite en fait <b>4*4 = 16</b> multiplications entre termes.<br />
<br />
<br />
<b>III-A. Méthode classique</b><br />
<br />
Testons maintenant l'opérateur de multiplication entre polynômes avec la méthode classique :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:192px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #808080;"># cr&eacute;ation des polyn&ocirc;mes p1 = X + 1; p2 = X + 2; p3 = X + 3; p4 = X + 4</span>
p1 = Polynome<span class="br0">&#40;</span><span class="br0">&#91;</span><span style="color: #cc66cc;">1</span>,<span style="color: #cc66cc;">1</span><span class="br0">&#93;</span><span class="br0">&#41;</span>; p2 = Polynome<span class="br0">&#40;</span><span class="br0">&#91;</span><span style="color: #cc66cc;">2</span>,<span style="color: #cc66cc;">1</span><span class="br0">&#93;</span><span class="br0">&#41;</span>; p3 = Polynome<span class="br0">&#40;</span><span class="br0">&#91;</span><span style="color: #cc66cc;">3</span>,<span style="color: #cc66cc;">1</span><span class="br0">&#93;</span><span class="br0">&#41;</span>; p4 = Polynome<span class="br0">&#40;</span><span class="br0">&#91;</span><span style="color: #cc66cc;">4</span>,<span style="color: #cc66cc;">1</span><span class="br0">&#93;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># produit de polyn&ocirc;mes</span>
p = p1*p1*p2*p2*p3*p3*p4*p4
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;produit = ({0})*({0})*({1})*({1})*({2})*({2})*({3})*({3})&quot;</span>.format<span class="br0">&#40;</span>p1,p2,p3,p4<span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;produit d&eacute;velopp&eacute; = &quot;</span> + str<span class="br0">&#40;</span>p<span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;nombre d'op&eacute;rations = &quot;</span> + str<span class="br0">&#40;</span>p.nombre_operations<span class="br0">&#41;</span><span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
Le code affiche :<br />
<br />
<span class="highlight">produit = (1 + X)*(1 + X)*(2 + X)*(2 + X)*(3 + X)*(3 + X)*(4 + X)*(4 + X)<br />
<br />
produit développé = 576 + 2400.X + 4180.X^2 + 3980.X^3 + 2273.X^4 + 800.X^5 + 170.X^6 + 20.X^7 + X^8<br />
<br />
nombre d'opérations = 70</span><br />
<br />
<br />
<b>III-B. Principe du « diviser pour régner »</b><br />
<br />
On peut également, comme on l'a vu précédemment, regrouper les sous-produits sur un <a href="https://fr.wikipedia.org/wiki/Arbre_de_produits" target="_blank">arbre de produits</a>.<br />
<br />
On obtient ainsi la fonction récursive basée sur le principe du « diviser pour régner » :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:156px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">def</span> produit_polynomes<span class="br0">&#40;</span>*polynomes<span class="br0">&#41;</span>:
&nbsp;
    <span style="color: #808080;"># test si le tuple polynomes contient plus de 1 &eacute;l&eacute;ment</span>
    <span style="color: #0000ff;">if</span> len<span class="br0">&#40;</span>polynomes<span class="br0">&#41;</span>&gt;<span style="color: #cc66cc;">1</span>:
        i=len<span class="br0">&#40;</span>polynomes<span class="br0">&#41;</span>//<span style="color: #cc66cc;">2</span> <span style="color: #808080;"># valeur du milieu</span>
        <span style="color: #808080;"># appels r&eacute;cursifs</span>
        <span style="color: #0000ff;">return</span> produit_polynomes<span class="br0">&#40;</span>*polynomes<span class="br0">&#91;</span>:i<span class="br0">&#93;</span><span class="br0">&#41;</span>*produit_polynomes<span class="br0">&#40;</span>*polynomes<span class="br0">&#91;</span>i:<span class="br0">&#93;</span><span class="br0">&#41;</span>
    <span style="color: #0000ff;">else</span>: <span style="color: #808080;"># sinon</span>
        <span style="color: #808080;"># renvoie l'unique polyn&ocirc;me du tuple</span>
        <span style="color: #0000ff;">return</span> polynomes<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span><span class="br0">&#93;</span></pre></td></tr></table></pre>
</div><br />
Libre à chacun ensuite d'optimiser ce code.<br />
<br />
Testons notre fonction avec ces quelques lignes :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:192px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #808080;"># cr&eacute;ation des polyn&ocirc;mes p1 = X + 1; p2 = X + 2; p3 = X + 3; p4 = X + 4</span>
p1 = Polynome<span class="br0">&#40;</span><span class="br0">&#91;</span><span style="color: #cc66cc;">1</span>,<span style="color: #cc66cc;">1</span><span class="br0">&#93;</span><span class="br0">&#41;</span>; p2 = Polynome<span class="br0">&#40;</span><span class="br0">&#91;</span><span style="color: #cc66cc;">2</span>,<span style="color: #cc66cc;">1</span><span class="br0">&#93;</span><span class="br0">&#41;</span>; p3 = Polynome<span class="br0">&#40;</span><span class="br0">&#91;</span><span style="color: #cc66cc;">3</span>,<span style="color: #cc66cc;">1</span><span class="br0">&#93;</span><span class="br0">&#41;</span>; p4 = Polynome<span class="br0">&#40;</span><span class="br0">&#91;</span><span style="color: #cc66cc;">4</span>,<span style="color: #cc66cc;">1</span><span class="br0">&#93;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># p = ((p1*p1)*(p2*p2))*((p3*p3)*(p4*p4))</span>
p = produit_polynomes<span class="br0">&#40;</span>p1,p1,p2,p2,p3,p3,p4,p4<span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;produit = ((({0})*({0}))*(({1})*({1})))*((({2})*({2}))*(({3})*({3})))&quot;</span>.format<span class="br0">&#40;</span>p1,p2,p3,p4<span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;produit d&eacute;velopp&eacute; = &quot;</span> + str<span class="br0">&#40;</span>p<span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;nombre d'op&eacute;rations = &quot;</span> + str<span class="br0">&#40;</span>p.nombre_operations<span class="br0">&#41;</span><span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
Le code affiche :<br />
<br />
<span class="highlight">produit = (((1 + X)*(1 + X))*((2 + X)*(2 + X)))*(((3 + X)*(3 + X))*((4 + X)*(4 + X)))<br />
<br />
produit développé = 576 + 2400.X + 4180.X^2 + 3980.X^3 + 2273.X^4 + 800.X^5 + 170.X^6 + 20.X^7 + X^8<br />
<br />
nombre d'opérations = 59</span><br />
<br />
<br />
<b>IV. Module complet</b><br />
<br />
On donne pour finir le contenu du module complet :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="40"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br />50<br />51<br />52<br />53<br />54<br />55<br />56<br />57<br />58<br />59<br />60<br />61<br />62<br />63<br />64<br />65<br />66<br />67<br />68<br />69<br />70<br />71<br />72<br />73<br />74<br />75<br />76<br />77<br />78<br />79<br />80<br />81<br />82<br />83<br />84<br />85<br />86<br />87<br />88<br />89<br />90<br />91<br />92<br />93<br />94<br />95<br />96<br />97<br />98<br />99<br />100<br />101<br />102<br />103<br />104<br />105<br />106<br />107<br />108<br />109<br />110<br />111<br />112<br />113<br />114<br />115<br />116<br />117<br />118<br />119<br />120<br />121<br />122<br />123<br />124<br />125<br />126<br />127<br />128<br />129<br />130<br />131<br />132<br />133<br />134<br />135<br />136<br />137<br />138<br />139<br />140<br />141<br />142<br />143<br />144<br />145<br />146<br />147<br />148<br />149<br />150<br />151<br />152<br />153<br />154<br />155<br />156<br />157<br />158<br />159<br />160<br />161<br />162<br />163<br />164<br />165<br />166<br />167<br />168<br />169<br />170<br />171<br />172<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">class</span> Polynome:
&nbsp;
    <span style="color: #0000ff;">def</span> <span style="color: #0080ff;">__init__</span><span class="br0">&#40;</span>self, liste_coefs=<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span><span class="br0">&#93;</span><span class="br0">&#41;</span>: <span style="color: #808080;"># m&eacute;thode constructeur de la classe</span>
&nbsp;
	<span style="color: #808080;"># on d&eacute;finit la liste des coefficients du polyn&ocirc;me [a0, a1, ..., an]</span>
        self.coefs = liste_coefs
&nbsp;
        <span style="color: #808080;"># on initialise le nombre d'op&eacute;rations de multiplication entre termes</span>
        self.nombre_operations = <span style="color: #cc66cc;">0</span>
&nbsp;
	<span style="color: #808080;"># suppression si n&eacute;cessaire des z&eacute;ros en queue de liste de coefficients. Exemple : [2, 3, 1, 0, 0] -&gt; [2, 3, 1]</span>
        self.reduire<span class="br0">&#40;</span><span class="br0">&#41;</span> 
&nbsp;
    <span style="color: #0000ff;">def</span> __str__<span class="br0">&#40;</span>self<span class="br0">&#41;</span>: <span style="color: #808080;"># permet d'afficher le polyn&ocirc;me sous la forme 1 + 2x + 3x^2</span>
        s=<span style="color: #FF0000;">&quot;&quot;</span> <span style="color: #808080;"># initialisation de la cha&icirc;ne de caract&egrave;res</span>
        <span style="color: #808080;"># on v&eacute;rifie d&#146;abord si le degr&eacute; du polyn&ocirc;me est nul</span>
        <span style="color: #0000ff;">if</span> <span class="br0">&#40;</span>len<span class="br0">&#40;</span>self.coefs<span class="br0">&#41;</span>-<span style="color: #cc66cc;">1</span>==<span style="color: #cc66cc;">0</span><span class="br0">&#41;</span>:
            <span style="color: #0000ff;">return</span> str<span class="br0">&#40;</span>self.coefs<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span><span class="br0">&#93;</span><span class="br0">&#41;</span>
        <span style="color: #0000ff;">else</span>: <span style="color: #808080;"># sinon</span>
            <span style="color: #0000ff;">if</span> self.coefs<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span><span class="br0">&#93;</span>!=<span style="color: #cc66cc;">0</span>:
                s=str<span class="br0">&#40;</span>self.coefs<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span><span class="br0">&#93;</span><span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot; + &quot;</span>
            <span style="color: #0000ff;">for</span> i <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span><span style="color: #cc66cc;">1</span>, len<span class="br0">&#40;</span>self.coefs<span class="br0">&#41;</span><span class="br0">&#41;</span>: <span style="color: #808080;"># parcours des indices des coefficients du polyn&ocirc;me : [a1, a2, ..., an]</span>
                <span style="color: #0000ff;">if</span> self.coefs<span class="br0">&#91;</span>i<span class="br0">&#93;</span>!=<span style="color: #cc66cc;">0</span>: <span style="color: #808080;"># si le coefficient de degr&eacute; i n'est pas nul</span>
                    <span style="color: #0000ff;">if</span> self.coefs<span class="br0">&#91;</span>i<span class="br0">&#93;</span>!=<span style="color: #cc66cc;">1</span>: <span style="color: #808080;"># si le coefficient de degr&eacute; i est diff&eacute;rent de 1</span>
                        s+=<span style="color: #FF0000;">&quot;{}.X^{} + &quot;</span>.format<span class="br0">&#40;</span>self.coefs<span class="br0">&#91;</span>i<span class="br0">&#93;</span>,i<span class="br0">&#41;</span>
                    <span style="color: #0000ff;">else</span>: s+=<span style="color: #FF0000;">&quot;X^{} + &quot;</span>.format<span class="br0">&#40;</span>i<span class="br0">&#41;</span>  
&nbsp;
            <span style="color: #808080;"># &eacute;limination des caract&egrave;res en trop           </span>
            s = s<span class="br0">&#91;</span>:-<span style="color: #cc66cc;">3</span><span class="br0">&#93;</span>.replace<span class="br0">&#40;</span><span style="color: #FF0000;">&quot;+ -&quot;</span>, <span style="color: #FF0000;">&quot;- &quot;</span><span class="br0">&#41;</span>.replace<span class="br0">&#40;</span><span style="color: #FF0000;">&quot;X^1 &quot;</span>,<span style="color: #FF0000;">&quot;X &quot;</span><span class="br0">&#41;</span>.replace<span class="br0">&#40;</span><span style="color: #FF0000;">&quot; 1.X&quot;</span>,<span style="color: #FF0000;">&quot; X&quot;</span><span class="br0">&#41;</span>
            <span style="color: #0000ff;">if</span> s<span class="br0">&#91;</span>-<span style="color: #cc66cc;">2</span>:<span class="br0">&#93;</span>==<span style="color: #FF0000;">&quot;^1&quot;</span>: s = s<span class="br0">&#91;</span>:-<span style="color: #cc66cc;">2</span><span class="br0">&#93;</span>
            <span style="color: #0000ff;">if</span> s<span class="br0">&#91;</span>:<span style="color: #cc66cc;">3</span><span class="br0">&#93;</span>==<span style="color: #FF0000;">&quot;1.X&quot;</span>: s = s<span class="br0">&#91;</span><span style="color: #cc66cc;">3</span>:<span class="br0">&#93;</span>
&nbsp;
            <span style="color: #0000ff;">return</span> s <span style="color: #808080;"># on retourne l'expression du polyn&ocirc;me</span>
&nbsp;
&nbsp;
    <span style="color: #0000ff;">def</span> degre<span class="br0">&#40;</span>self<span class="br0">&#41;</span>: <span style="color: #808080;"># retourne le degr&eacute; du polyn&ocirc;me</span>
        <span style="color: #0000ff;">return</span> <span class="br0">&#40;</span>len<span class="br0">&#40;</span>self.coefs<span class="br0">&#41;</span>-<span style="color: #cc66cc;">1</span><span class="br0">&#41;</span>
&nbsp;
&nbsp;
    <span style="color: #0000ff;">def</span> <span style="color: #0080ff;">__add__</span><span class="br0">&#40;</span>self, other<span class="br0">&#41;</span>: <span style="color: #808080;"># m&eacute;thode permettant de red&eacute;finir l'op&eacute;rateur &laquo; + &raquo; pour 2 polyn&ocirc;mes : (1 + 2x + x^2) + (1 + x) = 2 + 3x + x^2</span>
        <span style="color: #808080;"># p1 = self, p2 = other     </span>
        <span style="color: #0000ff;">if</span> len<span class="br0">&#40;</span>other.coefs<span class="br0">&#41;</span> &gt;len<span class="br0">&#40;</span>self.coefs<span class="br0">&#41;</span>: <span style="color: #808080;"># si degr&eacute; de p2 &gt; degr&eacute; de p1 </span>
            liste_coefs = other.coefs<span class="br0">&#91;</span>:<span class="br0">&#93;</span>; n = len<span class="br0">&#40;</span>self.coefs<span class="br0">&#41;</span> <span style="color: #808080;"># on copie les coefs du polyn&ocirc;me de degr&eacute; le plus &eacute;lev&eacute; et la longueur de la liste de coefs la plus petite. </span>
        <span style="color: #0000ff;">else</span>: liste_coefs = self.coefs<span class="br0">&#91;</span>:<span class="br0">&#93;</span>; n = len<span class="br0">&#40;</span>other.coefs<span class="br0">&#41;</span> <span style="color: #808080;"># sinon, ...</span>
&nbsp;
        <span style="color: #0000ff;">for</span> i <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span>n<span class="br0">&#41;</span>: <span style="color: #808080;"># parcours des indices de liste_coefs</span>
            liste_coefs<span class="br0">&#91;</span>i<span class="br0">&#93;</span> = self.coefs<span class="br0">&#91;</span>i<span class="br0">&#93;</span> + other.coefs<span class="br0">&#91;</span>i<span class="br0">&#93;</span> <span style="color: #808080;"># addition des coefficients de degr&eacute; i</span>
&nbsp;
        <span style="color: #0000ff;">return</span> Polynome<span class="br0">&#40;</span>liste_coefs<span class="br0">&#41;</span> <span style="color: #808080;"># renvoie le polyn&ocirc;me r&eacute;sultat de l'addition</span>
&nbsp;
&nbsp;
    <span style="color: #0000ff;">def</span> __sub__<span class="br0">&#40;</span>self, other<span class="br0">&#41;</span>: <span style="color: #808080;"># m&eacute;thode permettant de red&eacute;finir l'op&eacute;rateur &laquo; + &raquo; pour 2 polyn&ocirc;mes : (1 + 2x + x^2) + (1 + x) = 2 + 3x + x^2</span>
        <span style="color: #808080;"># p1 = self, p2 = other     </span>
        <span style="color: #0000ff;">if</span> len<span class="br0">&#40;</span>other.coefs<span class="br0">&#41;</span> &gt;len<span class="br0">&#40;</span>self.coefs<span class="br0">&#41;</span>: <span style="color: #808080;"># si degr&eacute; de p2 &gt; degr&eacute; de p1 </span>
            liste_coefs = other.coefs<span class="br0">&#91;</span>:<span class="br0">&#93;</span>; n = len<span class="br0">&#40;</span>self.coefs<span class="br0">&#41;</span> <span style="color: #808080;"># on copie les coefs du polyn&ocirc;me de degr&eacute; le plus &eacute;lev&eacute; et la longueur de la liste de coefs la plus petite. </span>
        <span style="color: #0000ff;">else</span>: liste_coefs = self.coefs<span class="br0">&#91;</span>:<span class="br0">&#93;</span>; n = len<span class="br0">&#40;</span>other.coefs<span class="br0">&#41;</span> <span style="color: #808080;"># sinon, ...</span>
&nbsp;
        <span style="color: #0000ff;">for</span> i <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span>n<span class="br0">&#41;</span>: <span style="color: #808080;"># parcours des indices de liste_coefs</span>
            liste_coefs<span class="br0">&#91;</span>i<span class="br0">&#93;</span> = self.coefs<span class="br0">&#91;</span>i<span class="br0">&#93;</span> - other.coefs<span class="br0">&#91;</span>i<span class="br0">&#93;</span> <span style="color: #808080;"># addition des coefficients de degr&eacute; i</span>
&nbsp;
        <span style="color: #0000ff;">return</span> Polynome<span class="br0">&#40;</span>liste_coefs<span class="br0">&#41;</span> <span style="color: #808080;"># renvoie le polyn&ocirc;me r&eacute;sultat de l'addition</span>
&nbsp;
&nbsp;
    <span style="color: #0000ff;">def</span> reduire<span class="br0">&#40;</span>self<span class="br0">&#41;</span>:
        <span style="color: #808080;"># tant que le dernier &eacute;l&eacute;ment de la liste est nul</span>
        <span style="color: #0000ff;">while</span> round<span class="br0">&#40;</span>self.coefs<span class="br0">&#91;</span>-<span style="color: #cc66cc;">1</span><span class="br0">&#93;</span>,<span style="color: #cc66cc;">12</span><span class="br0">&#41;</span> == <span style="color: #cc66cc;">0</span> <span style="color: #0000ff;">and</span> len<span class="br0">&#40;</span>self.coefs<span class="br0">&#41;</span>&gt;<span style="color: #cc66cc;">1</span>:
            self.coefs.pop<span class="br0">&#40;</span><span class="br0">&#41;</span> <span style="color: #808080;"># supprimer le dernier &eacute;l&eacute;ment</span>
&nbsp;
        <span style="color: #0000ff;">for</span> i <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span>len<span class="br0">&#40;</span>self.coefs<span class="br0">&#41;</span><span class="br0">&#41;</span>:
            self.coefs<span class="br0">&#91;</span>i<span class="br0">&#93;</span> = round<span class="br0">&#40;</span>self.coefs<span class="br0">&#91;</span>i<span class="br0">&#93;</span>,<span style="color: #cc66cc;">12</span><span class="br0">&#41;</span>
&nbsp;
&nbsp;
    <span style="color: #0000ff;">def</span> <span style="color: #0080ff;">__mul__</span><span class="br0">&#40;</span>self, other<span class="br0">&#41;</span>: <span style="color: #808080;"># m&eacute;thode permettant de red&eacute;finir l'op&eacute;rateur &laquo; * &raquo; pour 2 polyn&ocirc;mes : (1 + x) * (1 + 2x) =  1 + 3x + 2x^2</span>
&nbsp;
        <span style="color: #808080;"># initialisation de la liste des coefficients qu'avec des z&eacute;ros</span>
        liste_coefs=<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span><span class="br0">&#93;</span>*<span class="br0">&#40;</span>len<span class="br0">&#40;</span>self.coefs<span class="br0">&#41;</span>+len<span class="br0">&#40;</span>other.coefs<span class="br0">&#41;</span>-<span style="color: #cc66cc;">1</span><span class="br0">&#41;</span> <span style="color: #808080;"># exemple : [0, 0, 0]</span>
        <span style="color: #0000ff;">for</span> i1 <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span>len<span class="br0">&#40;</span>self.coefs<span class="br0">&#41;</span><span class="br0">&#41;</span>: <span style="color: #808080;"># parcours des indices des coefs du polyn&ocirc;me n&deg;1</span>
            <span style="color: #0000ff;">for</span> i2 <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span>len<span class="br0">&#40;</span>other.coefs<span class="br0">&#41;</span><span class="br0">&#41;</span>: <span style="color: #808080;"># parcours des indices des coefs du polyn&ocirc;me n&deg;2</span>
                <span style="color: #808080;"># multiplication des coefficients d'indices i1 et i2</span>
                liste_coefs<span class="br0">&#91;</span>i1+i2<span class="br0">&#93;</span> = liste_coefs<span class="br0">&#91;</span>i1+i2<span class="br0">&#93;</span> + self.coefs<span class="br0">&#91;</span>i1<span class="br0">&#93;</span>*other.coefs<span class="br0">&#91;</span>i2<span class="br0">&#93;</span>
&nbsp;
        poly = Polynome<span class="br0">&#40;</span>liste_coefs<span class="br0">&#41;</span> <span style="color: #808080;"># cr&eacute;ation de l'objet Polynome bas&eacute; sur la liste</span>
&nbsp;
        <span style="color: #808080;"># ajout du nombre d'op&eacute;rations de multiplication entre termes effectu&eacute;es lors de la multiplication entre polyn&ocirc;mes</span>
        poly.nombre_operations = self.nombre_operations + other.nombre_operations +  len<span class="br0">&#40;</span>self.coefs<span class="br0">&#41;</span>*len<span class="br0">&#40;</span>other.coefs<span class="br0">&#41;</span>
&nbsp;
        <span style="color: #0000ff;">return</span> poly <span style="color: #808080;"># renvoie le polyn&ocirc;me r&eacute;sultat de la multiplication</span>
&nbsp;
&nbsp;
    <span style="color: #0000ff;">def</span> __pow__<span class="br0">&#40;</span>self, n<span class="br0">&#41;</span>: <span style="color: #808080;"># m&eacute;thode permettant de red&eacute;finir l'op&eacute;rateur de puissance : self ** n</span>
        <span style="color: #808080;"># on cr&eacute;e l'objet poly &agrave; partir d'une liste contenant un seul &eacute;l&eacute;ment 1, &eacute;l&eacute;ment neutre pour la multiplication des polyn&ocirc;mes</span>
        poly = Polynome<span class="br0">&#40;</span><span class="br0">&#91;</span><span style="color: #cc66cc;">1</span><span class="br0">&#93;</span><span class="br0">&#41;</span> 
&nbsp;
        <span style="color: #0000ff;">for</span> i <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span>n<span class="br0">&#41;</span>: <span style="color: #808080;"># on multiplie n fois poly par self &agrave; l'aide de l'op&eacute;rateur *            </span>
            poly = poly*self <span style="color: #808080;"># &eacute;quivalent &agrave; : poly = poly.__mul__(self)</span>
&nbsp;
        <span style="color: #0000ff;">return</span> poly <span style="color: #808080;"># renvoie le polyn&ocirc;me r&eacute;sultat de l'op&eacute;ration (self ** n)</span>
&nbsp;
&nbsp;
    <span style="color: #0000ff;">def</span> <span style="color: #0080ff;">__eq__</span><span class="br0">&#40;</span>poly1, other<span class="br0">&#41;</span>: <span style="color: #808080;"># m&eacute;thode permettant de red&eacute;finir l'op&eacute;rateur &laquo; == &raquo; pour 2 polyn&ocirc;mes</span>
&nbsp;
        <span style="color: #0000ff;">return</span> <span class="br0">&#40;</span>poly1.coefs==other.coefs<span class="br0">&#41;</span> <span style="color: #808080;"># renvoie True si les 2 listes de coefficients sont &eacute;gales</span>
&nbsp;
&nbsp;
    <span style="color: #0000ff;">def</span> eval<span class="br0">&#40;</span>self,x<span class="br0">&#41;</span>: <span style="color: #808080;"># m&eacute;thode permettant d'&eacute;valuer le polyn&ocirc;me en fonction de x</span>
        <span style="color: #808080;"># intialisation des variables</span>
        valeur_polynome = self.coefs<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span><span class="br0">&#93;</span> <span style="color: #808080;"># valeur_polynome = a0</span>
        power=<span style="color: #cc66cc;">1</span>    
&nbsp;
        <span style="color: #0000ff;">for</span> coef <span style="color: #0000ff;">in</span> self.coefs<span class="br0">&#91;</span><span style="color: #cc66cc;">1</span>:<span class="br0">&#93;</span>: <span style="color: #808080;"># parcours des coefficients du polyn&ocirc;me &agrave; partir de a1 : a1, a2, ..., an</span>
            power = power*x <span style="color: #808080;"># calcul de la puissance de x pour ai : power = x^i</span>
            valeur_polynome += coef*power <span style="color: #808080;"># valeur_polynome = valeur_polynome + ai*x^i</span>
&nbsp;
        <span style="color: #0000ff;">return</span> valeur_polynome <span style="color: #808080;"># renvoie la valeur du polyn&ocirc;me</span>
&nbsp;
    <span style="color: #0000ff;">def</span> eval_horner<span class="br0">&#40;</span>self,x<span class="br0">&#41;</span>: <span style="color: #808080;"># m&eacute;thode permettant d'&eacute;valuer le polyn&ocirc;me en fonction de x</span>
        <span style="color: #808080;"># intialisation de la variable</span>
        valeur_polynome = self.coefs<span class="br0">&#91;</span>-<span style="color: #cc66cc;">1</span><span class="br0">&#93;</span> <span style="color: #808080;"># valeur_polynome = an</span>
&nbsp;
        <span style="color: #0000ff;">for</span> coef <span style="color: #0000ff;">in</span> reversed<span class="br0">&#40;</span>self.coefs<span class="br0">&#91;</span>:-<span style="color: #cc66cc;">1</span><span class="br0">&#93;</span><span class="br0">&#41;</span>: <span style="color: #808080;"># parcours des coefficients du polyn&ocirc;me &agrave; partir de an-1 : an-1, ..., a1, a0</span>
            valeur_polynome = valeur_polynome*x + coef  <span style="color: #808080;"># valeur_polynome = valeur_polynome*x + ai</span>
&nbsp;
        <span style="color: #0000ff;">return</span> valeur_polynome <span style="color: #808080;"># renvoie la valeur du polyn&ocirc;me</span>
&nbsp;
&nbsp;
<span style="color: #0000ff;">def</span> produit_polynomes<span class="br0">&#40;</span>*polynomes<span class="br0">&#41;</span>:
&nbsp;
    <span style="color: #808080;"># test si le tuple polynomes contient plus de 1 &eacute;l&eacute;ment</span>
    <span style="color: #0000ff;">if</span> len<span class="br0">&#40;</span>polynomes<span class="br0">&#41;</span>&gt;<span style="color: #cc66cc;">1</span>:
        i=len<span class="br0">&#40;</span>polynomes<span class="br0">&#41;</span>//<span style="color: #cc66cc;">2</span> <span style="color: #808080;"># valeur du milieu</span>
        <span style="color: #808080;"># appels r&eacute;cursifs</span>
        <span style="color: #0000ff;">return</span> produit_polynomes<span class="br0">&#40;</span>*polynomes<span class="br0">&#91;</span>:i<span class="br0">&#93;</span><span class="br0">&#41;</span>*produit_polynomes<span class="br0">&#40;</span>*polynomes<span class="br0">&#91;</span>i:<span class="br0">&#93;</span><span class="br0">&#41;</span>
    <span style="color: #0000ff;">else</span>: <span style="color: #808080;"># sinon</span>
        <span style="color: #808080;"># renvoie l'unique polyn&ocirc;me du tuple</span>
        <span style="color: #0000ff;">return</span> polynomes<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span><span class="br0">&#93;</span>
&nbsp;
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;I. Produit de polyn&ocirc;mes : m&eacute;thode classique&quot;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># cr&eacute;ation des polyn&ocirc;mes p1 = X + 1; p2 = X + 2; p3 = X + 3; p4 = X + 4</span>
p1 = Polynome<span class="br0">&#40;</span><span class="br0">&#91;</span><span style="color: #cc66cc;">1</span>,<span style="color: #cc66cc;">1</span><span class="br0">&#93;</span><span class="br0">&#41;</span>; p2 = Polynome<span class="br0">&#40;</span><span class="br0">&#91;</span><span style="color: #cc66cc;">2</span>,<span style="color: #cc66cc;">1</span><span class="br0">&#93;</span><span class="br0">&#41;</span>; p3 = Polynome<span class="br0">&#40;</span><span class="br0">&#91;</span><span style="color: #cc66cc;">3</span>,<span style="color: #cc66cc;">1</span><span class="br0">&#93;</span><span class="br0">&#41;</span>; p4 = Polynome<span class="br0">&#40;</span><span class="br0">&#91;</span><span style="color: #cc66cc;">4</span>,<span style="color: #cc66cc;">1</span><span class="br0">&#93;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># produit de polyn&ocirc;mes</span>
p = p1*p1*p2*p2*p3*p3*p4*p4
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;produit = ({0})*({0})*({1})*({1})*({2})*({2})*({3})*({3})&quot;</span>.format<span class="br0">&#40;</span>p1,p2,p3,p4<span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;produit d&eacute;velopp&eacute; = &quot;</span> + str<span class="br0">&#40;</span>p<span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;nombre d'op&eacute;rations = &quot;</span> + str<span class="br0">&#40;</span>p.nombre_operations<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;II. Produit de polyn&ocirc;mes : principe du diviser pour r&eacute;gner&quot;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># produit de polyn&ocirc;mes</span>
<span style="color: #808080;"># p = (p1*p1*p1)*(p2*p2*p2)</span>
<span style="color: #808080;"># p = ((p1*p1)*(p2*p2))*((p3*p3)*(p4*p4))</span>
p = produit_polynomes<span class="br0">&#40;</span>p1,p1,p2,p2,p3,p3,p4,p4<span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;produit = ((({0})*({0}))*(({1})*({1})))*((({2})*({2}))*(({3})*({3})))&quot;</span>.format<span class="br0">&#40;</span>p1,p2,p3,p4<span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;produit d&eacute;velopp&eacute; = &quot;</span> + str<span class="br0">&#40;</span>p<span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;nombre d'op&eacute;rations = &quot;</span> + str<span class="br0">&#40;</span>p.nombre_operations<span class="br0">&#41;</span><span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
<br />
<b>V. Conclusion</b><br />
<br />
Nous avons donc pu montrer les avantages du « diviser pour régner » dans le calcul du produit de nombres entiers, puis dans le développement du produit de petits polynômes, pour enfin le vérifier en Python à l'aide de la classe Polynome.<br />
<br />
<br />
<b>Sources : </b><br />
<br />
<a href="https://fr.wikipedia.org/wiki/Algorithme_de_multiplication_d%27entiers" target="_blank">https://fr.wikipedia.org/wiki/Algori...on_d%27entiers</a><br />
<a href="https://fr.wikipedia.org/wiki/Diviser_pour_r%C3%A9gner_(informatique)" target="_blank">https://fr.wikipedia.org/wiki/Divise...(informatique)</a><br />
<a href="https://fr.wikipedia.org/wiki/Arbre_de_produits" target="_blank">https://fr.wikipedia.org/wiki/Arbre_de_produits</a><br />
<a href="https://fr.wikipedia.org/wiki/Tri_fusion" target="_blank">https://fr.wikipedia.org/wiki/Tri_fusion</a></blockquote>

]]></content:encoded>
			<dc:creator>User</dc:creator>
			<guid isPermaLink="true">https://www.developpez.net/forums/blogs/44027-user/b10566/produit-polynomes-python-principe-diviser-regner/</guid>
		</item>
		<item>
			<title>Mathématiques et Python : matrice carrée et polynôme caractéristique</title>
			<link>https://www.developpez.net/forums/blogs/44027-user/b10555/mathematiques-python-matrice-carree-polynome-caracteristique/</link>
			<pubDate>Thu, 28 Dec 2023 15:48:01 GMT</pubDate>
			<description>*I. Introduction* 
 
On...</description>
			<content:encoded><![CDATA[<blockquote class="blogcontent restore"><font size="3"><br />
<b>I. Introduction</b><br />
<br />
On souhaite créer une fonction Python qui pourra déterminer le polynôme caractéristique d'une <a href="https://fr.wikipedia.org/wiki/Matrice_(math%C3%A9matiques)" target="_blank">matrice</a> carrée.<br />
<br />
Ce polynôme renferme d'importantes informations sur la matrice, comme ses <a href="https://fr.wikipedia.org/wiki/Valeur_propre_(synth%C3%A8se)" target="_blank">valeurs propres</a>, son <a href="https://fr.wikipedia.org/wiki/D%C3%A9terminant_(math%C3%A9matiques)" target="_blank">déterminant</a>, etc. Il permet aussi d'obtenir l'équation caractéristique associée à une <a href="https://fr.wikipedia.org/wiki/Suite_r%C3%A9currente_lin%C3%A9aire" target="_blank">suite récurrente linéaire</a>.<br />
<br />
<br />
<b>II. Définitions mathématiques</b><br />
<br />
<br />
<b>II-A. Polynôme caractéristique</b><br />
<br />
D'après Wikipedia, si on considère <b><i>M</i></b> une matrice carrée d'ordre <b>n</b>. Le <a href="https://fr.wikipedia.org/wiki/Polyn%C3%B4me_caract%C3%A9ristique" target="_blank">polynôme caractéristique</a> de <b><i>M</i></b>, noté <b><i>p<sub>M</sub></i>(X)</b>, est le polynôme défini par : <br />
<br />
<img src="https://www.developpez.net/forums/attachments/p647407d1701775545/c-cpp/c/reseau/librairies-standard-slang-h-curses-h/matrice_polynome.png/" border="0" alt="Nom : matrice_polynome.png
Affichages : 42599
Taille : 1,3 Ko"  style="float: CONFIG" /><br />
<br />
où <b>det</b> est le déterminant des matrices, <b><i>I<sub>n</sub></i></b> désigne la <a href="https://fr.wikipedia.org/wiki/Matrice_identit%C3%A9" target="_blank">matrice identité</a> d'ordre <b>n</b>.<br />
<br />
Par exemple, pour une matrice <b><i>M</i></b> d'ordre <b>2</b> :<br />
<br />
<img src="https://www.developpez.net/forums/attachments/p647408d1701775602/c-cpp/c/reseau/librairies-standard-slang-h-curses-h/matrice2.png/" border="0" alt="Nom : matrice2.png
Affichages : 8612
Taille : 3,1 Ko"  style="float: CONFIG" /><br />
<br />
<br />
<b>II-B. Calcul du déterminant - Formule de Laplace</b><br />
<br />
En algèbre linéaire, la <a href="https://fr.wikipedia.org/wiki/Comatrice" target="_blank">comatrice</a> d'une matrice carrée <b><i>A</i></b> est une matrice carrée de même taille, dont les coefficients, appelés les cofacteurs de <i>A</i>, interviennent dans le développement du déterminant de A suivant une ligne ou une colonne. <br />
<br />
Si <b><i>A</i></b> est une matrice inversible, sa comatrice intervient également dans une expression de son inverse. <br />
<br />
Le cofacteur d'indice <b>i, j</b> de <b><i>A</i></b> est : <br />
<br />
<img src="https://www.developpez.net/forums/attachments/p647386d1701767362/c-cpp/c/reseau/librairies-standard-slang-h-curses-h/cofacteur.png/" border="0" alt="Nom : cofacteur.png
Affichages : 8554
Taille : 2,4 Ko"  style="float: CONFIG" /><br />
<br />
<ul><li style=""><b><i>A</i>'<sub>i,j</sub></b> est la matrice carrée de taille <b>n</b> déduite de <b><i>A</i></b> en remplaçant la <b>j</b>-ème colonne par une colonne constituée uniquement de zéros, sauf un <b>1</b> sur la <b>i</b>-ème ligne ;</li><li style=""><b><i>A</i><sub>i,j</sub></b> est la sous-matrice carrée de taille <b>n–1</b> déduite de <b><i>A</i></b> en supprimant la <b>i</b>-ème ligne et la <b>j</b>-ème colonne (son déterminant fait donc partie des mineurs de <b><i>A</i></b>).</li></ul><br />
La comatrice de <b><i>A</i></b> est la matrice de ses cofacteurs. <br />
<br />
Formule de développement d'un déterminant d'ordre <b>n</b> par rapport à la ligne <b>i</b> : <br />
<br />
<img src="https://www.developpez.net/forums/attachments/p647423d1701785475/c-cpp/c/reseau/librairies-standard-slang-h-curses-h/formule_laplace2.png/" border="0" alt="Nom : formule_laplace2.png
Affichages : 8557
Taille : 1,8 Ko"  style="float: CONFIG" /><br />
<br />
Prenons comme exemple la matrice :<br />
<br />
<img src="https://www.developpez.net/forums/attachments/p647388d1701767409/c-cpp/c/reseau/librairies-standard-slang-h-curses-h/matrice_a.png/" border="0" alt="Nom : matrice_A.png
Affichages : 8535
Taille : 1,7 Ko"  style="float: CONFIG" /><br />
<br />
Son développement nous donne :<br />
<br />
<img src="https://www.developpez.net/forums/attachments/p647389d1701767430/c-cpp/c/reseau/librairies-standard-slang-h-curses-h/det_a.png/" border="0" alt="Nom : det_A.png
Affichages : 8554
Taille : 4,5 Ko"  style="float: CONFIG" /><br />
<br />
On peut également développer le déterminant par rapport à <b>j</b>.<br />
<br />
<br />
<br />
<b>III. Implémentation en Python</b><br />
<br />
On utilise à nouveau notre <a href="https://www.developpez.net/forums/blogs/44027-user/b10406/creer-classe-polynome-python/" target="_blank">classe Polynome</a> pour obtenir le polynôme caractéristique à partir de la matrice carrée.<br />
<br />
<br />
<b>III-A. Création de la matrice du polynôme caractéristique</b><br />
<br />
On va d'abord transformer la matrice <b><i>M</i></b> en matrice du polynôme résultat de l'expression <b><i>X.I</i><sub>n</sub> - <i>M</i></b> :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">def</span> matrice_polynome<span class="br0">&#40;</span>mat<span class="br0">&#41;</span>:
    <span style="color: #808080;"># cr&eacute;ation de la matrice du polyn&ocirc;me caract&eacute;ristique</span>
&nbsp;
    <span style="color: #808080;"># parcours des indices des lignes de la matrice</span>
    <span style="color: #0000ff;">for</span> i <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span>len<span class="br0">&#40;</span>mat<span class="br0">&#41;</span><span class="br0">&#41;</span>:
        <span style="color: #808080;"># parcours des indices des colonnes de la matrice</span>
        <span style="color: #0000ff;">for</span> j <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span>len<span class="br0">&#40;</span>mat<span class="br0">&#41;</span><span class="br0">&#41;</span>:
            <span style="color: #0000ff;">if</span> i==j: <span style="color: #808080;"># si le coefficient est sur la diagonale</span>
                <span style="color: #808080;"># On copie &agrave; cet emplacement le polyn&ocirc;me P(X) = X - mat[i][i]</span>
                mat<span class="br0">&#91;</span>i<span class="br0">&#93;</span><span class="br0">&#91;</span>i<span class="br0">&#93;</span> = Polynome<span class="br0">&#40;</span><span class="br0">&#91;</span>-mat<span class="br0">&#91;</span>i<span class="br0">&#93;</span><span class="br0">&#91;</span>i<span class="br0">&#93;</span>, <span style="color: #cc66cc;">1</span><span class="br0">&#93;</span><span class="br0">&#41;</span>
            <span style="color: #0000ff;">else</span>: <span style="color: #808080;"># sinon le polyn&ocirc;me P(X) = - mat[i][i]</span>
                mat<span class="br0">&#91;</span>i<span class="br0">&#93;</span><span class="br0">&#91;</span>j<span class="br0">&#93;</span> = Polynome<span class="br0">&#40;</span><span class="br0">&#91;</span>-mat<span class="br0">&#91;</span>i<span class="br0">&#93;</span><span class="br0">&#91;</span>j<span class="br0">&#93;</span><span class="br0">&#93;</span><span class="br0">&#41;</span>
&nbsp;
    <span style="color: #808080;"># renvoi la matrice du polyn&ocirc;me caract&eacute;ristique</span>
    <span style="color: #0000ff;">return</span> mat</pre></td></tr></table></pre>
</div><br />
<br />
<b>III-B. Développement du déterminant de la matrice du polynôme</b><br />
<br />
On va utiliser ensuite la formule de développement de Laplace par rapport à la ligne <b>i</b> pour obtenir le polynôme caractéristique de la matrice.<br />
<br />
La fonction suivante renvoie donc le polynôme caractéristique recherché :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">def</span> determinant<span class="br0">&#40;</span>mat<span class="br0">&#41;</span>:
    <span style="color: #808080;"># d&eacute;veloppement du d&eacute;terminant de la matrice mat par rapport la ligne i</span>
&nbsp;
    <span style="color: #808080;"># si la matrice est d'ordre 1</span>
    <span style="color: #0000ff;">if</span> len<span class="br0">&#40;</span>mat<span class="br0">&#41;</span>==<span style="color: #cc66cc;">1</span>:
        <span style="color: #808080;"># on renvoie l'unique &eacute;l&eacute;ment de la matrice</span>
        <span style="color: #0000ff;">return</span> mat<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span style="color: #cc66cc;">0</span><span class="br0">&#93;</span>
&nbsp;
    <span style="color: #0000ff;">else</span>: <span style="color: #808080;"># sinon</span>
        <span style="color: #808080;"># cr&eacute;ation du polyn&ocirc;me nul</span>
        d = Polynome<span class="br0">&#40;</span><span class="br0">&#91;</span><span style="color: #cc66cc;">0</span><span class="br0">&#93;</span><span class="br0">&#41;</span>
&nbsp;
        <span style="color: #808080;"># parcours des indices des colonnes de la matrice</span>
        <span style="color: #0000ff;">for</span> j, element <span style="color: #0000ff;">in</span> enumerate<span class="br0">&#40;</span>mat<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span><span class="br0">&#93;</span><span class="br0">&#41;</span>:
            <span style="color: #808080;"># suppression de la 1re ligne de la matrice : mat[1:]</span>
            <span style="color: #808080;"># + suppression de la colonne j dans la matrice mat</span>
            comat= <span class="br0">&#91;</span>ligne<span class="br0">&#91;</span>:j<span class="br0">&#93;</span> + ligne<span class="br0">&#91;</span>j+<span style="color: #cc66cc;">1</span>:<span class="br0">&#93;</span> <span style="color: #0000ff;">for</span> ligne <span style="color: #0000ff;">in</span> mat<span class="br0">&#91;</span><span style="color: #cc66cc;">1</span>:<span class="br0">&#93;</span><span class="br0">&#93;</span>
&nbsp;
            <span style="color: #808080;"># det(M) = (-1)**(j)*a(1,j)*(com M)(0,j)</span>
            d += Polynome<span class="br0">&#40;</span><span class="br0">&#91;</span>pow<span class="br0">&#40;</span>-<span style="color: #cc66cc;">1</span>,j<span class="br0">&#41;</span><span class="br0">&#93;</span><span class="br0">&#41;</span>*element*determinant<span class="br0">&#40;</span>comat<span class="br0">&#41;</span>
&nbsp;
        <span style="color: #808080;"># on renvoie le polyn&ocirc;me caract&eacute;ristique</span>
        <span style="color: #0000ff;">return</span> d</pre></td></tr></table></pre>
</div><br />
Testons maintenant nos fonctions :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:168px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #808080;"># matrice exemple</span>
m = <span class="br0">&#91;</span><span class="br0">&#91;</span><span style="color: #cc66cc;">2</span>, <span style="color: #cc66cc;">1</span><span class="br0">&#93;</span>, <span class="br0">&#91;</span>-<span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">0</span><span class="br0">&#93;</span><span class="br0">&#93;</span>
&nbsp;
<span style="color: #808080;"># cr&eacute;ation de la matrice du polyn&ocirc;me caract&eacute;ristique</span>
mp = matrice_polynome<span class="br0">&#40;</span>m<span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># d&eacute;termination du polyn&ocirc;me caract&eacute;ristique associ&eacute; &agrave; la matrice m</span>
p = determinant<span class="br0">&#40;</span>mp<span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche le polyn&ocirc;me caract&eacute;ristique</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Pm(X) = &quot;</span> + str<span class="br0">&#40;</span>p<span class="br0">&#41;</span><span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
Le code affiche :<br />
<br />
<span class="highlight">Pm(X) = 1 - 2.X + X^2</span><br />
<br />
<br />
<b>III-C. Application - Suite récurrence linéaire et matrice compagnon</b><br />
<br />
Soit une <a href="https://fr.wikipedia.org/wiki/Suite_r%C3%A9currente_lin%C3%A9aire" target="_blank">suite récurrente linéaire</a> définie sous sa forme générale par la relation :<br />
<br />
<img src="https://www.developpez.net/forums/attachments/p647390d1701767494/c-cpp/c/reseau/librairies-standard-slang-h-curses-h/relation_recurrence.png/" border="0" alt="Nom : relation_recurrence.png
Affichages : 8528
Taille : 2,4 Ko"  style="float: CONFIG" /><br />
<br />
Sa matrice compagnon est alors de la forme :<br />
<br />
<img src="https://www.developpez.net/forums/attachments/p647391d1701767513/c-cpp/c/reseau/librairies-standard-slang-h-curses-h/matrice_compagnon.png/" border="0" alt="Nom : matrice_compagnon.png
Affichages : 8544
Taille : 3,9 Ko"  style="float: CONFIG" /><br />
<br />
Si on considère maintenant la suite de Fibonacci et sa relation de récurrence :<br />
<br />
<img src="https://www.developpez.net/forums/attachments/p647392d1701767538/c-cpp/c/reseau/librairies-standard-slang-h-curses-h/relation_fibonacci.png/" border="0" alt="Nom : relation_fibonacci.png
Affichages : 8517
Taille : 1,0 Ko"  style="float: CONFIG" /><br />
<br />
On peut alors obtenir sa matrice compagnon :<br />
<br />
<img src="https://www.developpez.net/forums/attachments/p647393d1701767559/c-cpp/c/reseau/librairies-standard-slang-h-curses-h/matrice_fibonacci.png/" border="0" alt="Nom : matrice_fibonacci.png
Affichages : 8527
Taille : 950 octets"  style="float: CONFIG" /><br />
<br />
D'où l'on déduit son polynôme caractéristique :<br />
<br />
<img src="https://www.developpez.net/forums/attachments/p647394d1701767601/c-cpp/c/reseau/librairies-standard-slang-h-curses-h/polynome_fibonacci.png/" border="0" alt="Nom : polynome_fibonacci.png
Affichages : 8530
Taille : 3,9 Ko"  style="float: CONFIG" /><br />
<br />
On voit tout de suite le lien avec le nombre d'or <b>&#120593;</b> qui est racine de l'équation caractéristique :<br />
<br />
<img src="https://www.developpez.net/forums/attachments/p647395d1701767622/c-cpp/c/reseau/librairies-standard-slang-h-curses-h/equation_nombre_or1.png/" border="0" alt="Nom : equation_nombre_or1.png
Affichages : 8512
Taille : 1,2 Ko"  style="float: CONFIG" /><br />
<br />
Si l'on multiplie les deux côtés par <b>&#120593;<sup>n</sup></b>, on obtient:<br />
<br />
<span class="highlight">&#120593;<sup>n+2</sup> = &#120593;<sup>n+1</sup> + &#120593;<sup>n</sup></span><br />
<br />
Donc la suite <b>(&#120593;<sup>n</sup>)</b> est une suite de Fibonacci. <br />
<br />
<br />
Mise en œuvre en Python :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:168px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #808080;"># matrice compagnon associ&eacute;e &agrave; la suite de Fibonacci</span>
m = <span class="br0">&#91;</span><span class="br0">&#91;</span><span style="color: #cc66cc;">0</span>, <span style="color: #cc66cc;">1</span><span class="br0">&#93;</span>, <span class="br0">&#91;</span><span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">1</span><span class="br0">&#93;</span><span class="br0">&#93;</span>
&nbsp;
<span style="color: #808080;"># cr&eacute;ation de la matrice du polyn&ocirc;me caract&eacute;ristique</span>
mp = matrice_polynome<span class="br0">&#40;</span>m<span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># d&eacute;termination du polyn&ocirc;me caract&eacute;ristique associ&eacute; &agrave; la matrice m</span>
p = determinant<span class="br0">&#40;</span>mp<span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche le polyn&ocirc;me caract&eacute;ristique</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Pm(X) = &quot;</span> + str<span class="br0">&#40;</span>p<span class="br0">&#41;</span><span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
Le code affiche :<br />
<br />
<span class="highlight">Pm(X) = -1 - X + X^2</span><br />
<br />
<br />
<b>III-D. Module complet</b><br />
<br />
On donne enfin le code complet du module :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="40"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br />50<br />51<br />52<br />53<br />54<br />55<br />56<br />57<br />58<br />59<br />60<br />61<br />62<br />63<br />64<br />65<br />66<br />67<br />68<br />69<br />70<br />71<br />72<br />73<br />74<br />75<br />76<br />77<br />78<br />79<br />80<br />81<br />82<br />83<br />84<br />85<br />86<br />87<br />88<br />89<br />90<br />91<br />92<br />93<br />94<br />95<br />96<br />97<br />98<br />99<br />100<br />101<br />102<br />103<br />104<br />105<br />106<br />107<br />108<br />109<br />110<br />111<br />112<br />113<br />114<br />115<br />116<br />117<br />118<br />119<br />120<br />121<br />122<br />123<br />124<br />125<br />126<br />127<br />128<br />129<br />130<br />131<br />132<br />133<br />134<br />135<br />136<br />137<br />138<br />139<br />140<br />141<br />142<br />143<br />144<br />145<br />146<br />147<br />148<br />149<br />150<br />151<br />152<br />153<br />154<br />155<br />156<br />157<br />158<br />159<br />160<br />161<br />162<br />163<br />164<br />165<br />166<br />167<br />168<br />169<br />170<br />171<br />172<br />173<br />174<br />175<br />176<br />177<br />178<br />179<br />180<br />181<br />182<br />183<br />184<br />185<br />186<br />187<br />188<br />189<br />190<br />191<br />192<br />193<br />194<br />195<br />196<br />197<br />198<br />199<br />200<br />201<br />202<br />203<br />204<br />205<br />206<br />207<br />208<br />209<br />210<br />211<br />212<br />213<br />214<br />215<br />216<br />217<br />218<br />219<br />220<br />221<br />222<br />223<br />224<br />225<br />226<br />227<br />228<br />229<br />230<br />231<br />232<br />233<br />234<br />235<br />236<br />237<br />238<br />239<br />240<br />241<br />242<br />243<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">class</span> Polynome:
&nbsp;
    <span style="color: #0000ff;">def</span> <span style="color: #0080ff;">__init__</span><span class="br0">&#40;</span>self, liste_coefs=<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span><span class="br0">&#93;</span><span class="br0">&#41;</span>: <span style="color: #808080;"># m&eacute;thode constructeur de la classe</span>
&nbsp;
	<span style="color: #808080;"># on d&eacute;finit la liste des coefficients du polyn&ocirc;me [a0, a1, ..., an]</span>
        self.coefs = liste_coefs
&nbsp;
	<span style="color: #808080;"># suppression si n&eacute;cessaire des z&eacute;ros en queue de liste de coefficients. Exemple : [2, 3, 1, 0, 0] -&gt; [2, 3, 1]</span>
        self.reduire<span class="br0">&#40;</span><span class="br0">&#41;</span> 
&nbsp;
    <span style="color: #0000ff;">def</span> __str__<span class="br0">&#40;</span>self<span class="br0">&#41;</span>: <span style="color: #808080;"># permet d'afficher le polyn&ocirc;me sous la forme 1 + 2x + 3x^2</span>
        s=<span style="color: #FF0000;">&quot;&quot;</span> <span style="color: #808080;"># initialisation de la cha&icirc;ne de caract&egrave;res</span>
        <span style="color: #808080;"># on v&eacute;rifie d&#146;abord si le degr&eacute; du polyn&ocirc;me est nul</span>
        <span style="color: #0000ff;">if</span> <span class="br0">&#40;</span>len<span class="br0">&#40;</span>self.coefs<span class="br0">&#41;</span>-<span style="color: #cc66cc;">1</span>==<span style="color: #cc66cc;">0</span><span class="br0">&#41;</span>:
            <span style="color: #0000ff;">return</span> str<span class="br0">&#40;</span>self.coefs<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span><span class="br0">&#93;</span><span class="br0">&#41;</span>
        <span style="color: #0000ff;">else</span>: <span style="color: #808080;"># sinon</span>
            <span style="color: #0000ff;">if</span> self.coefs<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span><span class="br0">&#93;</span>!=<span style="color: #cc66cc;">0</span>:
                s=str<span class="br0">&#40;</span>self.coefs<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span><span class="br0">&#93;</span><span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot; + &quot;</span>
            <span style="color: #0000ff;">for</span> i <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span><span style="color: #cc66cc;">1</span>, len<span class="br0">&#40;</span>self.coefs<span class="br0">&#41;</span><span class="br0">&#41;</span>: <span style="color: #808080;"># parcours des indices des coefficients du polyn&ocirc;me : [a1, a2, ..., an]</span>
                <span style="color: #0000ff;">if</span> self.coefs<span class="br0">&#91;</span>i<span class="br0">&#93;</span>!=<span style="color: #cc66cc;">0</span>: <span style="color: #808080;"># si le coefficient de degr&eacute; i n'est pas nul</span>
                    <span style="color: #0000ff;">if</span> self.coefs<span class="br0">&#91;</span>i<span class="br0">&#93;</span>!=<span style="color: #cc66cc;">1</span>: <span style="color: #808080;"># si le coefficient de degr&eacute; i est diff&eacute;rent de 1</span>
                        s+=<span style="color: #FF0000;">&quot;{}.X^{} + &quot;</span>.format<span class="br0">&#40;</span>self.coefs<span class="br0">&#91;</span>i<span class="br0">&#93;</span>,i<span class="br0">&#41;</span>
                    <span style="color: #0000ff;">else</span>: s+=<span style="color: #FF0000;">&quot;X^{} + &quot;</span>.format<span class="br0">&#40;</span>i<span class="br0">&#41;</span>  
&nbsp;
            <span style="color: #808080;"># &eacute;limination des caract&egrave;res en trop           </span>
            s = s<span class="br0">&#91;</span>:-<span style="color: #cc66cc;">3</span><span class="br0">&#93;</span>.replace<span class="br0">&#40;</span><span style="color: #FF0000;">&quot;+ -&quot;</span>, <span style="color: #FF0000;">&quot;- &quot;</span><span class="br0">&#41;</span>.replace<span class="br0">&#40;</span><span style="color: #FF0000;">&quot;X^1 &quot;</span>,<span style="color: #FF0000;">&quot;X &quot;</span><span class="br0">&#41;</span>.replace<span class="br0">&#40;</span><span style="color: #FF0000;">&quot; 1.X&quot;</span>,<span style="color: #FF0000;">&quot; X&quot;</span><span class="br0">&#41;</span>
            <span style="color: #0000ff;">if</span> s<span class="br0">&#91;</span>-<span style="color: #cc66cc;">2</span>:<span class="br0">&#93;</span>==<span style="color: #FF0000;">&quot;^1&quot;</span>: s = s<span class="br0">&#91;</span>:-<span style="color: #cc66cc;">2</span><span class="br0">&#93;</span>
            <span style="color: #0000ff;">if</span> s<span class="br0">&#91;</span>:<span style="color: #cc66cc;">3</span><span class="br0">&#93;</span>==<span style="color: #FF0000;">&quot;1.X&quot;</span>: s = s<span class="br0">&#91;</span><span style="color: #cc66cc;">3</span>:<span class="br0">&#93;</span>
&nbsp;
            <span style="color: #0000ff;">return</span> s <span style="color: #808080;"># on retourne l'expression du polyn&ocirc;me</span>
&nbsp;
&nbsp;
    <span style="color: #0000ff;">def</span> degre<span class="br0">&#40;</span>self<span class="br0">&#41;</span>: <span style="color: #808080;"># retourne le degr&eacute; du polyn&ocirc;me</span>
        <span style="color: #0000ff;">return</span> <span class="br0">&#40;</span>len<span class="br0">&#40;</span>self.coefs<span class="br0">&#41;</span>-<span style="color: #cc66cc;">1</span><span class="br0">&#41;</span>
&nbsp;
&nbsp;
    <span style="color: #0000ff;">def</span> <span style="color: #0080ff;">__add__</span><span class="br0">&#40;</span>self, other<span class="br0">&#41;</span>: <span style="color: #808080;"># m&eacute;thode permettant de red&eacute;finir l'op&eacute;rateur &laquo; + &raquo; pour 2 polyn&ocirc;mes : (1 + 2x + x^2) + (1 + x) = 2 + 3x + x^2</span>
        <span style="color: #808080;"># p1 = self, p2 = other     </span>
        <span style="color: #0000ff;">if</span> len<span class="br0">&#40;</span>other.coefs<span class="br0">&#41;</span> &gt;len<span class="br0">&#40;</span>self.coefs<span class="br0">&#41;</span>: <span style="color: #808080;"># si degr&eacute; de p2 &gt; degr&eacute; de p1 </span>
            liste_coefs = other.coefs<span class="br0">&#91;</span>:<span class="br0">&#93;</span>; n = len<span class="br0">&#40;</span>self.coefs<span class="br0">&#41;</span> <span style="color: #808080;"># on copie les coefs du polyn&ocirc;me de degr&eacute; le plus &eacute;lev&eacute; et la longueur de la liste de coefs la plus petite. </span>
        <span style="color: #0000ff;">else</span>: liste_coefs = self.coefs<span class="br0">&#91;</span>:<span class="br0">&#93;</span>; n = len<span class="br0">&#40;</span>other.coefs<span class="br0">&#41;</span> <span style="color: #808080;"># sinon, ...</span>
&nbsp;
        <span style="color: #0000ff;">for</span> i <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span>n<span class="br0">&#41;</span>: <span style="color: #808080;"># parcours des indices de liste_coefs</span>
            liste_coefs<span class="br0">&#91;</span>i<span class="br0">&#93;</span> = self.coefs<span class="br0">&#91;</span>i<span class="br0">&#93;</span> + other.coefs<span class="br0">&#91;</span>i<span class="br0">&#93;</span> <span style="color: #808080;"># addition des coefficients de degr&eacute; i</span>
&nbsp;
        <span style="color: #0000ff;">return</span> Polynome<span class="br0">&#40;</span>liste_coefs<span class="br0">&#41;</span> <span style="color: #808080;"># renvoie le polyn&ocirc;me r&eacute;sultat de l'addition</span>
&nbsp;
&nbsp;
    <span style="color: #0000ff;">def</span> __sub__<span class="br0">&#40;</span>self, other<span class="br0">&#41;</span>: <span style="color: #808080;"># m&eacute;thode permettant de red&eacute;finir l'op&eacute;rateur &laquo; + &raquo; pour 2 polyn&ocirc;mes : (1 + 2x + x^2) + (1 + x) = 2 + 3x + x^2</span>
        <span style="color: #808080;"># p1 = self, p2 = other     </span>
        <span style="color: #0000ff;">if</span> len<span class="br0">&#40;</span>other.coefs<span class="br0">&#41;</span> &gt;len<span class="br0">&#40;</span>self.coefs<span class="br0">&#41;</span>: <span style="color: #808080;"># si degr&eacute; de p2 &gt; degr&eacute; de p1 </span>
            liste_coefs = other.coefs<span class="br0">&#91;</span>:<span class="br0">&#93;</span>; n = len<span class="br0">&#40;</span>self.coefs<span class="br0">&#41;</span> <span style="color: #808080;"># on copie les coefs du polyn&ocirc;me de degr&eacute; le plus &eacute;lev&eacute; et la longueur de la liste de coefs la plus petite. </span>
        <span style="color: #0000ff;">else</span>: liste_coefs = self.coefs<span class="br0">&#91;</span>:<span class="br0">&#93;</span>; n = len<span class="br0">&#40;</span>other.coefs<span class="br0">&#41;</span> <span style="color: #808080;"># sinon, ...</span>
&nbsp;
        <span style="color: #0000ff;">for</span> i <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span>n<span class="br0">&#41;</span>: <span style="color: #808080;"># parcours des indices de liste_coefs</span>
            liste_coefs<span class="br0">&#91;</span>i<span class="br0">&#93;</span> = self.coefs<span class="br0">&#91;</span>i<span class="br0">&#93;</span> - other.coefs<span class="br0">&#91;</span>i<span class="br0">&#93;</span> <span style="color: #808080;"># addition des coefficients de degr&eacute; i</span>
&nbsp;
        <span style="color: #0000ff;">return</span> Polynome<span class="br0">&#40;</span>liste_coefs<span class="br0">&#41;</span> <span style="color: #808080;"># renvoie le polyn&ocirc;me r&eacute;sultat de l'addition</span>
&nbsp;
&nbsp;
    <span style="color: #0000ff;">def</span> reduire<span class="br0">&#40;</span>self<span class="br0">&#41;</span>:
        <span style="color: #808080;"># tant que le dernier &eacute;l&eacute;ment de la liste est nul</span>
        <span style="color: #0000ff;">while</span> round<span class="br0">&#40;</span>self.coefs<span class="br0">&#91;</span>-<span style="color: #cc66cc;">1</span><span class="br0">&#93;</span>,<span style="color: #cc66cc;">12</span><span class="br0">&#41;</span> == <span style="color: #cc66cc;">0</span> <span style="color: #0000ff;">and</span> len<span class="br0">&#40;</span>self.coefs<span class="br0">&#41;</span>&gt;<span style="color: #cc66cc;">1</span>:
            self.coefs.pop<span class="br0">&#40;</span><span class="br0">&#41;</span> <span style="color: #808080;"># supprimer le dernier &eacute;l&eacute;ment</span>
&nbsp;
        <span style="color: #0000ff;">for</span> i <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span>len<span class="br0">&#40;</span>self.coefs<span class="br0">&#41;</span><span class="br0">&#41;</span>:
            self.coefs<span class="br0">&#91;</span>i<span class="br0">&#93;</span> = round<span class="br0">&#40;</span>self.coefs<span class="br0">&#91;</span>i<span class="br0">&#93;</span>,<span style="color: #cc66cc;">12</span><span class="br0">&#41;</span>
&nbsp;
&nbsp;
    <span style="color: #0000ff;">def</span> <span style="color: #0080ff;">__mul__</span><span class="br0">&#40;</span>self, other<span class="br0">&#41;</span>: <span style="color: #808080;"># m&eacute;thode permettant de red&eacute;finir l'op&eacute;rateur &laquo; * &raquo; pour 2 polyn&ocirc;mes : (1 + x) * (1 + 2x) =  1 + 3x + 2x^2</span>
&nbsp;
        <span style="color: #0000ff;">if</span> isinstance<span class="br0">&#40;</span>other,tuple<span class="br0">&#41;</span>:
&nbsp;
            coef = other<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span><span class="br0">&#93;</span>; degre = other<span class="br0">&#91;</span><span style="color: #cc66cc;">1</span><span class="br0">&#93;</span>
            liste_coefs = <span class="br0">&#91;</span><span style="color: #cc66cc;">0</span><span class="br0">&#93;</span>*degre + self.coefs
&nbsp;
            <span style="color: #0000ff;">for</span> i <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span>degre, len<span class="br0">&#40;</span>liste_coefs<span class="br0">&#41;</span><span class="br0">&#41;</span>:
                liste_coefs<span class="br0">&#91;</span>i<span class="br0">&#93;</span> = liste_coefs<span class="br0">&#91;</span>i<span class="br0">&#93;</span>*coef
&nbsp;
        <span style="color: #0000ff;">else</span>:
            <span style="color: #808080;"># initialisation de la liste des coefficients qu'avec des z&eacute;ros</span>
            liste_coefs=<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span><span class="br0">&#93;</span>*<span class="br0">&#40;</span>len<span class="br0">&#40;</span>self.coefs<span class="br0">&#41;</span>+len<span class="br0">&#40;</span>other.coefs<span class="br0">&#41;</span>-<span style="color: #cc66cc;">1</span><span class="br0">&#41;</span> <span style="color: #808080;"># exemple : [0, 0, 0]</span>
            <span style="color: #0000ff;">for</span> i1 <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span>len<span class="br0">&#40;</span>self.coefs<span class="br0">&#41;</span><span class="br0">&#41;</span>: <span style="color: #808080;"># parcours des indices des coefs du polyn&ocirc;me n&deg;1</span>
                <span style="color: #0000ff;">for</span> i2 <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span>len<span class="br0">&#40;</span>other.coefs<span class="br0">&#41;</span><span class="br0">&#41;</span>: <span style="color: #808080;"># parcours des indices des coefs du polyn&ocirc;me n&deg;2</span>
                    <span style="color: #808080;"># multiplication des coefficients d'indices i1 et i2</span>
                    liste_coefs<span class="br0">&#91;</span>i1+i2<span class="br0">&#93;</span> = liste_coefs<span class="br0">&#91;</span>i1+i2<span class="br0">&#93;</span> + self.coefs<span class="br0">&#91;</span>i1<span class="br0">&#93;</span>*other.coefs<span class="br0">&#91;</span>i2<span class="br0">&#93;</span>
&nbsp;
        poly = Polynome<span class="br0">&#40;</span>liste_coefs<span class="br0">&#41;</span> <span style="color: #808080;"># cr&eacute;ation de l'objet Polynome bas&eacute; sur la liste</span>
&nbsp;
        <span style="color: #0000ff;">return</span> poly <span style="color: #808080;"># renvoie le polyn&ocirc;me r&eacute;sultat de la multiplication</span>
&nbsp;
&nbsp;
    <span style="color: #0000ff;">def</span> __pow__<span class="br0">&#40;</span>self, n<span class="br0">&#41;</span>: <span style="color: #808080;"># m&eacute;thode permettant de red&eacute;finir l'op&eacute;rateur de puissance : self ** n</span>
        <span style="color: #808080;"># on cr&eacute;e l'objet poly &agrave; partir d'une liste contenant un seul &eacute;l&eacute;ment 1, &eacute;l&eacute;ment neutre pour la multiplication des polyn&ocirc;mes</span>
        poly = Polynome<span class="br0">&#40;</span><span class="br0">&#91;</span><span style="color: #cc66cc;">1</span><span class="br0">&#93;</span><span class="br0">&#41;</span> 
&nbsp;
        <span style="color: #0000ff;">for</span> i <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span>n<span class="br0">&#41;</span>: <span style="color: #808080;"># on multiplie n fois poly par self &agrave; l'aide de l'op&eacute;rateur *            </span>
            poly = poly*self <span style="color: #808080;"># &eacute;quivalent &agrave; : poly = poly.__mul__(self)</span>
&nbsp;
        <span style="color: #0000ff;">return</span> poly <span style="color: #808080;"># renvoie le polyn&ocirc;me r&eacute;sultat de l'op&eacute;ration (self ** n)</span>
&nbsp;
&nbsp;
    <span style="color: #0000ff;">def</span> __truediv__<span class="br0">&#40;</span>self, other<span class="br0">&#41;</span>: <span style="color: #808080;"># m&eacute;thode permettant de red&eacute;finir l'op&eacute;rateur &laquo; / &raquo; pour 2 polyn&ocirc;mes</span>
&nbsp;
        <span style="color: #808080;"># si le degr&eacute; de self est inf&eacute;rieur au degr&eacute; de other</span>
        <span style="color: #0000ff;">if</span> self.degre<span class="br0">&#40;</span><span class="br0">&#41;</span>&lt;other.degre<span class="br0">&#40;</span><span class="br0">&#41;</span>:
            <span style="color: #808080;"># on renvoie (0, self) : q=0, r=self</span>
            <span style="color: #0000ff;">return</span> <span class="br0">&#40;</span>Polynome<span class="br0">&#40;</span><span class="br0">&#91;</span><span style="color: #cc66cc;">0</span><span class="br0">&#93;</span><span class="br0">&#41;</span>, self<span class="br0">&#41;</span> <span style="color: #808080;"># sortie de la fonction</span>
&nbsp;
        <span style="color: #808080;"># polyn&ocirc;me self repr&eacute;sentant au d&eacute;part le reste r</span>
        r = Polynome<span class="br0">&#40;</span>self.coefs<span class="br0">&#41;</span>
&nbsp;
        <span style="color: #808080;"># degr&eacute; du polyn&ocirc;me repr&eacute;sentant le quotient q</span>
        degre = r.degre<span class="br0">&#40;</span><span class="br0">&#41;</span> - other.degre<span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
        <span style="color: #808080;"># initialisation du polyn&ocirc;me q : [0, 0, 1] -&gt; ... + X^2</span>
        q = Polynome<span class="br0">&#40;</span><span class="br0">&#91;</span><span style="color: #cc66cc;">0</span><span class="br0">&#93;</span>*degre + <span class="br0">&#91;</span><span style="color: #cc66cc;">1</span><span class="br0">&#93;</span><span class="br0">&#41;</span>
&nbsp;
        <span style="color: #808080;"># tant que le degr&eacute; mini des termes du polyn&ocirc;me q est sup&eacute;rieur ou &eacute;gal &agrave; 0, et que r n'est pas &eacute;gal &agrave; 0.</span>
        <span style="color: #0000ff;">while</span> <span class="br0">&#40;</span>degre&gt;=<span style="color: #cc66cc;">0</span><span class="br0">&#41;</span> <span style="color: #0000ff;">and</span> <span class="br0">&#40;</span>r.coefs<span class="br0">&#91;</span>-<span style="color: #cc66cc;">1</span><span class="br0">&#93;</span>!=<span style="color: #cc66cc;">0</span><span class="br0">&#41;</span>:
&nbsp;
            <span style="color: #808080;"># coefficient du nouveau terme du polyn&ocirc;me q</span>
            coef = r.coefs<span class="br0">&#91;</span>-<span style="color: #cc66cc;">1</span><span class="br0">&#93;</span> / other.coefs<span class="br0">&#91;</span>-<span style="color: #cc66cc;">1</span><span class="br0">&#93;</span>
&nbsp;
            <span style="color: #808080;"># affectation du coefficient au terme</span>
            q.coefs<span class="br0">&#91;</span>degre<span class="br0">&#93;</span> = coef
&nbsp;
            <span style="color: #808080;"># on multiplie le polyn&ocirc;me other par le polyn&ocirc;me coef*(x^degre)</span>
            p = other * <span class="br0">&#40;</span>coef, degre<span class="br0">&#41;</span>
&nbsp;
            <span style="color: #808080;"># soustraction des polyn&ocirc;mes r et p</span>
            r = r - p
&nbsp;
            <span style="color: #808080;"># degr&eacute; du nouveau terme du polyn&ocirc;me q</span>
            degre = r.degre<span class="br0">&#40;</span><span class="br0">&#41;</span> - other.degre<span class="br0">&#40;</span><span class="br0">&#41;</span> 
&nbsp;
        <span style="color: #808080;"># renvoi le couple (q, r) repr&eacute;sentant le quotient et le reste de la division            </span>
        <span style="color: #0000ff;">return</span> <span class="br0">&#40;</span>q, r<span class="br0">&#41;</span>
&nbsp;
&nbsp;
    <span style="color: #0000ff;">def</span> <span style="color: #0080ff;">__eq__</span><span class="br0">&#40;</span>poly1, other<span class="br0">&#41;</span>: <span style="color: #808080;"># m&eacute;thode permettant de red&eacute;finir l'op&eacute;rateur &laquo; == &raquo; pour 2 polyn&ocirc;mes</span>
&nbsp;
        <span style="color: #0000ff;">return</span> <span class="br0">&#40;</span>poly1.coefs==other.coefs<span class="br0">&#41;</span> <span style="color: #808080;"># renvoie True si les 2 listes de coefficients sont &eacute;gales</span>
&nbsp;
&nbsp;
    <span style="color: #0000ff;">def</span> eval<span class="br0">&#40;</span>self,x<span class="br0">&#41;</span>: <span style="color: #808080;"># m&eacute;thode permettant d'&eacute;valuer le polyn&ocirc;me en fonction de x</span>
        <span style="color: #808080;"># intialisation des variables</span>
        valeur_polynome = self.coefs<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span><span class="br0">&#93;</span> <span style="color: #808080;"># valeur_polynome = a0</span>
        power=<span style="color: #cc66cc;">1</span>    
&nbsp;
        <span style="color: #0000ff;">for</span> coef <span style="color: #0000ff;">in</span> self.coefs<span class="br0">&#91;</span><span style="color: #cc66cc;">1</span>:<span class="br0">&#93;</span>: <span style="color: #808080;"># parcours des coefficients du polyn&ocirc;me &agrave; partir de a1 : a1, a2, ..., an</span>
            power = power*x <span style="color: #808080;"># calcul de la puissance de x pour ai : power = x^i</span>
            valeur_polynome += coef*power <span style="color: #808080;"># valeur_polynome = valeur_polynome + ai*x^i</span>
&nbsp;
        <span style="color: #0000ff;">return</span> valeur_polynome <span style="color: #808080;"># renvoie la valeur du polyn&ocirc;me</span>
&nbsp;
    <span style="color: #0000ff;">def</span> eval_horner<span class="br0">&#40;</span>self,x<span class="br0">&#41;</span>: <span style="color: #808080;"># m&eacute;thode permettant d'&eacute;valuer le polyn&ocirc;me en fonction de x</span>
        <span style="color: #808080;"># intialisation de la variable</span>
        valeur_polynome = self.coefs<span class="br0">&#91;</span>-<span style="color: #cc66cc;">1</span><span class="br0">&#93;</span> <span style="color: #808080;"># valeur_polynome = an</span>
&nbsp;
        <span style="color: #0000ff;">for</span> coef <span style="color: #0000ff;">in</span> reversed<span class="br0">&#40;</span>self.coefs<span class="br0">&#91;</span>:-<span style="color: #cc66cc;">1</span><span class="br0">&#93;</span><span class="br0">&#41;</span>: <span style="color: #808080;"># parcours des coefficients du polyn&ocirc;me &agrave; partir de an-1 : an-1, ..., a1, a0</span>
            valeur_polynome = valeur_polynome*x + coef  <span style="color: #808080;"># valeur_polynome = valeur_polynome*x + ai</span>
&nbsp;
        <span style="color: #0000ff;">return</span> valeur_polynome <span style="color: #808080;"># renvoie la valeur du polyn&ocirc;me</span>
&nbsp;
<span style="color: #0000ff;">def</span> matrice_polynome<span class="br0">&#40;</span>mat<span class="br0">&#41;</span>:
    <span style="color: #808080;"># cr&eacute;ation de la matrice du polyn&ocirc;me caract&eacute;ristique</span>
&nbsp;
    <span style="color: #808080;"># parcours des indices des lignes de la matrice</span>
    <span style="color: #0000ff;">for</span> i <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span>len<span class="br0">&#40;</span>mat<span class="br0">&#41;</span><span class="br0">&#41;</span>:
        <span style="color: #808080;"># parcours des indices des colonnes de la matrice</span>
        <span style="color: #0000ff;">for</span> j <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span>len<span class="br0">&#40;</span>mat<span class="br0">&#41;</span><span class="br0">&#41;</span>:
            <span style="color: #0000ff;">if</span> i==j: <span style="color: #808080;"># si le coefficient est sur la diagonale</span>
                <span style="color: #808080;"># On copie &agrave; cet emplacement le polyn&ocirc;me P(X) = X - mat[i][i]</span>
                mat<span class="br0">&#91;</span>i<span class="br0">&#93;</span><span class="br0">&#91;</span>i<span class="br0">&#93;</span> = Polynome<span class="br0">&#40;</span><span class="br0">&#91;</span>-mat<span class="br0">&#91;</span>i<span class="br0">&#93;</span><span class="br0">&#91;</span>i<span class="br0">&#93;</span>, <span style="color: #cc66cc;">1</span><span class="br0">&#93;</span><span class="br0">&#41;</span>
            <span style="color: #0000ff;">else</span>: <span style="color: #808080;"># sinon le polyn&ocirc;me P(X) = - mat[i][i]</span>
                mat<span class="br0">&#91;</span>i<span class="br0">&#93;</span><span class="br0">&#91;</span>j<span class="br0">&#93;</span> = Polynome<span class="br0">&#40;</span><span class="br0">&#91;</span>-mat<span class="br0">&#91;</span>i<span class="br0">&#93;</span><span class="br0">&#91;</span>j<span class="br0">&#93;</span><span class="br0">&#93;</span><span class="br0">&#41;</span>
&nbsp;
    <span style="color: #808080;"># renvoi la matrice du polyn&ocirc;me caract&eacute;ristique</span>
    <span style="color: #0000ff;">return</span> mat
&nbsp;
&nbsp;
<span style="color: #0000ff;">def</span> determinant<span class="br0">&#40;</span>mat<span class="br0">&#41;</span>:
    <span style="color: #808080;"># d&eacute;veloppement du d&eacute;terminant de la matrice mat par rapport la ligne i</span>
&nbsp;
    <span style="color: #808080;"># si la matrice est d'ordre 1</span>
    <span style="color: #0000ff;">if</span> len<span class="br0">&#40;</span>mat<span class="br0">&#41;</span>==<span style="color: #cc66cc;">1</span>:
        <span style="color: #808080;"># on renvoie l'unique &eacute;l&eacute;ment de la matrice</span>
        <span style="color: #0000ff;">return</span> mat<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span style="color: #cc66cc;">0</span><span class="br0">&#93;</span>
&nbsp;
    <span style="color: #0000ff;">else</span>: <span style="color: #808080;"># sinon</span>
        <span style="color: #808080;"># cr&eacute;ation du polyn&ocirc;me nul</span>
        d = Polynome<span class="br0">&#40;</span><span class="br0">&#91;</span><span style="color: #cc66cc;">0</span><span class="br0">&#93;</span><span class="br0">&#41;</span>
&nbsp;
        <span style="color: #808080;"># parcours des indices des colonnes de la matrice</span>
        <span style="color: #0000ff;">for</span> j, element <span style="color: #0000ff;">in</span> enumerate<span class="br0">&#40;</span>mat<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span><span class="br0">&#93;</span><span class="br0">&#41;</span>:
            <span style="color: #808080;"># suppression de la 1re ligne de la matrice : mat[1:]</span>
            <span style="color: #808080;"># + suppression de la colonne j dans la matrice mat</span>
            comat= <span class="br0">&#91;</span>ligne<span class="br0">&#91;</span>:j<span class="br0">&#93;</span> + ligne<span class="br0">&#91;</span>j+<span style="color: #cc66cc;">1</span>:<span class="br0">&#93;</span> <span style="color: #0000ff;">for</span> ligne <span style="color: #0000ff;">in</span> mat<span class="br0">&#91;</span><span style="color: #cc66cc;">1</span>:<span class="br0">&#93;</span><span class="br0">&#93;</span>
&nbsp;
            <span style="color: #808080;"># det(M) = (-1)**(j)*a(1,j)*(com M)(0,j)</span>
            d += Polynome<span class="br0">&#40;</span><span class="br0">&#91;</span>pow<span class="br0">&#40;</span>-<span style="color: #cc66cc;">1</span>,j<span class="br0">&#41;</span><span class="br0">&#93;</span><span class="br0">&#41;</span>*element*determinant<span class="br0">&#40;</span>comat<span class="br0">&#41;</span>
&nbsp;
        <span style="color: #808080;"># on renvoie le polyn&ocirc;me caract&eacute;ristique</span>
        <span style="color: #0000ff;">return</span> d
&nbsp;
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;I. Polyn&ocirc;me carcat&eacute;ristique d'une matrice&quot;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># matrice exemple</span>
m = <span class="br0">&#91;</span><span class="br0">&#91;</span><span style="color: #cc66cc;">2</span>, <span style="color: #cc66cc;">1</span><span class="br0">&#93;</span>, <span class="br0">&#91;</span>-<span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">0</span><span class="br0">&#93;</span><span class="br0">&#93;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;m = &quot;</span> + str<span class="br0">&#40;</span>m<span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># cr&eacute;ation de la matrice du polyn&ocirc;me caract&eacute;ristique</span>
mp = matrice_polynome<span class="br0">&#40;</span>m<span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># d&eacute;termination du polyn&ocirc;me caract&eacute;ristique associ&eacute; &agrave; la matrice m</span>
p = determinant<span class="br0">&#40;</span>mp<span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche le polyn&ocirc;me caract&eacute;ristique de m</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Pm(X) = &quot;</span> + str<span class="br0">&#40;</span>p<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;II. Polyn&ocirc;me caract&eacute;ristique associ&eacute; &agrave; une suite r&eacute;currente lin&eacute;aire&quot;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># matrice compagnon associ&eacute;e &agrave; la suite de Fibonacci</span>
m = <span class="br0">&#91;</span><span class="br0">&#91;</span><span style="color: #cc66cc;">0</span>, <span style="color: #cc66cc;">1</span><span class="br0">&#93;</span>, <span class="br0">&#91;</span><span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">1</span><span class="br0">&#93;</span><span class="br0">&#93;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;m = &quot;</span> + str<span class="br0">&#40;</span>m<span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># cr&eacute;ation de la matrice du polyn&ocirc;me caract&eacute;ristique</span>
mp = matrice_polynome<span class="br0">&#40;</span>m<span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># d&eacute;termination du polyn&ocirc;me caract&eacute;ristique associ&eacute; &agrave; la matrice m</span>
p = determinant<span class="br0">&#40;</span>mp<span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche le polyn&ocirc;me caract&eacute;ristique</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Pm(X) = &quot;</span> + str<span class="br0">&#40;</span>p<span class="br0">&#41;</span><span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
<br />
<b>IV. Conclusion</b><br />
<br />
Après avoir montré comment obtenir le polynôme caractéristique associé à une matrice carrée, nous avons pu proposer une implémentation en Python.<br />
<br />
Enfin, nous avons mieux compris l'intérêt de ces polynômes caractéristiques à l'aide d'un exemple simple permettant de faire le lien entre la suite de Fibonacci et le nombre d'or.<br />
<br />
<br />
<b>Sources :</b><br />
<br />
<a href="https://fr.wikipedia.org/wiki/Polyn%C3%B4me_caract%C3%A9ristique" target="_blank">https://fr.wikipedia.org/wiki/Polyn%...%C3%A9ristique</a><br />
<a href="https://fr.wikipedia.org/wiki/D%C3%A9terminant_(math%C3%A9matiques)" target="_blank">https://fr.wikipedia.org/wiki/D%C3%A...C3%A9matiques)</a><br />
<a href="https://fr.wikipedia.org/wiki/Matrice_(math%C3%A9matiques)" target="_blank">https://fr.wikipedia.org/wiki/Matric...C3%A9matiques)</a><br />
<a href="https://fr.wikipedia.org/wiki/Matrice_identit%C3%A9" target="_blank">https://fr.wikipedia.org/wiki/Matrice_identit%C3%A9</a><br />
<a href="https://fr.wikipedia.org/wiki/Comatrice" target="_blank">https://fr.wikipedia.org/wiki/Comatrice</a><br />
<a href="https://en.wikipedia.org/wiki/Laplace_expansion" target="_blank">https://en.wikipedia.org/wiki/Laplace_expansion</a><br />
<a href="https://fr.wikipedia.org/wiki/Suite_r%C3%A9currente_lin%C3%A9aire" target="_blank">https://fr.wikipedia.org/wiki/Suite_..._lin%C3%A9aire</a><br />
</font></blockquote>

]]></content:encoded>
			<dc:creator>User</dc:creator>
			<guid isPermaLink="true">https://www.developpez.net/forums/blogs/44027-user/b10555/mathematiques-python-matrice-carree-polynome-caracteristique/</guid>
		</item>
		<item>
			<title>Mathématiques et Python : PGCD de nombres entiers et de polynômes</title>
			<link>https://www.developpez.net/forums/blogs/44027-user/b10548/mathematiques-python-pgcd-nombres-entiers-polynomes/</link>
			<pubDate>Sun, 26 Nov 2023 18:21:46 GMT</pubDate>
			<description>*I. Introduction* 
 
On...</description>
			<content:encoded><![CDATA[<blockquote class="blogcontent restore"><font size="3"><br />
<b>I. Introduction</b><br />
<br />
On souhaite créer une fonction permettant de calculer le <a href="https://fr.wikipedia.org/wiki/Plus_grand_commun_diviseur_de_nombres_entiers" target="_blank">plus grand commun diviseur</a> ou <b>PGCD</b> entre deux nombres entiers à l'aide de l'<a href="https://fr.wikipedia.org/wiki/Algorithme_d%27Euclide" target="_blank">algorithme d'Euclide</a>.<br />
<br />
Ensuite, toujours en se basant sur cet algorithme, on va créer une autre fonction qui pourra déterminer le <a href="https://fr.wikipedia.org/wiki/Plus_grand_commun_diviseur#PGCD_de_polyn%C3%B4mes_%C3%A0_coefficients_entiers_ou_r%C3%A9els" target="_blank">PGCD de deux polynômes</a>.<br />
<br />
<br />
<b>II. Définitions mathématiques</b><br />
<br />
<br />
<b>II-A. PGCD de nombres entiers</b><br />
<br />
D'après Wikipedia, en mathématiques, le <b>PGCD</b> de nombres entiers différents de zéro est, parmi les diviseurs communs à ces entiers, le plus grand d'entre eux. <br />
<br />
Par exemple, les diviseurs positifs de <b>30</b> sont, dans l'ordre : <b>1, 2, 3, 5, 6, 10, 15 et 30</b>. Ceux de <b>18</b> sont <b>1, 2, 3, 6, 9 et 18</b>. <br />
<br />
Les diviseurs communs de <b>30</b> et <b>18</b> étant <b>1, 2, 3 et 6</b>, leur <b>PGCD</b> est <b>6</b>. Ce qui se note : <b>PGCD(30, 18) = 6</b>. <br />
<br />
Les diviseurs communs à plusieurs entiers sont les diviseurs de leur <b>PGCD</b>. Connaître le <b>PGCD</b> de deux nombres entiers non nuls <b>a</b> et <b>b</b> permet de simplifier la fraction <b>a/b</b>. <br />
<br />
Il est possible de le déterminer par divers raisonnements, dont l'<a href="https://fr.wikipedia.org/wiki/Algorithme_d%27Euclide" target="_blank">algorithme d'Euclide</a>. <br />
<br />
<br />
<b>II-B. PGCD de polynômes</b><br />
<br />
On va simplement transposer pour les polynômes l'algorithme d'Euclide servant à trouver le <b>PGCD</b> de deux nombres entiers. <br />
<br />
Toutefois, comme il y a une infinité de <b>PGCD</b> possibles avec les polynômes, pour avoir un <b>PGCD</b> unique, on choisira par convention le <a href="https://fr.wikipedia.org/wiki/Polyn%C3%B4me_unitaire" target="_blank">polynôme unitaire</a>, polynôme non nul et dont le coefficient dominant vaut 1.<br />
<br />
Connaître le <a href="https://fr.wikipedia.org/wiki/Plus_grand_commun_diviseur#PGCD_de_polyn%C3%B4mes_%C3%A0_coefficients_entiers_ou_r%C3%A9els" target="_blank">PGCD de deux polynômes</a> non nuls <b>A</b> et <b>B</b> permet de simplifier la fraction <b>A/B</b>.<br />
<br />
<br />
<b>III. Algorithme d'Euclide</b><br />
<br />
<br />
<b>III-A. PGCD de deux nombres entiers</b><br />
<br />
Ainsi, selon Wikipedia, l'<a href="https://fr.wikipedia.org/wiki/Algorithme_d%27Euclide" target="_blank">algorithme d'Euclide</a> sur deux nombres entiers positifs <b>a</b> et <b>b</b> avec <b>a &gt; b &#10878; 0</b> procède comme suit :<br />
<br />
<ul><li style="">si <b>b = 0</b>, l'algorithme termine et rend la valeur <b>a</b> ;</li><li style="">sinon, l'algorithme calcule le reste <b>r</b> de la division euclidienne de <b>a</b> par <b>b</b>, puis recommence avec <b>a := b</b> et <b>b := r</b>.</li></ul><br />
<br />
Formellement l'algorithme d'Euclide construit une suite finie d'entiers <b>(r<sub>n</sub>)</b> par récurrence double :<br />
<br />
<ul><li style=""><b>r<sub>0</sub> = a, r<sub>1</sub> = b ;</b></li><li style="">pour <b>n &#10878; 1, r<sub>n+1</sub></b> est le reste de la division euclidienne de <b>r<sub>n-1</sub></b> par <b>r<sub>n</sub></b>, en particulier <b>r<sub>n+1</sub> &lt; r<sub>n</sub></b>.</li></ul><br />
<br />
La suite <b>(r<sub>n</sub>)</b> est une suite strictement décroissante d'entiers positifs à partir du rang <b>1</b> : elle est donc finie et s'arrête au premier <b>n</b> tel que <b>r<sub>n</sub> = 0</b>.<br />
<br />
Le tableau suivant montre le calcul du <b>PGCD</b> de <b>21</b> et <b>15</b>. On réalise la division euclidienne de <b>a = 21</b> et <b>b = 15</b> : le quotient est <b>1</b> et le reste <b>6</b>. <br />
L'algorithme continue avec <b>a := b</b> et <b>b :=</b> le précédent reste, jusqu'à trouver un reste nul. L'algorithme s'arrête alors et retourne le dernier reste non nul trouvé, ici <b>r<sub>3</sub> = 3</b> qui est bien le PGCD de <b>21</b> et <b>15</b> : <br />
<br />
<div style="text-align: center;"><img src="https://www.developpez.net/forums/attachments/p646757d1700239633/parkings/restreint-parking-admin/version-2-nouveau-gabarit-dynamique-vos-articles/tableau_pgcd.png/" border="0" alt="Nom : tableau_pgcd.png
Affichages : 58441
Taille : 7,6 Ko"  style="float: CONFIG" /></div><br />
<br />
<b>III-B. PGCD de polynômes</b><br />
<br />
On procédera de la même façon pour le calcul du <a href="https://fr.wikipedia.org/wiki/Plus_grand_commun_diviseur#PGCD_de_polyn%C3%B4mes_%C3%A0_coefficients_entiers_ou_r%C3%A9els" target="_blank">PGCD des polynômes</a> <b>A</b> et <b>B</b> :<br />
<br />
<ul><li style="">si <b>B = 0</b> alors <b>PGCD(A, B) = A</b> ;</li><li style="">sinon, l'algorithme calcule le reste <b>R</b> de la division euclidienne des polynômes <b>A</b> et <b>B</b>, puis recommence avec <b>A := B</b> et <b>B := R</b>.</li></ul><br />
<br />
Pour avoir plus d'information sur la division d'un polynôme, je vous invite à consulter la page <a href="https://fr.wikipedia.org/wiki/Division_d%27un_polyn%C3%B4me" target="_blank">Division d'un polynôme</a>.<br />
 <br />
<br />
<b>IV. Implémentation en Python</b><br />
<br />
On va chercher comme d'habitude à écrire du code le plus lisible possible, sans chercher forcément à l'optimiser.<br />
<br />
<br />
<b>IV-A. PGCD de nombres entiers</b><br />
<br />
A partir de l'algorithme décrit précédemment on obtient facilement la fonction récursive :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:180px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">def</span> PGCD<span class="br0">&#40;</span>a, b<span class="br0">&#41;</span>:
&nbsp;
    <span style="color: #808080;"># si b=0</span>
    <span style="color: #0000ff;">if</span> <span class="br0">&#40;</span>b==<span style="color: #cc66cc;">0</span><span class="br0">&#41;</span>:
        <span style="color: #808080;"># renvoi de a</span>
        <span style="color: #0000ff;">return</span> a
    <span style="color: #0000ff;">else</span>: <span style="color: #808080;"># sinon</span>
        <span style="color: #808080;"># calcul du reste r de la division de a par b</span>
        r = a % b
&nbsp;
        <span style="color: #808080;"># appel de la fonction PGCD pour a=b et b=r</span>
        <span style="color: #0000ff;">return</span> PGCD<span class="br0">&#40;</span>b, r<span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
On laisse le choix à chacun de traduire ensuite ce code en <a href="https://fr.wikibooks.org/wiki/Algorithmique_imp%C3%A9rative/It%C3%A9ration" target="_blank">fonction itérative</a>.<br />
<br />
<br />
Testons maintenant cette fonction :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:96px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="26"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #808080;"># calcul du PGCD des entiers 21 et 15</span>
gcd = PGCD<span class="br0">&#40;</span><span style="color: #cc66cc;">21</span>, <span style="color: #cc66cc;">15</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche le r&eacute;sultat</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;PGCD(21, 15) = &quot;</span> + str<span class="br0">&#40;</span>gcd<span class="br0">&#41;</span><span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
Le code affiche :<br />
<br />
<span class="highlight">PGCD(21, 15) = 3</span><br />
<br />
<br />
<b>IV-B. PGCD de polynômes</b><br />
<br />
On utilise à nouveau notre <a href="https://algo.developpez.com/actu/339249/Mathematiques-et-Python-moins-apprendre-a-creer-une-classe-Polynome-en-Python-avec-la-surcharge-des-operateurs-un-billet-blog-de-Denis-Hulo" target="_blank">classe Polynome</a> dans laquelle on va ajouter une méthode pour réaliser une division euclidienne entre deux polynômes :<br />
<br />
<div style="text-align: center;"><img src="https://www.developpez.net/forums/attachments/p646758d1700239704/parkings/restreint-parking-admin/version-2-nouveau-gabarit-dynamique-vos-articles/classe_polynome.png/" border="0" alt="Nom : classe_polynome.png
Affichages : 20483
Taille : 10,9 Ko"  style="float: CONFIG" /></div><br />
On donne maintenant le code complet de la méthode permettant de réaliser cette division en surchargeant l'opérateur « / » :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">class</span> Polynome: 
    ...
    <span style="color: #0000ff;">def</span> __truediv__<span class="br0">&#40;</span>self, other<span class="br0">&#41;</span>: <span style="color: #808080;"># m&eacute;thode permettant de red&eacute;finir l'op&eacute;rateur &laquo; / &raquo; pour 2 polyn&ocirc;mes</span>
&nbsp;
        <span style="color: #808080;"># si le degr&eacute; de self est inf&eacute;rieur au degr&eacute; de other</span>
        <span style="color: #0000ff;">if</span> self.degre<span class="br0">&#40;</span><span class="br0">&#41;</span>&lt;other.degre<span class="br0">&#40;</span><span class="br0">&#41;</span>:
            <span style="color: #808080;"># on renvoie (0, self) : q=0, r=self</span>
            <span style="color: #0000ff;">return</span> <span class="br0">&#40;</span>Polynome<span class="br0">&#40;</span><span class="br0">&#91;</span><span style="color: #cc66cc;">0</span><span class="br0">&#93;</span><span class="br0">&#41;</span>, self<span class="br0">&#41;</span> <span style="color: #808080;"># sortie de la fonction</span>
&nbsp;
        <span style="color: #808080;"># polyn&ocirc;me self repr&eacute;sentant au d&eacute;part le reste r</span>
        r = Polynome<span class="br0">&#40;</span>self.coefs<span class="br0">&#41;</span>
&nbsp;
        <span style="color: #808080;"># degr&eacute; du polyn&ocirc;me repr&eacute;sentant le quotient q</span>
        degre = r.degre<span class="br0">&#40;</span><span class="br0">&#41;</span> - other.degre<span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
        <span style="color: #808080;"># initialisation du polyn&ocirc;me q : [0, 0, 1] -&gt; ... + X^2</span>
        q = Polynome<span class="br0">&#40;</span><span class="br0">&#91;</span><span style="color: #cc66cc;">0</span><span class="br0">&#93;</span>*degre + <span class="br0">&#91;</span><span style="color: #cc66cc;">1</span><span class="br0">&#93;</span><span class="br0">&#41;</span>
&nbsp;
        <span style="color: #808080;"># tant que le degr&eacute; mini des termes du polyn&ocirc;me q est sup&eacute;rieur ou &eacute;gal &agrave; 0, et que r n'est pas &eacute;gal &agrave; 0.</span>
        <span style="color: #0000ff;">while</span> <span class="br0">&#40;</span>degre&gt;=<span style="color: #cc66cc;">0</span><span class="br0">&#41;</span> <span style="color: #0000ff;">and</span> <span class="br0">&#40;</span>r.coefs<span class="br0">&#91;</span>-<span style="color: #cc66cc;">1</span><span class="br0">&#93;</span>!=<span style="color: #cc66cc;">0</span><span class="br0">&#41;</span>:
&nbsp;
            <span style="color: #808080;"># coefficient du nouveau terme du polyn&ocirc;me q</span>
            coef = r.coefs<span class="br0">&#91;</span>-<span style="color: #cc66cc;">1</span><span class="br0">&#93;</span> / other.coefs<span class="br0">&#91;</span>-<span style="color: #cc66cc;">1</span><span class="br0">&#93;</span>
&nbsp;
            <span style="color: #808080;"># affectation du coefficient au terme</span>
            q.coefs<span class="br0">&#91;</span>degre<span class="br0">&#93;</span> = coef
&nbsp;
            <span style="color: #808080;"># on multiplie le polyn&ocirc;me other par le polyn&ocirc;me coef*(x^degre)</span>
            p = other * <span class="br0">&#40;</span>coef, degre<span class="br0">&#41;</span>
&nbsp;
            <span style="color: #808080;"># soustraction des polyn&ocirc;mes r et p</span>
            r = r - p
&nbsp;
            <span style="color: #808080;"># degr&eacute; du nouveau terme du polyn&ocirc;me q</span>
            degre = r.degre<span class="br0">&#40;</span><span class="br0">&#41;</span> - other.degre<span class="br0">&#40;</span><span class="br0">&#41;</span> 
&nbsp;
        <span style="color: #808080;"># renvoi le couple (q, r) repr&eacute;sentant le quotient et le reste de la division            </span>
        <span style="color: #0000ff;">return</span> <span class="br0">&#40;</span>q, r<span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
On doit donc d'abord comparer les degrés des polynômes <b>p1 = self</b> et <b>p2 = other</b> au début du code.<br />
<br />
Si le degré de <b>p1</b> est inférieur au degré de <b>p2</b>, alors <b>q = 0</b> et <b>r = p1</b>,<br />
sinon, on procède à la division des deux polynômes pour obtenir <b>q</b> et <b>r</b>.<br />
<br />
<br />
Testons cette méthode :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code  :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:180px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br /></div></td><td valign="top"><pre style="margin: 0"># création du polynôme p1 = (1 + X)(2 + X) = 2 + 3X + X^2
p1 = Polynome([1, 1])*Polynome([2, 1])

# création du polynôme p2 = 1 + 2X + X^2 = (1 + X)^2
p2 = Polynome([1, 2, 1])

# division euclidienne : p1 = p2*q + r
q, r = p1 / p2

# affiche le quotient q et le reste r de la division
print(&quot;q = &quot; + str(q))
print(&quot;r = &quot; + str(r))</pre></td></tr></table></pre>
</div>Le code affiche le quotient <b>q</b> et le reste <b>r</b> résultat de la division :<br />
<br />
<span class="highlight">q = 1.0<br />
r = 1.0 + X</span><br />
<br />
On peut maintenant créer notre fonction permettant de déterminer le <b>PGCD</b> entre deux polynômes :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">def</span> PGCD_POLY<span class="br0">&#40;</span>A, B<span class="br0">&#41;</span>:
&nbsp;
    <span style="color: #808080;"># si B=0</span>
    <span style="color: #0000ff;">if</span> <span class="br0">&#40;</span>B==Polynome<span class="br0">&#40;</span><span class="br0">&#91;</span><span style="color: #cc66cc;">0</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>:
        <span style="color: #808080;"># par convention on choisit de renvoyer le polyn&ocirc;me unitaire, polyn&ocirc;me non nul et dont le coefficient dominant vaut 1 :</span>
        coef = <span style="color: #cc66cc;">1.0</span>/A.coefs<span class="br0">&#91;</span>-<span style="color: #cc66cc;">1</span><span class="br0">&#93;</span>
	<span style="color: #808080;"># multiplication de A par coef</span>
        A = A*<span class="br0">&#40;</span>coef,<span style="color: #cc66cc;">0</span><span class="br0">&#41;</span>
&nbsp;
        <span style="color: #808080;"># renvoi de A    </span>
        <span style="color: #0000ff;">return</span> A
    <span style="color: #0000ff;">else</span>:
        <span style="color: #808080;"># d&eacute;termination du quotient Q et du reste R de la division de A par B</span>
        Q, R = A / B
&nbsp;
        <span style="color: #808080;"># appel de la fonction PGCD pour A=B et B=R</span>
        <span style="color: #0000ff;">return</span> PGCD_POLY<span class="br0">&#40;</span>B, R<span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
Testons enfin notre fonction :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code  :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:168px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br /></div></td><td valign="top"><pre style="margin: 0"># création du polynôme p1 = (1 + X)(2 + X) = 2 + 3X + X^2
p1 = Polynome([1, 1])*Polynome([2, 1])

# création du polynôme p2 = 1 + 2X + X^2 = (1 + X)^2
p2 = Polynome([1, 2, 1])

# calcul du PGCD des polynômes p1 et p2
gcd = PGCD_POLY(p1, p2)

# affiche le résultat
print(&quot;PGCD(p1, p2) = &quot; + str(gcd))</pre></td></tr></table></pre>
</div>Le code affiche :<br />
<br />
<span class="highlight">PGCD(p1, p2) = 1.0 + X</span><br />
<br />
<br />
<b>IV-C. Application : simplification de fraction</b><br />
<br />
Supposons que l'on souhaite connaître la limite :<br />
<br />
<img src="https://www.developpez.net/forums/attachments/p646892d1700577668/parkings/restreint-parking-admin/version-2-nouveau-gabarit-dynamique-vos-articles/limite1.png/" border="0" alt="Nom : limite1.png
Affichages : 20173
Taille : 2,9 Ko"  style="float: CONFIG" /><br />
<br />
On voit facilement qu'on aboutit à une forme indéterminée <b>0/0</b>.<br />
<br />
Pour lever cette indétermination on identifie d'abord le <b>PGCD</b> entre le numérateur et le dénominateur <b>(x - 2)</b>, pour ensuite simplifier la fraction :<br />
<br />
<img src="https://www.developpez.net/forums/attachments/p646893d1700577680/parkings/restreint-parking-admin/version-2-nouveau-gabarit-dynamique-vos-articles/limite2.png/" border="0" alt="Nom : limite2.png
Affichages : 20164
Taille : 5,1 Ko"  style="float: CONFIG" /><br />
<br />
On obtient ainsi la limite égale à <b>13/7</b>.<br />
<br />
Mise en œuvre en Python :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #808080;"># cr&eacute;ation du polyn&ocirc;me p1 = -10 + X + X^3</span>
p1 = Polynome<span class="br0">&#40;</span><span class="br0">&#91;</span>-<span style="color: #cc66cc;">10</span>, <span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">0</span>, <span style="color: #cc66cc;">1</span><span class="br0">&#93;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;p1 = &quot;</span> + str<span class="br0">&#40;</span>p1<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># cr&eacute;ation du polyn&ocirc;me p2 = -6 - X + 2X^2</span>
p2 = Polynome<span class="br0">&#40;</span><span class="br0">&#91;</span>-<span style="color: #cc66cc;">6</span>, -<span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">2</span><span class="br0">&#93;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;p2 = &quot;</span> + str<span class="br0">&#40;</span>p2<span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Limite de p1/p2 quand X -&gt; 2 = 0/0<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># calcul du PGCD des polyn&ocirc;mes p1 et p2</span>
gcd = PGCD_POLY<span class="br0">&#40;</span>p1, p2<span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche le r&eacute;sultat</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;PGCD(p1, p2) = &quot;</span> + str<span class="br0">&#40;</span>gcd<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># simplification de p1</span>
p1, r1 = p1 / gcd
&nbsp;
<span style="color: #808080;"># simplification de p2</span>
p2, r2 = p2 / gcd
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;p1/p2 = ({0})/({1})&quot;</span>.format<span class="br0">&#40;</span>p1, p2<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Limite de p1/p2 quand X -&gt; 2 = {0}/{1}<span style="color: #800000;">\n</span>&quot;</span>.format<span class="br0">&#40;</span>p1.eval<span class="br0">&#40;</span><span style="color: #cc66cc;">2</span><span class="br0">&#41;</span>,p2.eval<span class="br0">&#40;</span><span style="color: #cc66cc;">2</span><span class="br0">&#41;</span><span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
Le code affiche :<br />
<br />
<span class="highlight">p1 = -10 + X + X^3<br />
p2 = -6 - X + 2.X^2<br />
<br />
Limite de p1/p2 quand X -&gt; 2 = 0/0<br />
<br />
PGCD(p1, p2) = -2.0 + X<br />
<br />
p1/p2 = (5.0 + 2.0.X + X^2)/(3.0 + 2.0.X^1)<br />
<br />
Limite de p1/p2 quand X -&gt; 2 = 13.0/7.0</span><br />
<br />
On voit qu'on obtient le même résultat, les termes des polynômes sont simplement affichés dans l'ordre inverse.<br />
<br />
<br />
<b>IV-D. Module complet</b><br />
<br />
On donne pour finir le code complet permettant d'effectuer les différents tests :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="40"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br />50<br />51<br />52<br />53<br />54<br />55<br />56<br />57<br />58<br />59<br />60<br />61<br />62<br />63<br />64<br />65<br />66<br />67<br />68<br />69<br />70<br />71<br />72<br />73<br />74<br />75<br />76<br />77<br />78<br />79<br />80<br />81<br />82<br />83<br />84<br />85<br />86<br />87<br />88<br />89<br />90<br />91<br />92<br />93<br />94<br />95<br />96<br />97<br />98<br />99<br />100<br />101<br />102<br />103<br />104<br />105<br />106<br />107<br />108<br />109<br />110<br />111<br />112<br />113<br />114<br />115<br />116<br />117<br />118<br />119<br />120<br />121<br />122<br />123<br />124<br />125<br />126<br />127<br />128<br />129<br />130<br />131<br />132<br />133<br />134<br />135<br />136<br />137<br />138<br />139<br />140<br />141<br />142<br />143<br />144<br />145<br />146<br />147<br />148<br />149<br />150<br />151<br />152<br />153<br />154<br />155<br />156<br />157<br />158<br />159<br />160<br />161<br />162<br />163<br />164<br />165<br />166<br />167<br />168<br />169<br />170<br />171<br />172<br />173<br />174<br />175<br />176<br />177<br />178<br />179<br />180<br />181<br />182<br />183<br />184<br />185<br />186<br />187<br />188<br />189<br />190<br />191<br />192<br />193<br />194<br />195<br />196<br />197<br />198<br />199<br />200<br />201<br />202<br />203<br />204<br />205<br />206<br />207<br />208<br />209<br />210<br />211<br />212<br />213<br />214<br />215<br />216<br />217<br />218<br />219<br />220<br />221<br />222<br />223<br />224<br />225<br />226<br />227<br />228<br />229<br />230<br />231<br />232<br />233<br />234<br />235<br />236<br />237<br />238<br />239<br />240<br />241<br />242<br />243<br />244<br />245<br />246<br />247<br />248<br />249<br />250<br />251<br />252<br />253<br />254<br />255<br />256<br />257<br />258<br />259<br />260<br />261<br />262<br />263<br />264<br />265<br />266<br />267<br />268<br />269<br />270<br />271<br />272<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">class</span> Polynome:
&nbsp;
    <span style="color: #0000ff;">def</span> <span style="color: #0080ff;">__init__</span><span class="br0">&#40;</span>self, liste_coefs=<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span><span class="br0">&#93;</span><span class="br0">&#41;</span>: <span style="color: #808080;"># m&eacute;thode constructeur de la classe</span>
&nbsp;
	<span style="color: #808080;"># on d&eacute;finit la liste des coefficients du polyn&ocirc;me [a0, a1, ..., an]</span>
        self.coefs = liste_coefs
&nbsp;
	<span style="color: #808080;"># suppression si n&eacute;cessaire des z&eacute;ros en queue de liste de coefficients. Exemple : [2, 3, 1, 0, 0] -&gt; [2, 3, 1]</span>
        self.reduire<span class="br0">&#40;</span><span class="br0">&#41;</span> 
&nbsp;
    <span style="color: #0000ff;">def</span> __str__<span class="br0">&#40;</span>self<span class="br0">&#41;</span>: <span style="color: #808080;"># permet d'afficher le polyn&ocirc;me sous la forme 1 + 2x + 3x^2</span>
        s=<span style="color: #FF0000;">&quot;&quot;</span> <span style="color: #808080;"># initialisation de la cha&icirc;ne de caract&egrave;res</span>
        <span style="color: #808080;"># on v&eacute;rifie d&#146;abord si le degr&eacute; du polyn&ocirc;me est nul</span>
        <span style="color: #0000ff;">if</span> <span class="br0">&#40;</span>len<span class="br0">&#40;</span>self.coefs<span class="br0">&#41;</span>-<span style="color: #cc66cc;">1</span>==<span style="color: #cc66cc;">0</span><span class="br0">&#41;</span>:
            <span style="color: #0000ff;">return</span> str<span class="br0">&#40;</span>self.coefs<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span><span class="br0">&#93;</span><span class="br0">&#41;</span>
        <span style="color: #0000ff;">else</span>: <span style="color: #808080;"># sinon</span>
            <span style="color: #0000ff;">if</span> self.coefs<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span><span class="br0">&#93;</span>!=<span style="color: #cc66cc;">0</span>:
                s=str<span class="br0">&#40;</span>self.coefs<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span><span class="br0">&#93;</span><span class="br0">&#41;</span> + <span style="color: #FF0000;">&quot; + &quot;</span>
            <span style="color: #0000ff;">for</span> i <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span><span style="color: #cc66cc;">1</span>, len<span class="br0">&#40;</span>self.coefs<span class="br0">&#41;</span><span class="br0">&#41;</span>: <span style="color: #808080;"># parcours des indices des coefficients du polyn&ocirc;me : [a1, a2, ..., an]</span>
                <span style="color: #0000ff;">if</span> self.coefs<span class="br0">&#91;</span>i<span class="br0">&#93;</span>!=<span style="color: #cc66cc;">0</span>: <span style="color: #808080;"># si le coefficient de degr&eacute; i n'est pas nul</span>
                    <span style="color: #0000ff;">if</span> self.coefs<span class="br0">&#91;</span>i<span class="br0">&#93;</span>!=<span style="color: #cc66cc;">1</span>: <span style="color: #808080;"># si le coefficient de degr&eacute; i est diff&eacute;rent de 1</span>
                        s+=<span style="color: #FF0000;">&quot;{}.X^{} + &quot;</span>.format<span class="br0">&#40;</span>self.coefs<span class="br0">&#91;</span>i<span class="br0">&#93;</span>,i<span class="br0">&#41;</span>
                    <span style="color: #0000ff;">else</span>: s+=<span style="color: #FF0000;">&quot;X^{} + &quot;</span>.format<span class="br0">&#40;</span>i<span class="br0">&#41;</span>  
&nbsp;
            <span style="color: #808080;"># &eacute;limination des caract&egrave;res en trop           </span>
            s = s<span class="br0">&#91;</span>:-<span style="color: #cc66cc;">3</span><span class="br0">&#93;</span>.replace<span class="br0">&#40;</span><span style="color: #FF0000;">&quot;+ -&quot;</span>, <span style="color: #FF0000;">&quot;- &quot;</span><span class="br0">&#41;</span>.replace<span class="br0">&#40;</span><span style="color: #FF0000;">&quot;X^1 &quot;</span>,<span style="color: #FF0000;">&quot;X &quot;</span><span class="br0">&#41;</span>.replace<span class="br0">&#40;</span><span style="color: #FF0000;">&quot; 1.X&quot;</span>,<span style="color: #FF0000;">&quot; X&quot;</span><span class="br0">&#41;</span>
            <span style="color: #0000ff;">if</span> s<span class="br0">&#91;</span>-<span style="color: #cc66cc;">2</span>:<span class="br0">&#93;</span>==<span style="color: #FF0000;">&quot;^1&quot;</span>: s = s<span class="br0">&#91;</span>:-<span style="color: #cc66cc;">2</span><span class="br0">&#93;</span>
            <span style="color: #0000ff;">if</span> s<span class="br0">&#91;</span>:<span style="color: #cc66cc;">3</span><span class="br0">&#93;</span>==<span style="color: #FF0000;">&quot;1.X&quot;</span>: s = s<span class="br0">&#91;</span><span style="color: #cc66cc;">3</span>:<span class="br0">&#93;</span>
&nbsp;
            <span style="color: #0000ff;">return</span> s <span style="color: #808080;"># on retourne l'expression du polyn&ocirc;me</span>
&nbsp;
&nbsp;
    <span style="color: #0000ff;">def</span> degre<span class="br0">&#40;</span>self<span class="br0">&#41;</span>: <span style="color: #808080;"># retourne le degr&eacute; du polyn&ocirc;me</span>
        <span style="color: #0000ff;">return</span> <span class="br0">&#40;</span>len<span class="br0">&#40;</span>self.coefs<span class="br0">&#41;</span>-<span style="color: #cc66cc;">1</span><span class="br0">&#41;</span>
&nbsp;
&nbsp;
    <span style="color: #0000ff;">def</span> <span style="color: #0080ff;">__add__</span><span class="br0">&#40;</span>self, other<span class="br0">&#41;</span>: <span style="color: #808080;"># m&eacute;thode permettant de red&eacute;finir l'op&eacute;rateur &laquo; + &raquo; pour 2 polyn&ocirc;mes : (1 + 2x + x^2) + (1 + x) = 2 + 3x + x^2</span>
        <span style="color: #808080;"># p1 = self, p2 = other     </span>
        <span style="color: #0000ff;">if</span> len<span class="br0">&#40;</span>other.coefs<span class="br0">&#41;</span> &gt;len<span class="br0">&#40;</span>self.coefs<span class="br0">&#41;</span>: <span style="color: #808080;"># si degr&eacute; de p2 &gt; degr&eacute; de p1 </span>
            liste_coefs = other.coefs<span class="br0">&#91;</span>:<span class="br0">&#93;</span>; n = len<span class="br0">&#40;</span>self.coefs<span class="br0">&#41;</span> <span style="color: #808080;"># on copie les coefs du polyn&ocirc;me de degr&eacute; le plus &eacute;lev&eacute; et la longueur de la liste de coefs la plus petite. </span>
        <span style="color: #0000ff;">else</span>: liste_coefs = self.coefs<span class="br0">&#91;</span>:<span class="br0">&#93;</span>; n = len<span class="br0">&#40;</span>other.coefs<span class="br0">&#41;</span> <span style="color: #808080;"># sinon, ...</span>
&nbsp;
        <span style="color: #0000ff;">for</span> i <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span>n<span class="br0">&#41;</span>: <span style="color: #808080;"># parcours des indices de liste_coefs</span>
            liste_coefs<span class="br0">&#91;</span>i<span class="br0">&#93;</span> = self.coefs<span class="br0">&#91;</span>i<span class="br0">&#93;</span> + other.coefs<span class="br0">&#91;</span>i<span class="br0">&#93;</span> <span style="color: #808080;"># addition des coefficients de degr&eacute; i</span>
&nbsp;
        <span style="color: #0000ff;">return</span> Polynome<span class="br0">&#40;</span>liste_coefs<span class="br0">&#41;</span> <span style="color: #808080;"># renvoie le polyn&ocirc;me r&eacute;sultat de l'addition</span>
&nbsp;
&nbsp;
    <span style="color: #0000ff;">def</span> __sub__<span class="br0">&#40;</span>self, other<span class="br0">&#41;</span>: <span style="color: #808080;"># m&eacute;thode permettant de red&eacute;finir l'op&eacute;rateur &laquo; + &raquo; pour 2 polyn&ocirc;mes : (1 + 2x + x^2) + (1 + x) = 2 + 3x + x^2</span>
        <span style="color: #808080;"># p1 = self, p2 = other     </span>
        <span style="color: #0000ff;">if</span> len<span class="br0">&#40;</span>other.coefs<span class="br0">&#41;</span> &gt;len<span class="br0">&#40;</span>self.coefs<span class="br0">&#41;</span>: <span style="color: #808080;"># si degr&eacute; de p2 &gt; degr&eacute; de p1 </span>
            liste_coefs = other.coefs<span class="br0">&#91;</span>:<span class="br0">&#93;</span>; n = len<span class="br0">&#40;</span>self.coefs<span class="br0">&#41;</span> <span style="color: #808080;"># on copie les coefs du polyn&ocirc;me de degr&eacute; le plus &eacute;lev&eacute; et la longueur de la liste de coefs la plus petite. </span>
        <span style="color: #0000ff;">else</span>: liste_coefs = self.coefs<span class="br0">&#91;</span>:<span class="br0">&#93;</span>; n = len<span class="br0">&#40;</span>other.coefs<span class="br0">&#41;</span> <span style="color: #808080;"># sinon, ...</span>
&nbsp;
        <span style="color: #0000ff;">for</span> i <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span>n<span class="br0">&#41;</span>: <span style="color: #808080;"># parcours des indices de liste_coefs</span>
            liste_coefs<span class="br0">&#91;</span>i<span class="br0">&#93;</span> = self.coefs<span class="br0">&#91;</span>i<span class="br0">&#93;</span> - other.coefs<span class="br0">&#91;</span>i<span class="br0">&#93;</span> <span style="color: #808080;"># addition des coefficients de degr&eacute; i</span>
&nbsp;
        <span style="color: #0000ff;">return</span> Polynome<span class="br0">&#40;</span>liste_coefs<span class="br0">&#41;</span> <span style="color: #808080;"># renvoie le polyn&ocirc;me r&eacute;sultat de l'addition</span>
&nbsp;
&nbsp;
    <span style="color: #0000ff;">def</span> reduire<span class="br0">&#40;</span>self<span class="br0">&#41;</span>:
        <span style="color: #808080;"># tant que le dernier &eacute;l&eacute;ment de la liste est nul</span>
        <span style="color: #0000ff;">while</span> round<span class="br0">&#40;</span>self.coefs<span class="br0">&#91;</span>-<span style="color: #cc66cc;">1</span><span class="br0">&#93;</span>,<span style="color: #cc66cc;">12</span><span class="br0">&#41;</span> == <span style="color: #cc66cc;">0</span> <span style="color: #0000ff;">and</span> len<span class="br0">&#40;</span>self.coefs<span class="br0">&#41;</span>&gt;<span style="color: #cc66cc;">1</span>:
            self.coefs.pop<span class="br0">&#40;</span><span class="br0">&#41;</span> <span style="color: #808080;"># supprimer le dernier &eacute;l&eacute;ment</span>
&nbsp;
        <span style="color: #0000ff;">for</span> i <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span>len<span class="br0">&#40;</span>self.coefs<span class="br0">&#41;</span><span class="br0">&#41;</span>:
            self.coefs<span class="br0">&#91;</span>i<span class="br0">&#93;</span> = round<span class="br0">&#40;</span>self.coefs<span class="br0">&#91;</span>i<span class="br0">&#93;</span>,<span style="color: #cc66cc;">12</span><span class="br0">&#41;</span>
&nbsp;
&nbsp;
    <span style="color: #0000ff;">def</span> <span style="color: #0080ff;">__mul__</span><span class="br0">&#40;</span>self, other<span class="br0">&#41;</span>: <span style="color: #808080;"># m&eacute;thode permettant de red&eacute;finir l'op&eacute;rateur &laquo; * &raquo; pour 2 polyn&ocirc;mes : (1 + x) * (1 + 2x) =  1 + 3x + 2x^2</span>
&nbsp;
        <span style="color: #0000ff;">if</span> isinstance<span class="br0">&#40;</span>other,tuple<span class="br0">&#41;</span>:
&nbsp;
            coef = other<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span><span class="br0">&#93;</span>; degre = other<span class="br0">&#91;</span><span style="color: #cc66cc;">1</span><span class="br0">&#93;</span>
            liste_coefs = <span class="br0">&#91;</span><span style="color: #cc66cc;">0</span><span class="br0">&#93;</span>*degre + self.coefs
&nbsp;
            <span style="color: #0000ff;">for</span> i <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span>degre, len<span class="br0">&#40;</span>liste_coefs<span class="br0">&#41;</span><span class="br0">&#41;</span>:
                liste_coefs<span class="br0">&#91;</span>i<span class="br0">&#93;</span> = liste_coefs<span class="br0">&#91;</span>i<span class="br0">&#93;</span>*coef
&nbsp;
        <span style="color: #0000ff;">else</span>:
            <span style="color: #808080;"># initialisation de la liste des coefficients qu'avec des z&eacute;ros</span>
            liste_coefs=<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span><span class="br0">&#93;</span>*<span class="br0">&#40;</span>len<span class="br0">&#40;</span>self.coefs<span class="br0">&#41;</span>+len<span class="br0">&#40;</span>other.coefs<span class="br0">&#41;</span>-<span style="color: #cc66cc;">1</span><span class="br0">&#41;</span> <span style="color: #808080;"># exemple : [0, 0, 0]</span>
            <span style="color: #0000ff;">for</span> i1 <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span>len<span class="br0">&#40;</span>self.coefs<span class="br0">&#41;</span><span class="br0">&#41;</span>: <span style="color: #808080;"># parcours des indices des coefs du polyn&ocirc;me n&deg;1</span>
                <span style="color: #0000ff;">for</span> i2 <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span>len<span class="br0">&#40;</span>other.coefs<span class="br0">&#41;</span><span class="br0">&#41;</span>: <span style="color: #808080;"># parcours des indices des coefs du polyn&ocirc;me n&deg;2</span>
                    <span style="color: #808080;"># multiplication des coefficients d'indices i1 et i2</span>
                    liste_coefs<span class="br0">&#91;</span>i1+i2<span class="br0">&#93;</span> = liste_coefs<span class="br0">&#91;</span>i1+i2<span class="br0">&#93;</span> + self.coefs<span class="br0">&#91;</span>i1<span class="br0">&#93;</span>*other.coefs<span class="br0">&#91;</span>i2<span class="br0">&#93;</span>
&nbsp;
        poly = Polynome<span class="br0">&#40;</span>liste_coefs<span class="br0">&#41;</span> <span style="color: #808080;"># cr&eacute;ation de l'objet Polynome bas&eacute; sur la liste</span>
&nbsp;
        <span style="color: #0000ff;">return</span> poly <span style="color: #808080;"># renvoie le polyn&ocirc;me r&eacute;sultat de la multiplication</span>
&nbsp;
&nbsp;
    <span style="color: #0000ff;">def</span> __pow__<span class="br0">&#40;</span>self, n<span class="br0">&#41;</span>: <span style="color: #808080;"># m&eacute;thode permettant de red&eacute;finir l'op&eacute;rateur de puissance : self ** n</span>
        <span style="color: #808080;"># on cr&eacute;e l'objet poly &agrave; partir d'une liste contenant un seul &eacute;l&eacute;ment 1, &eacute;l&eacute;ment neutre pour la multiplication des polyn&ocirc;mes</span>
        poly = Polynome<span class="br0">&#40;</span><span class="br0">&#91;</span><span style="color: #cc66cc;">1</span><span class="br0">&#93;</span><span class="br0">&#41;</span> 
&nbsp;
        <span style="color: #0000ff;">for</span> i <span style="color: #0000ff;">in</span> range<span class="br0">&#40;</span>n<span class="br0">&#41;</span>: <span style="color: #808080;"># on multiplie n fois poly par self &agrave; l'aide de l'op&eacute;rateur *            </span>
            poly = poly*self <span style="color: #808080;"># &eacute;quivalent &agrave; : poly = poly.__mul__(self)</span>
&nbsp;
        <span style="color: #0000ff;">return</span> poly <span style="color: #808080;"># renvoie le polyn&ocirc;me r&eacute;sultat de l'op&eacute;ration (self ** n)</span>
&nbsp;
&nbsp;
    <span style="color: #0000ff;">def</span> __truediv__<span class="br0">&#40;</span>self, other<span class="br0">&#41;</span>: <span style="color: #808080;"># m&eacute;thode permettant de red&eacute;finir l'op&eacute;rateur &laquo; / &raquo; pour 2 polyn&ocirc;mes</span>
&nbsp;
        <span style="color: #808080;"># si le degr&eacute; de self est inf&eacute;rieur au degr&eacute; de other</span>
        <span style="color: #0000ff;">if</span> self.degre<span class="br0">&#40;</span><span class="br0">&#41;</span>&lt;other.degre<span class="br0">&#40;</span><span class="br0">&#41;</span>:
            <span style="color: #808080;"># on renvoie (0, self) : q=0, r=self</span>
            <span style="color: #0000ff;">return</span> <span class="br0">&#40;</span>Polynome<span class="br0">&#40;</span><span class="br0">&#91;</span><span style="color: #cc66cc;">0</span><span class="br0">&#93;</span><span class="br0">&#41;</span>, self<span class="br0">&#41;</span> <span style="color: #808080;"># sortie de la fonction</span>
&nbsp;
        <span style="color: #808080;"># polyn&ocirc;me self repr&eacute;sentant au d&eacute;part le reste r</span>
        r = Polynome<span class="br0">&#40;</span>self.coefs<span class="br0">&#41;</span>
&nbsp;
        <span style="color: #808080;"># degr&eacute; du polyn&ocirc;me repr&eacute;sentant le quotient q</span>
        degre = r.degre<span class="br0">&#40;</span><span class="br0">&#41;</span> - other.degre<span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
        <span style="color: #808080;"># initialisation du polyn&ocirc;me q : [0, 0, 1] -&gt; ... + X^2</span>
        q = Polynome<span class="br0">&#40;</span><span class="br0">&#91;</span><span style="color: #cc66cc;">0</span><span class="br0">&#93;</span>*degre + <span class="br0">&#91;</span><span style="color: #cc66cc;">1</span><span class="br0">&#93;</span><span class="br0">&#41;</span>
&nbsp;
        <span style="color: #808080;"># tant que le degr&eacute; mini des termes du polyn&ocirc;me q est sup&eacute;rieur ou &eacute;gal &agrave; 0, et que r n'est pas &eacute;gal &agrave; 0.</span>
        <span style="color: #0000ff;">while</span> <span class="br0">&#40;</span>degre&gt;=<span style="color: #cc66cc;">0</span><span class="br0">&#41;</span> <span style="color: #0000ff;">and</span> <span class="br0">&#40;</span>r.coefs<span class="br0">&#91;</span>-<span style="color: #cc66cc;">1</span><span class="br0">&#93;</span>!=<span style="color: #cc66cc;">0</span><span class="br0">&#41;</span>:
&nbsp;
            <span style="color: #808080;"># coefficient du nouveau terme du polyn&ocirc;me q</span>
            coef = r.coefs<span class="br0">&#91;</span>-<span style="color: #cc66cc;">1</span><span class="br0">&#93;</span> / other.coefs<span class="br0">&#91;</span>-<span style="color: #cc66cc;">1</span><span class="br0">&#93;</span>
&nbsp;
            <span style="color: #808080;"># affectation du coefficient au terme</span>
            q.coefs<span class="br0">&#91;</span>degre<span class="br0">&#93;</span> = coef
&nbsp;
            <span style="color: #808080;"># on multiplie le polyn&ocirc;me other par le polyn&ocirc;me coef*(x^degre)</span>
            p = other * <span class="br0">&#40;</span>coef, degre<span class="br0">&#41;</span>
&nbsp;
            <span style="color: #808080;"># soustraction des polyn&ocirc;mes r et p</span>
            r = r - p
&nbsp;
            <span style="color: #808080;"># degr&eacute; du nouveau terme du polyn&ocirc;me q</span>
            degre = r.degre<span class="br0">&#40;</span><span class="br0">&#41;</span> - other.degre<span class="br0">&#40;</span><span class="br0">&#41;</span> 
&nbsp;
        <span style="color: #808080;"># renvoi le couple (q, r) repr&eacute;sentant le quotient et le reste de la division            </span>
        <span style="color: #0000ff;">return</span> <span class="br0">&#40;</span>q, r<span class="br0">&#41;</span>
&nbsp;
&nbsp;
    <span style="color: #0000ff;">def</span> <span style="color: #0080ff;">__eq__</span><span class="br0">&#40;</span>poly1, other<span class="br0">&#41;</span>: <span style="color: #808080;"># m&eacute;thode permettant de red&eacute;finir l'op&eacute;rateur &laquo; == &raquo; pour 2 polyn&ocirc;mes</span>
&nbsp;
        <span style="color: #0000ff;">return</span> <span class="br0">&#40;</span>poly1.coefs==other.coefs<span class="br0">&#41;</span> <span style="color: #808080;"># renvoie True si les 2 listes de coefficients sont &eacute;gales</span>
&nbsp;
&nbsp;
    <span style="color: #0000ff;">def</span> eval<span class="br0">&#40;</span>self,x<span class="br0">&#41;</span>: <span style="color: #808080;"># m&eacute;thode permettant d'&eacute;valuer le polyn&ocirc;me en fonction de x</span>
        <span style="color: #808080;"># intialisation des variables</span>
        valeur_polynome = self.coefs<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span><span class="br0">&#93;</span> <span style="color: #808080;"># valeur_polynome = a0</span>
        power=<span style="color: #cc66cc;">1</span>    
&nbsp;
        <span style="color: #0000ff;">for</span> coef <span style="color: #0000ff;">in</span> self.coefs<span class="br0">&#91;</span><span style="color: #cc66cc;">1</span>:<span class="br0">&#93;</span>: <span style="color: #808080;"># parcours des coefficients du polyn&ocirc;me &agrave; partir de a1 : a1, a2, ..., an</span>
            power = power*x <span style="color: #808080;"># calcul de la puissance de x pour ai : power = x^i</span>
            valeur_polynome += coef*power <span style="color: #808080;"># valeur_polynome = valeur_polynome + ai*x^i</span>
&nbsp;
        <span style="color: #0000ff;">return</span> valeur_polynome <span style="color: #808080;"># renvoie la valeur du polyn&ocirc;me</span>
&nbsp;
    <span style="color: #0000ff;">def</span> eval_horner<span class="br0">&#40;</span>self,x<span class="br0">&#41;</span>: <span style="color: #808080;"># m&eacute;thode permettant d'&eacute;valuer le polyn&ocirc;me en fonction de x</span>
        <span style="color: #808080;"># intialisation de la variable</span>
        valeur_polynome = self.coefs<span class="br0">&#91;</span>-<span style="color: #cc66cc;">1</span><span class="br0">&#93;</span> <span style="color: #808080;"># valeur_polynome = an</span>
&nbsp;
        <span style="color: #0000ff;">for</span> coef <span style="color: #0000ff;">in</span> reversed<span class="br0">&#40;</span>self.coefs<span class="br0">&#91;</span>:-<span style="color: #cc66cc;">1</span><span class="br0">&#93;</span><span class="br0">&#41;</span>: <span style="color: #808080;"># parcours des coefficients du polyn&ocirc;me &agrave; partir de an-1 : an-1, ..., a1, a0</span>
            valeur_polynome = valeur_polynome*x + coef  <span style="color: #808080;"># valeur_polynome = valeur_polynome*x + ai</span>
&nbsp;
        <span style="color: #0000ff;">return</span> valeur_polynome <span style="color: #808080;"># renvoie la valeur du polyn&ocirc;me</span>
&nbsp;
&nbsp;
<span style="color: #0000ff;">def</span> PGCD<span class="br0">&#40;</span>a, b<span class="br0">&#41;</span>:
&nbsp;
    <span style="color: #808080;"># si b=0</span>
    <span style="color: #0000ff;">if</span> <span class="br0">&#40;</span>b==<span style="color: #cc66cc;">0</span><span class="br0">&#41;</span>:
        <span style="color: #808080;"># renvoi de a</span>
        <span style="color: #0000ff;">return</span> a
    <span style="color: #0000ff;">else</span>: <span style="color: #808080;"># sinon</span>
        <span style="color: #808080;"># calcul du reste r de la division de a par b</span>
        r = a % b
&nbsp;
        <span style="color: #808080;"># appel de la fonction PGCD pour a=b et b=r</span>
        <span style="color: #0000ff;">return</span> PGCD<span class="br0">&#40;</span>b, r<span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">def</span> PGCD_POLY<span class="br0">&#40;</span>A, B<span class="br0">&#41;</span>:
&nbsp;
    <span style="color: #808080;"># si B=0</span>
    <span style="color: #0000ff;">if</span> <span class="br0">&#40;</span>B==Polynome<span class="br0">&#40;</span><span class="br0">&#91;</span><span style="color: #cc66cc;">0</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>:
        <span style="color: #808080;"># par convention on choisit de renvoyer le polyn&ocirc;me unitaire, polyn&ocirc;me non nul et dont le coefficient dominant vaut 1 :</span>
        coef = <span style="color: #cc66cc;">1</span>/A.coefs<span class="br0">&#91;</span>-<span style="color: #cc66cc;">1</span><span class="br0">&#93;</span>
	<span style="color: #808080;"># multiplication de A par coef</span>
        A = A*<span class="br0">&#40;</span>coef,<span style="color: #cc66cc;">0</span><span class="br0">&#41;</span>
&nbsp;
        <span style="color: #808080;"># renvoi de A    </span>
        <span style="color: #0000ff;">return</span> A
    <span style="color: #0000ff;">else</span>:
        <span style="color: #808080;"># d&eacute;termination du quotient Q et du reste R de la division de A par B</span>
        Q, R = A / B
&nbsp;
        <span style="color: #808080;"># appel de la fonction PGCD pour A=B et B=R</span>
        <span style="color: #0000ff;">return</span> PGCD_POLY<span class="br0">&#40;</span>B, R<span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;I. PGCD de deux entiers :<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># calcul du PGCD des entiers 25 et 15</span>
gcd = PGCD<span class="br0">&#40;</span><span style="color: #cc66cc;">21</span>, <span style="color: #cc66cc;">15</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche le r&eacute;sultat</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;PGCD(21, 15) = &quot;</span> + str<span class="br0">&#40;</span>gcd<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;II. Division de deux polyn&ocirc;mes :<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># cr&eacute;ation du polyn&ocirc;me p1 = (1 + X)(2 + X) = 2 + 3X + X^2</span>
p1 = Polynome<span class="br0">&#40;</span><span class="br0">&#91;</span><span style="color: #cc66cc;">1</span>,<span style="color: #cc66cc;">1</span><span class="br0">&#93;</span><span class="br0">&#41;</span>*Polynome<span class="br0">&#40;</span><span class="br0">&#91;</span><span style="color: #cc66cc;">2</span>, <span style="color: #cc66cc;">1</span><span class="br0">&#93;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;p1 = &quot;</span> + str<span class="br0">&#40;</span>p1<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># cr&eacute;ation du polyn&ocirc;me p2 = 1 + 2X + X^2 = (1 + X)^2</span>
p2 = Polynome<span class="br0">&#40;</span><span class="br0">&#91;</span><span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">2</span>, <span style="color: #cc66cc;">1</span><span class="br0">&#93;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;p2 = &quot;</span> + str<span class="br0">&#40;</span>p2<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># division euclidienne : p1 = p2*q + r</span>
q, r = p1 / p2
&nbsp;
<span style="color: #808080;"># affiche le quotient q et le reste r de la division</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;q = &quot;</span> + str<span class="br0">&#40;</span>q<span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;r = &quot;</span> + str<span class="br0">&#40;</span>r<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;III. PGCD de deux polyn&ocirc;mes :<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># calcul du PGCD des polyn&ocirc;mes p1 et p2</span>
gcd = PGCD_POLY<span class="br0">&#40;</span>p1, p2<span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche le r&eacute;sultat</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;PGCD(p1, p2) = &quot;</span> + str<span class="br0">&#40;</span>gcd<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;IV. Application : simplification de fractions :<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># cr&eacute;ation du polyn&ocirc;me p1 = -10 + X + X^3</span>
p1 = Polynome<span class="br0">&#40;</span><span class="br0">&#91;</span>-<span style="color: #cc66cc;">10</span>, <span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">0</span>, <span style="color: #cc66cc;">1</span><span class="br0">&#93;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;p1 = &quot;</span> + str<span class="br0">&#40;</span>p1<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># cr&eacute;ation du polyn&ocirc;me p2 = -6 - X + 2X^2</span>
p2 = Polynome<span class="br0">&#40;</span><span class="br0">&#91;</span>-<span style="color: #cc66cc;">6</span>, -<span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">2</span><span class="br0">&#93;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;p2 = &quot;</span> + str<span class="br0">&#40;</span>p2<span class="br0">&#41;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Limite de p1/p2 quand X -&gt; 2 = 0/0<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># calcul du PGCD des polyn&ocirc;mes p1 et p2</span>
gcd = PGCD_POLY<span class="br0">&#40;</span>p1, p2<span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche le r&eacute;sultat</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;PGCD(p1, p2) = &quot;</span> + str<span class="br0">&#40;</span>gcd<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># simplification de p1</span>
p1, r1 = p1 / gcd
&nbsp;
<span style="color: #808080;"># simplification de p2</span>
p2, r2 = p2 / gcd
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;p1/p2 = ({0})/({1})&quot;</span>.format<span class="br0">&#40;</span>p1, p2<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Limite de p1/p2 quand X -&gt; 2 = {0}/{1}<span style="color: #800000;">\n</span>&quot;</span>.format<span class="br0">&#40;</span>p1.eval<span class="br0">&#40;</span><span style="color: #cc66cc;">2</span><span class="br0">&#41;</span>,p2.eval<span class="br0">&#40;</span><span style="color: #cc66cc;">2</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
<br />
<b>V. Conclusion</b><br />
<br />
Après avoir décrit l'algorithme d'Euclide, nous avons pu créer des fonctions récursives permettant d'obtenir le PGCD de deux nombres entiers et celui de deux polynômes.<br />
<br />
Chacun pourra ensuite librement les transformer en fonctions itératives.<br />
<br />
<br />
<b>Sources :</b><br />
<br />
<a href="https://fr.wikipedia.org/wiki/Plus_grand_commun_diviseur_de_nombres_entiers" target="_blank">https://fr.wikipedia.org/wiki/Plus_g...ombres_entiers</a><br />
<a href="https://fr.wikipedia.org/wiki/Plus_grand_commun_diviseur" target="_blank">https://fr.wikipedia.org/wiki/Plus_g...ommun_diviseur</a><br />
<a href="https://fr.wikipedia.org/wiki/Algorithme_d%27Euclide" target="_blank">https://fr.wikipedia.org/wiki/Algorithme_d%27Euclide</a><br />
<a href="https://fr.wikipedia.org/wiki/Division_d%27un_polyn%C3%B4me" target="_blank">https://fr.wikipedia.org/wiki/Divisi..._polyn%C3%B4me</a><br />
<a href="https://fr.wikipedia.org/wiki/Polyn%C3%B4me_unitaire" target="_blank">https://fr.wikipedia.org/wiki/Polyn%C3%B4me_unitaire</a><br />
<a href="http://www.jybaudot.fr/Maths/divipolyn.html" target="_blank">http://www.jybaudot.fr/Maths/divipolyn.html</a></font></blockquote>

]]></content:encoded>
			<dc:creator>User</dc:creator>
			<guid isPermaLink="true">https://www.developpez.net/forums/blogs/44027-user/b10548/mathematiques-python-pgcd-nombres-entiers-polynomes/</guid>
		</item>
		<item>
			<title><![CDATA[Mathématiques et Python : générer les partitions d'un entier]]></title>
			<link>https://www.developpez.net/forums/blogs/44027-user/b10544/mathematiques-python-generer-partitions-d-entier/</link>
			<pubDate>Wed, 08 Nov 2023 12:59:56 GMT</pubDate>
			<description>*I. Introduction* 
 
Après...</description>
			<content:encoded><![CDATA[<blockquote class="blogcontent restore"><font size="3"><b>I. Introduction</b><br />
<br />
Après les <a href="https://fr.wikipedia.org/wiki/Partition_d%27un_ensemble" target="_blank">partitions d'un ensemble</a>, on s'intéresse maintenant aux <a href="https://fr.wikipedia.org/wiki/Partition_d%27un_entier" target="_blank">partitions d'un entier</a> :<br />
<br />
L'objectif sera cette fois de créer une <a href="https://fr.wikiversity.org/wiki/Algorithmique/Forme_d%27%C3%A9criture#Forme_it%C3%A9rative" target="_blank">fonction itérative</a> en Python qui pourra générer la liste des partitions d'un entier quelconque.<br />
<br />
On va ensuite montrer comment transformer ce code en une <a href="https://gayerie.dev/docs/python/python3/iterateur_generateur.html#les-fonctions-generatrices-avec-yield" target="_blank">fonction génératrice</a> qui va nous permettre d'obtenir les partitions sans avoir besoin de les stocker dans une liste.<br />
<br />
<br />
<br />
<b>II. Partitions d'un entier</b><br />
<br />
<br />
<b>II-A. Définition mathématique</b><br />
<br />
En mathématiques, une <a href="https://fr.wikipedia.org/wiki/Partition_d%27un_entier" target="_blank">partition d'un entier</a> (parfois aussi appelée partage d'un entier) est une décomposition de cet entier en une somme d'entiers strictement positifs (appelés parties ou sommants), à l'ordre près des termes (à la différence du problème de composition tenant compte de l'ordre des termes). <br />
<br />
Une telle partition est en général représentée par la suite des termes de la somme, rangés par ordre décroissant. <br />
<br />
Prenons par exemple le nombre entier <b>5</b>, les <b>7</b> partitions de <b>5</b> sont :<br />
<br />
<ul><li style="">5 ;</li><li style="">4 + 1 ;</li><li style="">3 + 2 ;</li><li style="">3 + 1 + 1 ;</li><li style="">2 + 2 + 1 ;</li><li style="">2 + 1 + 1 + 1 ;</li><li style="">1 + 1 + 1 + 1 + 1.</li></ul><br />
<br />
Si on note <b>&#119901;(n)</b> le nombre de partitions de l'entier <b>n</b>, alors les premiers termes de la suite <b>&#119901;(n)</b> donnent :<br />
<br />
<span class="highlight">&#119901;(1) = 1, &#119901;(2) = 2, &#119901;(3) = 3, &#119901;(4) = 5, &#119901;(5) = 7, &#119901;(6) = 11, &#119901;(7) = 15, &#119901;(8) = 22, &#119901;(9) = 30, &#119901;(10) = 42, ..., <br />
&#119901;(50) = 204226, ..., &#119901;(100) = 190 569 292, ..., &#119901;(200) = 3 972 999 029 388, ...</span><br />
<br />
On peut remarquer que la croissance de cette suite est très rapide.<br />
<br />
<br />
<b>II-B. Génération des partitions d'un entier</b><br />
<br />
On va utiliser pour cela l'algorithme de construction décrit sur la page Wikipedia <a href="https://fr.wikipedia.org/wiki/Partition_d%27un_entier#Algorithme_de_construction" target="_blank">partition d'un entier</a> :<br />
<br />
La liste de toutes les partitions de <b>&#119899;</b> dans l'ordre décroissant est donnée par un algorithme itératif. <br />
<br />
Si une partition est représentée par une suite finie décroissante <b>(&#119886;<sub>&#119894;</sub>)</b> dont au moins un terme est strictement supérieur à <b>1</b>, la partition suivante <b>(&#119887;<sub>&#119894;</sub>)</b> est construite comme suit :<br />
<br />
On note <b>&#119896;</b> le rang du dernier terme strictement supérieur à <b>1</b> et <b>&#119873;</b> le nombre de termes qui valent <b>1</b> dans <b>(&#119886;<sub>&#119894;</sub>)</b>.<br />
Pour tout <b>j &lt; &#119896;</b>, on définit <b>&#119887;<sub>&#119895;</sub> = &#119886;<sub>&#119895;</sub></b>.<br />
On définit <b>&#119887;<sub>&#119896;</sub> = &#119886;<sub>&#119896;</sub> &#8722; 1</b>.<br />
En notant <b>&#119873; + 1 = &#119887;<sub>&#119896;</sub>&#119902; + &#119903;</b> la division euclidienne de <b>&#119873; + 1</b> par <b>&#119887;<sub>&#119896;</sub></b>, on définit les termes <b>&#119887;<sub>&#119895;</sub></b> pour <b>&#119896; &lt; &#119895; &lt; &#119896; + &#119902; + 1</b>  par <b>&#119887;<sub>&#119895;</sub> = &#119887;<sub>&#119896;</sub></b>.<br />
Si <b>&#119903;</b> est non nul, on définit un dernier terme <b>&#119887;<sub>&#119896;+&#119902;+1</sub> = &#119903;</b>.<br />
<br />
On peut obtenir ainsi la liste des partitions <b>p<sub>i</sub></b> de l'entier <b>5</b> :<br />
<br />
<img src="https://www.developpez.net/forums/attachments/p646257d1699367208/parkings/restreint-parking-admin/version-2-nouveau-gabarit-dynamique-vos-articles/tableau_algo.png/" border="0" alt="Nom : tableau_algo.png
Affichages : 21527
Taille : 30,0 Ko"  style="float: CONFIG" /><br />
<br />
L'objectif va être ensuite de traduire cet algorithme en Python.<br />
<br />
<br />
<br />
<b>III. Implémentation en Python</b><br />
<br />
<br />
<b>III-A. Génération de la liste des partitions d'un entier</b><br />
<br />
On crée tout d'abord la fonction permettant de passer de la partition <b>p<sub>i</sub></b> à la partition <b>p<sub>i+1</sub></b> :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">def</span> partition_suivante<span class="br0">&#40;</span>a, k, N<span class="br0">&#41;</span>:
    <span style="color: #808080;"># Construit la partition b qui suit la partition a dans la liste des partitions.</span>
    <span style="color: #808080;"># a : liste des entiers repr&eacute;sentant la partition pass&eacute;e en argument</span>
    <span style="color: #808080;"># k : rang du dernier entier dans a strictement sup&eacute;rieur &agrave; 1</span>
    <span style="color: #808080;"># N : nombre d'entiers qui valent 1 dans la liste a </span>
&nbsp;
    <span style="color: #808080;"># pour tout j &lt; k, on d&eacute;finit b[j] = a[j] : a = [2, 2, 1] -&gt; b = [2]</span>
    b = a<span class="br0">&#91;</span>:k<span class="br0">&#93;</span>
&nbsp;
    <span style="color: #808080;"># On ajoute (a[k] - 1) &agrave; la liste b : b[k] = a[k] - 1 : a = [2, 2, 1] -&gt; b = [2, 1]</span>
    b.append<span class="br0">&#40;</span>a<span class="br0">&#91;</span>k<span class="br0">&#93;</span>-<span style="color: #cc66cc;">1</span><span class="br0">&#41;</span>
&nbsp;
    <span style="color: #808080;"># En notant N+1 = b[k]*q + r la division euclidienne de N+1 par b[k] </span>
    <span style="color: #808080;"># On obtient le quotient q et le reste r de cette division.</span>
    q = <span class="br0">&#40;</span>N+<span style="color: #cc66cc;">1</span><span class="br0">&#41;</span> // b<span class="br0">&#91;</span>k<span class="br0">&#93;</span> ; r = <span class="br0">&#40;</span>N+<span style="color: #cc66cc;">1</span><span class="br0">&#41;</span> % b<span class="br0">&#91;</span>k<span class="br0">&#93;</span>
&nbsp;
    <span style="color: #808080;"># On &eacute;value ensuite les entiers b[j] = b[k] pour k &lt; j &lt; k + q + 1 : a = [2, 2, 1] -&gt; b = [2, 1] + 2*[1] = [2, 1, 1, 1]</span>
    b = b + q*<span class="br0">&#91;</span>b<span class="br0">&#91;</span>k<span class="br0">&#93;</span><span class="br0">&#93;</span>
&nbsp;
    <span style="color: #808080;"># Si le reste r est non nul.</span>
    <span style="color: #0000ff;">if</span> r!=<span style="color: #cc66cc;">0</span>: <span style="color: #808080;"># ou : if r:</span>
        <span style="color: #808080;"># On ajoute l'entier r &agrave; la liste b : b[k+q+1] = r</span>
        b.append<span class="br0">&#40;</span>r<span class="br0">&#41;</span>
&nbsp;
    <span style="color: #808080;"># calcul des valeurs de k et N pour la nouvelle partition b</span>
    <span style="color: #0000ff;">while</span> <span class="br0">&#40;</span>b<span class="br0">&#91;</span>k<span class="br0">&#93;</span>!=<span style="color: #cc66cc;">1</span><span class="br0">&#41;</span>:
        k+=<span style="color: #cc66cc;">1</span>
        <span style="color: #0000ff;">if</span> k==len<span class="br0">&#40;</span>b<span class="br0">&#41;</span>:
            <span style="color: #0000ff;">break</span>
&nbsp;
    <span style="color: #808080;"># renvoi de la partition b suivant la partition a, du rang k dans b, et du nombre N d'entiers valant 1 dans b</span>
    <span style="color: #0000ff;">return</span> <span class="br0">&#40;</span>b, k-<span style="color: #cc66cc;">1</span>, len<span class="br0">&#40;</span>b<span class="br0">&#41;</span> - k<span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
Enfin, on crée la fonction principale permettant de générer la liste des partitions de l'entier <b>n</b> :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">def</span> generer_partitions<span class="br0">&#40;</span>n<span class="br0">&#41;</span>:
    <span style="color: #808080;"># Fonction principale permettant de g&eacute;n&eacute;rer la liste des partitions de l'entier n.</span>
    <span style="color: #808080;"># Partitions dont les termes sont rang&eacute;s dans l'ordre d&eacute;croissant : [[5], [4, 1], [3, 2], ..., [1, 1, 1, 1, 1,]]</span>
&nbsp;
    <span style="color: #808080;"># 1re partition de la liste</span>
    p = <span class="br0">&#91;</span>n<span class="br0">&#93;</span>
&nbsp;
    <span style="color: #808080;"># initialisation de la liste avec la 1re partition [n]</span>
    partitions = <span class="br0">&#91;</span>p<span class="br0">&#93;</span>
&nbsp;
    <span style="color: #808080;"># initialisation des variables k et N</span>
    <span style="color: #808080;"># k : rang du dernier entier de [n] strictement sup&eacute;rieur &agrave; 1</span>
    <span style="color: #808080;"># N : nombre d'entiers qui valent 1 dans [n]</span>
&nbsp;
    <span style="color: #808080;"># k=-1 et N=1 si n=1, sinon k=0 et N=0</span>
    <span class="br0">&#40;</span>k, N<span class="br0">&#41;</span> = <span class="br0">&#40;</span>-<span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">1</span><span class="br0">&#41;</span> <span style="color: #0000ff;">if</span> n==<span style="color: #cc66cc;">1</span> <span style="color: #0000ff;">else</span> <span class="br0">&#40;</span><span style="color: #cc66cc;">0</span>, <span style="color: #cc66cc;">0</span><span class="br0">&#41;</span>
&nbsp;
    <span style="color: #808080;"># Tant que k est sup&eacute;rieur ou &eacute;gal &agrave; 0 : si k=-1 on sort de la boucle</span>
    <span style="color: #0000ff;">while</span> k&gt;=<span style="color: #cc66cc;">0</span>:
&nbsp;
        <span style="color: #808080;"># appel de la fonction renvoyant la partition suivant p, avec les param&egrave;tres k et N</span>
        p, k, N = partition_suivante<span class="br0">&#40;</span>p, k, N<span class="br0">&#41;</span>
&nbsp;
        <span style="color: #808080;"># ajout de la nouvelle partition &agrave; la liste</span>
        partitions.append<span class="br0">&#40;</span>p<span class="br0">&#41;</span>
&nbsp;
    <span style="color: #808080;"># renvoi de la liste des partitions : [5], [4,1], [3,2], ..., [1, 1, 1, 1, 1,]]</span>
    <span style="color: #0000ff;">return</span> partitions</pre></td></tr></table></pre>
</div><br />
Testons maintenant la fonction :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:144px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="26"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #808080;"># Nombre entier dont on souhaite g&eacute;n&eacute;rer les partitions.</span>
n = <span style="color: #cc66cc;">5</span>
&nbsp;
<span style="color: #808080;"># version n&deg;1 : cr&eacute;ation de la liste des partitions de l'entier de d&eacute;part</span>
partitions = generer_partitions<span class="br0">&#40;</span>n<span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># Affiche les partitions une &agrave; une.</span>
<span style="color: #0000ff;">for</span> partition <span style="color: #0000ff;">in</span> partitions:
    <span style="color: #0000ff;">print</span><span class="br0">&#40;</span>tuple<span class="br0">&#40;</span>partition<span class="br0">&#41;</span><span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
Le code affiche :<br />
<br />
<span class="highlight">(5,)<br />
(4, 1)<br />
(3, 2)<br />
(3, 1, 1)<br />
(2, 2, 1)<br />
(2, 1, 1, 1)<br />
(1, 1, 1, 1, 1)<br />
</span><br />
<br />
<br />
<b>III-B. Fonction génératrice avec yield</b><br />
<br />
Comme on l'a vu précédemment, le nombre de partitions croît très rapidement quand l'entier <b>n</b> augmente, ce qui risque d'entrainer des problèmes de mémoire insuffisante (MemoryError, ...).<br />
<br />
On peut dans ce cas utiliser à la place une <a href="https://gayerie.dev/docs/python/python3/iterateur_generateur.html#les-fonctions-generatrices-avec-yield" target="_blank">fonction génératrice</a> qui va créer à la demande l'élément suivant de la séquence sans avoir besoin de le stocker dans une liste, permettant ainsi d’économiser de la mémoire.<br />
<br />
Pour cela, Python dispose de l'instruction <i>yield</i> qui permet de transformer une fonction en générateur :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">def</span> generateur_partitions<span class="br0">&#40;</span>n<span class="br0">&#41;</span>:
    <span style="color: #808080;"># Fonction g&eacute;n&eacute;ratrice permettant de parcourir les partitions de l'entier n. </span>
    <span style="color: #808080;"># Partitions dont les termes sont rang&eacute;s dans l'ordre d&eacute;croissant : [[5], [4, 1], [3, 2], ..., [1, 1, 1, 1, 1,]]</span>
&nbsp;
    <span style="color: #808080;"># 1re partition de la liste</span>
    p = <span class="br0">&#91;</span>n<span class="br0">&#93;</span>
&nbsp;
    <span style="color: #808080;"># renvoi de la 1re partition</span>
    <span style="color: #0000ff;">yield</span> p
&nbsp;
    <span style="color: #808080;"># initialisation des variables k et N</span>
    <span style="color: #808080;"># k : rang du dernier entier de [n] strictement sup&eacute;rieur &agrave; 1</span>
    <span style="color: #808080;"># N : nombre d'entiers qui valent 1 dans [n]</span>
&nbsp;
    <span style="color: #808080;"># k=-1 et N=1 si n=1, sinon k=0 et N=0</span>
    <span class="br0">&#40;</span>k, N<span class="br0">&#41;</span> = <span class="br0">&#40;</span>-<span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">1</span><span class="br0">&#41;</span> <span style="color: #0000ff;">if</span> n==<span style="color: #cc66cc;">1</span> <span style="color: #0000ff;">else</span> <span class="br0">&#40;</span><span style="color: #cc66cc;">0</span>, <span style="color: #cc66cc;">0</span><span class="br0">&#41;</span>
&nbsp;
    <span style="color: #808080;"># Tant que k est sup&eacute;rieur ou &eacute;gal &agrave; 0 : si k=-1 on sort de la boucle.</span>
    <span style="color: #0000ff;">while</span> k&gt;=<span style="color: #cc66cc;">0</span>:
&nbsp;
        <span style="color: #808080;"># appel de la fonction renvoyant la partition qui suit p, avec les param&egrave;tres k et N</span>
        p, k, N = partition_suivante<span class="br0">&#40;</span>p, k, N<span class="br0">&#41;</span>
&nbsp;
        <span style="color: #808080;"># renvoi de la nouvelle partition p</span>
        <span style="color: #0000ff;">yield</span> p</pre></td></tr></table></pre>
</div><br />
Testons maintenant la fonction :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:144px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="26"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #808080;"># Nombre entier dont on souhaite g&eacute;n&eacute;rer les partitions.</span>
n = <span style="color: #cc66cc;">5</span>
&nbsp;
<span style="color: #808080;"># version n&deg;2 : cr&eacute;ation du g&eacute;n&eacute;rateur permettant de parcourir la liste des partitions de l'entier de d&eacute;part</span>
gen_partitions = generateur_partitions<span class="br0">&#40;</span>n<span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># Affiche les partitions une &agrave; une.</span>
<span style="color: #0000ff;">for</span> partition <span style="color: #0000ff;">in</span> gen_partitions:
    <span style="color: #0000ff;">print</span><span class="br0">&#40;</span>tuple<span class="br0">&#40;</span>partition<span class="br0">&#41;</span><span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
Le code affiche :<br />
<br />
<span class="highlight">(5,)<br />
(4, 1)<br />
(3, 2)<br />
(3, 1, 1)<br />
(2, 2, 1)<br />
(2, 1, 1, 1)<br />
(1, 1, 1, 1, 1)<br />
</span><br />
<br />
<br />
<b>III-C. Module complet</b><br />
<br />
On donne enfin le code complet du module pour effectuer les tests :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="40"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br />50<br />51<br />52<br />53<br />54<br />55<br />56<br />57<br />58<br />59<br />60<br />61<br />62<br />63<br />64<br />65<br />66<br />67<br />68<br />69<br />70<br />71<br />72<br />73<br />74<br />75<br />76<br />77<br />78<br />79<br />80<br />81<br />82<br />83<br />84<br />85<br />86<br />87<br />88<br />89<br />90<br />91<br />92<br />93<br />94<br />95<br />96<br />97<br />98<br />99<br />100<br />101<br />102<br />103<br />104<br />105<br />106<br />107<br />108<br />109<br />110<br />111<br />112<br />113<br />114<br />115<br />116<br />117<br />118<br />119<br />120<br />121<br />122<br />123<br />124<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">def</span> partition_suivante<span class="br0">&#40;</span>a, k, N<span class="br0">&#41;</span>:
    <span style="color: #808080;"># Construit la partition b qui suit la partition a dans la liste des partitions.</span>
    <span style="color: #808080;"># a : liste des entiers repr&eacute;sentant la partition pass&eacute;e en argument</span>
    <span style="color: #808080;"># k : rang du dernier entier dans a strictement sup&eacute;rieur &agrave; 1</span>
    <span style="color: #808080;"># N : nombre d'entiers qui valent 1 dans la liste a </span>
&nbsp;
    <span style="color: #808080;"># pour tout j &lt; k, on d&eacute;finit b[j] = a[j] : a = [2, 2, 1] -&gt; b = [2]</span>
    b = a<span class="br0">&#91;</span>:k<span class="br0">&#93;</span>
&nbsp;
    <span style="color: #808080;"># On ajoute (a[k] - 1) &agrave; la liste b : b[k] = a[k] - 1 : a = [2, 2, 1] -&gt; b = [2, 1]</span>
    b.append<span class="br0">&#40;</span>a<span class="br0">&#91;</span>k<span class="br0">&#93;</span>-<span style="color: #cc66cc;">1</span><span class="br0">&#41;</span>
&nbsp;
    <span style="color: #808080;"># En notant N+1 = b[k]*q + r la division euclidienne de N+1 par b[k] </span>
    <span style="color: #808080;"># On obtient le quotient q et le reste r de cette division.</span>
    q = <span class="br0">&#40;</span>N+<span style="color: #cc66cc;">1</span><span class="br0">&#41;</span> // b<span class="br0">&#91;</span>k<span class="br0">&#93;</span> ; r = <span class="br0">&#40;</span>N+<span style="color: #cc66cc;">1</span><span class="br0">&#41;</span> % b<span class="br0">&#91;</span>k<span class="br0">&#93;</span>
&nbsp;
    <span style="color: #808080;"># On &eacute;value ensuite les entiers b[j] = b[k] pour k &lt; j &lt; k + q + 1 : a = [2, 2, 1] -&gt; b = [2, 1] + 2*[1] = [2, 1, 1, 1]</span>
    b = b + q*<span class="br0">&#91;</span>b<span class="br0">&#91;</span>k<span class="br0">&#93;</span><span class="br0">&#93;</span>
&nbsp;
    <span style="color: #808080;"># Si le reste r est non nul.</span>
    <span style="color: #0000ff;">if</span> r!=<span style="color: #cc66cc;">0</span>: <span style="color: #808080;"># ou : if r:</span>
        <span style="color: #808080;"># On ajoute l'entier r &agrave; la liste b : b[k+q+1] = r</span>
        b.append<span class="br0">&#40;</span>r<span class="br0">&#41;</span>
&nbsp;
    <span style="color: #808080;"># calcul des valeurs de k et N pour la nouvelle partition b</span>
    <span style="color: #0000ff;">while</span> <span class="br0">&#40;</span>b<span class="br0">&#91;</span>k<span class="br0">&#93;</span>!=<span style="color: #cc66cc;">1</span><span class="br0">&#41;</span>:
        k+=<span style="color: #cc66cc;">1</span>
        <span style="color: #0000ff;">if</span> k==len<span class="br0">&#40;</span>b<span class="br0">&#41;</span>:
            <span style="color: #0000ff;">break</span>
&nbsp;
    <span style="color: #808080;"># renvoi de la partition b suivant la partition a, du rang k dans b, et du nombre N d'entiers valant 1 dans b</span>
    <span style="color: #0000ff;">return</span> <span class="br0">&#40;</span>b, k-<span style="color: #cc66cc;">1</span>, len<span class="br0">&#40;</span>b<span class="br0">&#41;</span> - k<span class="br0">&#41;</span>
&nbsp;
&nbsp;
<span style="color: #0000ff;">def</span> generer_partitions<span class="br0">&#40;</span>n<span class="br0">&#41;</span>:
    <span style="color: #808080;"># Fonction principale permettant de g&eacute;n&eacute;rer la liste des partitions de l'entier n.</span>
    <span style="color: #808080;"># Partitions dont les termes sont rang&eacute;s dans l'ordre d&eacute;croissant : [[5], [4, 1], [3, 2], ..., [1, 1, 1, 1, 1,]]</span>
&nbsp;
    <span style="color: #808080;"># 1re partition de la liste</span>
    p = <span class="br0">&#91;</span>n<span class="br0">&#93;</span>
&nbsp;
    <span style="color: #808080;"># initialisation de la liste avec la 1re partition [n]</span>
    partitions = <span class="br0">&#91;</span>p<span class="br0">&#93;</span>
&nbsp;
    <span style="color: #808080;"># initialisation des variables k et N</span>
    <span style="color: #808080;"># k : rang du dernier entier de [n] strictement sup&eacute;rieur &agrave; 1</span>
    <span style="color: #808080;"># N : nombre d'entiers qui valent 1 dans [n]</span>
&nbsp;
    <span style="color: #808080;"># k=-1 et N=1 si n=1, sinon k=0 et N=0</span>
    <span class="br0">&#40;</span>k, N<span class="br0">&#41;</span> = <span class="br0">&#40;</span>-<span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">1</span><span class="br0">&#41;</span> <span style="color: #0000ff;">if</span> n==<span style="color: #cc66cc;">1</span> <span style="color: #0000ff;">else</span> <span class="br0">&#40;</span><span style="color: #cc66cc;">0</span>, <span style="color: #cc66cc;">0</span><span class="br0">&#41;</span>
&nbsp;
    <span style="color: #808080;"># Tant que k est sup&eacute;rieur ou &eacute;gal &agrave; 0 : si k=-1 on sort de la boucle</span>
    <span style="color: #0000ff;">while</span> k&gt;=<span style="color: #cc66cc;">0</span>:
&nbsp;
        <span style="color: #808080;"># appel de la fonction renvoyant la partition suivant p, avec les param&egrave;tres k et N</span>
        p, k, N = partition_suivante<span class="br0">&#40;</span>p, k, N<span class="br0">&#41;</span>
&nbsp;
        <span style="color: #808080;"># ajout de la nouvelle partition &agrave; la liste</span>
        partitions.append<span class="br0">&#40;</span>p<span class="br0">&#41;</span>
&nbsp;
    <span style="color: #808080;"># renvoi de la liste des partitions : [5], [4,1], [3,2], ..., [1, 1, 1, 1, 1,]]</span>
    <span style="color: #0000ff;">return</span> partitions
&nbsp;
&nbsp;
<span style="color: #0000ff;">def</span> generateur_partitions<span class="br0">&#40;</span>n<span class="br0">&#41;</span>:
    <span style="color: #808080;"># Fonction g&eacute;n&eacute;ratrice permettant de parcourir les partitions de l'entier n. </span>
    <span style="color: #808080;"># Partitions dont les termes sont rang&eacute;s dans l'ordre d&eacute;croissant : [[5], [4, 1], [3, 2], ..., [1, 1, 1, 1, 1,]]</span>
&nbsp;
    <span style="color: #808080;"># 1re partition de la liste</span>
    p = <span class="br0">&#91;</span>n<span class="br0">&#93;</span>
&nbsp;
    <span style="color: #808080;"># renvoi de la 1re partition</span>
    <span style="color: #0000ff;">yield</span> p
&nbsp;
    <span style="color: #808080;"># initialisation des variables k et N</span>
    <span style="color: #808080;"># k : rang du dernier entier de [n] strictement sup&eacute;rieur &agrave; 1</span>
    <span style="color: #808080;"># N : nombre d'entiers qui valent 1 dans [n]</span>
&nbsp;
    <span style="color: #808080;"># k=-1 et N=1 si n=1, sinon k=0 et N=0</span>
    <span class="br0">&#40;</span>k, N<span class="br0">&#41;</span> = <span class="br0">&#40;</span>-<span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">1</span><span class="br0">&#41;</span> <span style="color: #0000ff;">if</span> n==<span style="color: #cc66cc;">1</span> <span style="color: #0000ff;">else</span> <span class="br0">&#40;</span><span style="color: #cc66cc;">0</span>, <span style="color: #cc66cc;">0</span><span class="br0">&#41;</span>
&nbsp;
    <span style="color: #808080;"># Tant que k est sup&eacute;rieur ou &eacute;gal &agrave; 0 : si k=-1 on sort de la boucle.</span>
    <span style="color: #0000ff;">while</span> k&gt;=<span style="color: #cc66cc;">0</span>:
&nbsp;
        <span style="color: #808080;"># appel de la fonction renvoyant la partition qui suit p, avec les param&egrave;tres k et N</span>
        p, k, N = partition_suivante<span class="br0">&#40;</span>p, k, N<span class="br0">&#41;</span>
&nbsp;
        <span style="color: #808080;"># renvoi de la nouvelle partition p</span>
        <span style="color: #0000ff;">yield</span> p
&nbsp;
&nbsp;
<span style="color: #808080;"># Nombre entier dont on souhaite g&eacute;n&eacute;rer les partitions.</span>
n = <span style="color: #cc66cc;">5</span>
&nbsp;
<span style="color: #808080;"># Affiche le nombre entier.</span>
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Partitions de &quot;</span> + str<span class="br0">&#40;</span>n<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;G&eacute;n&eacute;ration des partitions de l'entier..<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;I. Version n&deg;1 : m&eacute;thode classique<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># version n&deg;1 : g&eacute;n&egrave;re la liste des partitions de l'entier n</span>
partitions = generer_partitions<span class="br0">&#40;</span>n<span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Liste des partitions de n :<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># Affiche les partitions une &agrave; une.</span>
<span style="color: #0000ff;">for</span> partition <span style="color: #0000ff;">in</span> partitions:
    <span style="color: #0000ff;">print</span><span class="br0">&#40;</span>tuple<span class="br0">&#40;</span>partition<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;II. Version n&deg;2 : fonction g&eacute;n&eacute;ratrice avec yield<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># version n&deg;2 : cr&eacute;e le g&eacute;n&eacute;rateur permettant de parcourir la liste des partitions de l'entier de d&eacute;part</span>
gen_partitions = generateur_partitions<span class="br0">&#40;</span>n<span class="br0">&#41;</span>
&nbsp;
<span style="color: #0000ff;">print</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Liste des partitions de n :<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># Affiche les partitions une &agrave; une.</span>
<span style="color: #0000ff;">for</span> partition <span style="color: #0000ff;">in</span> gen_partitions:
    <span style="color: #0000ff;">print</span><span class="br0">&#40;</span>tuple<span class="br0">&#40;</span>partition<span class="br0">&#41;</span><span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
<br />
<b>IV. Conclusion</b><br />
<br />
Après avoir décrit l'algorithme permettant d'obtenir les partitions d'un entier, on a donc pu générer en Python la liste des partitions d'un entier quelconque.<br />
<br />
Enfin, on a créé une fonction génératrice à partir de ce code, pour éviter les problèmes de mémoire insuffisante.<br />
<br />
<br />
<b>Sources :</b><br />
<br />
<a href="https://fr.wikipedia.org/wiki/Partition_d%27un_entier" target="_blank">https://fr.wikipedia.org/wiki/Partition_d%27un_entier</a><br />
<a href="https://fr.wikiversity.org/wiki/Algorithmique/Forme_d%27%C3%A9criture#Forme_it%C3%A9rative" target="_blank">https://fr.wikiversity.org/wiki/Algo...it%C3%A9rative</a><br />
<a href="https://gayerie.dev/docs/python/python3/iterateur_generateur.html#les-generateurs" target="_blank">https://gayerie.dev/docs/python/pyth...es-generateurs</a></font></blockquote>

]]></content:encoded>
			<dc:creator>User</dc:creator>
			<guid isPermaLink="true">https://www.developpez.net/forums/blogs/44027-user/b10544/mathematiques-python-generer-partitions-d-entier/</guid>
		</item>
		<item>
			<title><![CDATA[Python : générer les partitions d'un ensemble]]></title>
			<link>https://www.developpez.net/forums/blogs/44027-user/b10537/python-generer-partitions-d-ensemble/</link>
			<pubDate>Wed, 18 Oct 2023 11:03:52 GMT</pubDate>
			<description>*I. Introduction* 
 
Après...</description>
			<content:encoded><![CDATA[<blockquote class="blogcontent restore"><font size="3"><b>I. Introduction</b><br />
<br />
Après les <a href="https://fr.wikipedia.org/wiki/Ensemble_des_parties_d%27un_ensemble" target="_blank">parties d'un ensemble</a>, on s'intéresse maintenant aux <a href="https://fr.wikipedia.org/wiki/Partition_d%27un_ensemble" target="_blank">partitions d'un ensemble</a> :<br />
<br />
L'objectif sera donc cette fois de créer une fonction Python qui pourra générer la liste des partitions d'un ensemble d'éléments.<br />
<br />
On va également créer une fonction génératrice qui va permettre d'obtenir les partitions sans avoir besoin de les stocker dans une liste.<br />
<br />
<br />
<b>II. Partitions d'un ensemble</b><br />
<br />
<br />
<b>II-A. Définition mathématique</b><br />
<br />
En mathématiques, une <a href="https://fr.wikipedia.org/wiki/Partition_d%27un_ensemble" target="_blank">partition d'un ensemble</a> <b><i>E</i></b> est un ensemble de parties non vides de <b><i>E</i></b> deux à deux disjointes et dont l'union est <b><i>E</i></b>. <br />
<br />
Soit par exemple <b><i>E</i></b> un ensemble de <b>3</b> éléments :<br />
<br />
<span class="highlight"><i>E</i> = {1, 2, 3}</span><br />
<br />
L'ensemble <b><i>E</i></b> a les partitions suivantes :<br />
<br />
<ul><li style="">{{1}, {2}, {3}} ;</li><li style="">{{1, 3}, {2}} ;</li><li style="">{{1}, {2, 3}} ;</li><li style="">{{1, 2}, {3}} ;</li><li style="">{{1, 2, 3}}.</li></ul><br />
On remarque que :<br />
<br />
<ul><li style="">{&#8709;, {1, 3}, {2}} n'est pas une partition parce qu'elle contient l'ensemble vide &#8709; ou {} ;</li><li style="">{{1, 2}, {2, 3}} n'est pas une partition parce que l'élément 2 appartient à plus d'une partie ;</li><li style="">{{1}, {2}} n'est pas une partition de {1, 2, 3} car l'union de tous les éléments est {1, 2} ; c'est une partition de {1, 2}.</li></ul><br />
<br />
Le nombre de partitions d'un ensemble à <b>n</b> éléments en exactement <b>k</b> sous-ensembles est le <a href="https://fr.wikipedia.org/wiki/Nombre_de_Stirling#Nombre_de_Stirling_de_seconde_esp%C3%A8ce" target="_blank">nombre de Stirling de seconde espèce</a> noté <b>S(n, k)</b>. <br />
<br />
Le nombre total de partitions de cet ensemble est égal au <a href="https://fr.wikipedia.org/wiki/Nombre_de_Bell" target="_blank">nombre de Bell</a> : <br />
<br />
<img src="https://www.developpez.net/forums/attachments/p645315d1697443183/parkings/restreint-parking-admin/version-2-nouveau-gabarit-dynamique-vos-articles/nombre_bell.png/" border="0" alt="Nom : nombre_bell.png
Affichages : 18194
Taille : 1,8 Ko"  style="float: CONFIG" /><br />
<br />
Ces nombres forment une suite d'entiers dont on peut calculer les premiers termes :<br />
<br />
<span class="highlight"><i>B</i><sub>0</sub> = 1, <i>B</i><sub>1</sub> = 1, <i>B</i><sub>2</sub> = 2,<br />
<i>B</i><sub>3</sub> = 5, <i>B</i><sub>4</sub> = 15, <i>B</i><sub>5</sub> = 52,<br />
<i>B</i><sub>6</sub> = 203, <i>B</i><sub>7</sub> = 877, ...</span><br />
<br />
<br />
<b>II-B. Génération des partitions d'un ensemble</b><br />
<br />
Reprenons notre ensemble {1, 2, 3}.<br />
<br />
On part de l'ensemble vide <span class="highlight"><i>E</i><sub>0</sub> = {}</span>.<br />
<br />
La partition de l'ensemble vide est la partition vide {}.<br />
<br />
Puis, on va chercher à obtenir successivement les listes de partitions des ensembles à 1, 2 et 3 éléments :<br />
<br />
<br />
<b>1.</b> Partition de l'ensemble <span class="highlight"><i>E</i><sub>1</sub> = {1}</span> :<br />
<br />
<ul><li style="">{{1}} : ajout de {1} à l'ensemble vide {}.</li></ul><br />
<br />
<br />
<b>2.</b> Liste des partitions <b><i>P</i><sub>2</sub></b> de l'ensemble <span class="highlight"><i>E</i><sub>2</sub> = {1, 2}</span> :<br />
<br />
<ul><li style="">{{1}, {2}} : ajout de {2} à la partition {{1}} ;</li><li style="">{{1, 2}} : ajout de 2 à {1} pour former le sous-ensemble {1, 2}.</li></ul><br />
<br />
<br />
<b>3.</b> Liste des partitions <b><i>P</i><sub>3</sub></b> de l'ensemble <span class="highlight"><i>E</i><sub>3</sub> = {1, 2, 3}</span>.<br />
<br />
On ajoute {3} à la partition {{1}, {2}} et on distribue <b>3</b> sur les sous-ensembles de la partition :<br />
<br />
<ul><li style="">{{1}, {2}, {3}} : ajout de {3} à l'ensemble {{1}, {2}} ;</li><li style="">{{1, 3}, {2}} : ajout de 3 à {1} pour former le sous-ensemble {1, 3} ;</li><li style="">{{1}, {2, 3}} : ajout de 3 à {2} pour former le sous-ensemble {2, 3} ;</li></ul><br />
<br />
On ajoute {3} à la partition {{1, 2}} et 3 au sous-ensemble {1, 2} :<br />
<br />
<ul><li style="">{{1, 2}, {3}} : ajout de {3} à l'ensemble {{1, 2}} ;</li><li style="">{{1, 2, 3}} : ajout de 3 au sous-ensemble {1, 2} pour former le sous-ensemble {1, 2, 3}.</li></ul><br />
<br />
<br />
Dans le cas général, on distribue donc à chaque étape le nouvel élément <b>e<sub>n+1</sub></b> sur les partitions de la liste <b><i>P</i><sub>n</sub></b>, et sur leurs sous-ensembles pour former la nouvelle liste de partitions <b><i>P</i><sub>n+1</sub></b>.<br />
<br />
On peut donc écrire la relation :<br />
<br />
<span class="highlight"><i>P</i><sub>n+1</sub> = distribuer_element(<i>P</i><sub>n</sub>, e<sub>n+1</sub>)</span><br />
<br />
avec :<br />
<br />
<span class="highlight"><i>P</i><sub>0</sub> = {}</span><br />
<br />
<br />
L'objectif est alors de déterminer la fonction <span class="highlight">distribuer_element</span> qui relie <b><i>P</i><sub>n</sub></b> à <b><i>P</i><sub>n+1</sub></b>.<br />
<br />
<br />
<br />
<b>III. Implémentation en Python</b><br />
<br />
<br />
<b>III-A. Génération de la liste des partitions d'un ensemble</b><br />
<br />
On crée tout d'abord la fonction permettant de passer d'une liste de partitions d'un ensemble à <b>n</b> éléments, à une liste de partitions d'un ensemble à <b>n+1</b> éléments :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">def</span> distribuer_element_v1<span class="br0">&#40;</span>partitions, element<span class="br0">&#41;</span>:
    <span style="color: #808080;"># fonction permettant de distribuer l'&eacute;l&eacute;ment sur les partitions et leurs sous-ensembles pour former les nouvelles partitions :</span>
    <span style="color: #808080;"># {{e1}, {e2}} -&gt; {{e1}, {e2}, {e3}} ; {{e1, e3}, {e2}} ; {{e1}, {e2, e3}} ; etc.</span>
&nbsp;
    <span style="color: #808080;"># initialisation de la nouvelle liste de partitions</span>
    parts=<span class="br0">&#91;</span><span class="br0">&#93;</span>
&nbsp;
    <span style="color: #808080;"># parcours de la liste des partitions pass&eacute;e en argument</span>
    <span style="color: #0000ff;">for</span> partition <span style="color: #0000ff;">in</span> partitions:
        <span style="color: #808080;"># ajout d'une nouvelle partition constitu&eacute;e de la partition d'origine &agrave; laquelle on ajoute l'&eacute;l&eacute;ment : {{e1}, {e2}} -&gt; {{e1}, {e2}, {e3}}</span>
        parts += <span class="br0">&#91;</span>partition + <span class="br0">&#91;</span><span class="br0">&#91;</span>element<span class="br0">&#93;</span><span class="br0">&#93;</span><span class="br0">&#93;</span>
        <span style="color: #808080;"># parcours des sous-ensembles des partitions (subset)</span>
        <span style="color: #0000ff;">for</span> i, subset <span style="color: #0000ff;">in</span> enumerate<span class="br0">&#40;</span>partition<span class="br0">&#41;</span>:
            <span style="color: #808080;"># ajout d'une partition constitu&eacute;e du sous-ensemble subset auquel on ajoute l'&eacute;l&eacute;ment : {{e1}, {e2}} -&gt; {{e1, e3}, {e2}}</span>
            parts += <span class="br0">&#91;</span>partition<span class="br0">&#91;</span>:i<span class="br0">&#93;</span> + <span class="br0">&#91;</span>subset + <span class="br0">&#91;</span>element<span class="br0">&#93;</span><span class="br0">&#93;</span> + partition<span class="br0">&#91;</span>i+<span style="color: #cc66cc;">1</span>:<span class="br0">&#93;</span><span class="br0">&#93;</span>
&nbsp;
    <span style="color: #808080;"># renvoie la liste des partitions r&eacute;sultat de la distribution de l'&eacute;l&eacute;ment sur les partitions et leurs sous-ensembles</span>
    <span style="color: #0000ff;">return</span> parts</pre></td></tr></table></pre>
</div><br />
<br />
Enfin, on crée la fonction principale permettant de générer les partitions d'une ensemble donné :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:192px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">def</span> generer_partitions<span class="br0">&#40;</span>elements<span class="br0">&#41;</span>:
    <span style="color: #808080;"># version n&deg;1 : g&eacute;n&egrave;re la liste des partitions de l'ensemble de d&eacute;part repr&eacute;sent&eacute; par la liste elements</span>
&nbsp;
    <span style="color: #808080;"># initialisation de la liste des partitions</span>
    partitions = <span class="br0">&#91;</span><span class="br0">&#91;</span><span class="br0">&#93;</span><span class="br0">&#93;</span>
&nbsp;
    <span style="color: #808080;"># parcours des &eacute;l&eacute;ments de la liste pass&eacute;e en argument</span>
    <span style="color: #0000ff;">for</span> ei <span style="color: #0000ff;">in</span> elements:
        <span style="color: #808080;"># g&eacute;n&eacute;ration des partitions de l'ensemble Ei = {e1, e2, ..., ei} </span>
        partitions = distribuer_element_v1<span class="br0">&#40;</span>partitions, ei<span class="br0">&#41;</span>
&nbsp;
    <span style="color: #808080;"># renvoie la liste des partitions de l'ensemble de d&eacute;part repr&eacute;sent&eacute; par elements</span>
    <span style="color: #0000ff;">return</span> partitions</pre></td></tr></table></pre>
</div><br />
Testons maintenant la fonction :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:144px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="26"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #808080;"># cr&eacute;ation de la liste des &eacute;l&eacute;ments de l'ensemble de d&eacute;part E = {1, 2, 3}</span>
elements = <span class="br0">&#91;</span><span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">2</span>, <span style="color: #cc66cc;">3</span><span class="br0">&#93;</span>
&nbsp;
<span style="color: #808080;"># version n&deg;1 : g&eacute;n&egrave;re la liste des partitions de l'ensemble repr&eacute;sent&eacute; par la liste elements</span>
partitions = generer_partitions<span class="br0">&#40;</span>elements<span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche les partitions une &agrave; une</span>
<span style="color: #0000ff;">for</span> partition <span style="color: #0000ff;">in</span> partitions:
    <span style="color: #0000ff;">print</span><span class="br0">&#40;</span>format_ensemble<span class="br0">&#40;</span>partition<span class="br0">&#41;</span><span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
Le code affiche :<br />
<br />
<span class="highlight"><font color="#000080">{1, 2, 3}<br />
{{1, 3}, {2}}<br />
{{1}, {2, 3}}<br />
{{1, 2}, {3}}<br />
{{1, 2, 3}}<br />
</font></span><br />
<br />
<br />
<b>III-B. Fonction génératrice avec yield</b><br />
<br />
Comme on a pu le constater précédemment, si la taille <b>n</b> de l'ensemble de départ augmente, le nombre de partitions générées (nombre de Bell <b><i>B</i><sub>n</sub></b>) peut très vite devenir important, ce qui risque d'entrainer des problèmes de mémoire insuffisante (MemoryError). <br />
<br />
Pour éviter ces débordements, on peut utiliser à la place une <a href="https://gayerie.dev/docs/python/python3/iterateur_generateur.html#les-fonctions-generatrices-avec-yield" target="_blank">fonction génératrice</a> qui va créer à la demande l'élément suivant de la séquence sans avoir besoin de le stocker en mémoire dans une liste ou une autre structure de données.<br />
<br />
Pour cela, Python dispose du mot-clé <i>yield</i> qui permet de transformer une fonction en générateur :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:180px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">def</span> distribuer_element_v2<span class="br0">&#40;</span>gen_partitions, element<span class="br0">&#41;</span>:
    <span style="color: #808080;"># fonction g&eacute;n&eacute;ratrice permettant de distribuer l'&eacute;l&eacute;ment sur les partitions et leurs sous-ensembles pour former les nouvelles partitions :</span>
    <span style="color: #808080;"># {{e1}, {e2}} -&gt; {{e1}, {e2}, {e3}} ; {{e1, e3}, {e2}} ; {{e1}, {e2, e3}} ; etc.</span>
&nbsp;
    <span style="color: #808080;"># parcours des partitions une &agrave; une</span>
    <span style="color: #0000ff;">for</span> partition <span style="color: #0000ff;">in</span> gen_partitions:
        <span style="color: #808080;"># ajout d'une nouvelle partition constitu&eacute;e de la partition d'origine &agrave; laquelle on ajoute l'&eacute;l&eacute;ment : {{e1}, {e2}} -&gt; {{e1}, {e2}, {e3}}</span>
        <span style="color: #0000ff;">yield</span> partition + <span class="br0">&#91;</span><span class="br0">&#91;</span>element<span class="br0">&#93;</span><span class="br0">&#93;</span>
        <span style="color: #808080;"># parcours des sous-ensembles des partitions (subset)</span>
        <span style="color: #0000ff;">for</span> i, subset <span style="color: #0000ff;">in</span> enumerate<span class="br0">&#40;</span>partition<span class="br0">&#41;</span>:
            <span style="color: #808080;"># ajout d'une partition constitu&eacute;e du sous-ensemble subset auquel on ajoute l'&eacute;l&eacute;ment : {{e1}, {e2}} -&gt; {{e1, e3}, {e2}}</span>
            <span style="color: #0000ff;">yield</span> partition<span class="br0">&#91;</span>:i<span class="br0">&#93;</span> + <span class="br0">&#91;</span>subset + <span class="br0">&#91;</span>element<span class="br0">&#93;</span><span class="br0">&#93;</span> + partition<span class="br0">&#91;</span>i+<span style="color: #cc66cc;">1</span>:<span class="br0">&#93;</span></pre></td></tr></table></pre>
</div><br />
<br />
La fonction principale devient :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:192px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">def</span> generateur_partitions<span class="br0">&#40;</span>elements<span class="br0">&#41;</span>:
    <span style="color: #808080;"># version n&deg;2 : cr&eacute;e un g&eacute;n&eacute;rateur permettant de parcourir les partitions une &agrave; une</span>
&nbsp;
    <span style="color: #808080;"># initialisation de la variable gen_partitions : [] -&gt; {}</span>
    gen_partitions = iter<span class="br0">&#40;</span><span class="br0">&#91;</span><span class="br0">&#91;</span><span class="br0">&#93;</span><span class="br0">&#93;</span><span class="br0">&#41;</span>
&nbsp;
    <span style="color: #808080;"># parcours des &eacute;l&eacute;ments de la liste pass&eacute;e en argument</span>
    <span style="color: #0000ff;">for</span> ei <span style="color: #0000ff;">in</span> elements:
        <span style="color: #808080;"># cr&eacute;ation du g&eacute;n&eacute;rateur permettant de parcourir les partitions de l'ensemble Ei = {e1, e2, ..., ei}</span>
        gen_partitions = distribuer_element_v2<span class="br0">&#40;</span>gen_partitions, ei<span class="br0">&#41;</span>
&nbsp;
    <span style="color: #808080;"># renvoie le g&eacute;n&eacute;rateur permettant de parcourir les partitions une &agrave; une</span>
    <span style="color: #0000ff;">return</span> gen_partitions</pre></td></tr></table></pre>
</div><br />
Testons maintenant la fonction :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:144px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="26"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #808080;"># cr&eacute;ation de la liste des &eacute;l&eacute;ments de l'ensemble de d&eacute;part E = {1, 2, 3}}</span>
elements = <span class="br0">&#91;</span><span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">2</span>, <span style="color: #cc66cc;">3</span><span class="br0">&#93;</span>
&nbsp;
<span style="color: #808080;"># version n&deg;2 : cr&eacute;e le g&eacute;n&eacute;rateur permettant de parcourir la liste des partitions de l'ensemble de d&eacute;part</span>
gen_partitions = generateur_partitions<span class="br0">&#40;</span>elements<span class="br0">&#41;</span>
&nbsp;
<span style="color: #808080;"># affiche les partitions une &agrave; une</span>
<span style="color: #0000ff;">for</span> partition <span style="color: #0000ff;">in</span> gen_partitions:
    <span style="color: #0000ff;">print</span><span class="br0">&#40;</span>format_ensemble<span class="br0">&#40;</span>partition<span class="br0">&#41;</span><span class="br0">&#41;</span></pre></td></tr></table></pre>
</div><br />
Le code affiche :<br />
<br />
<span class="highlight"><font color="#000080">{1, 2, 3}<br />
{{1, 3}, {2}}<br />
{{1}, {2, 3}}<br />
{{1, 2}, {3}}<br />
{{1, 2, 3}}<br />
</font></span><br />
<br />
<br />
<b>III-C. Module complet</b><br />
<br />
On donne enfin le code complet du module pour effectuer les tests :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code Python :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="40"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br />50<br />51<br />52<br />53<br />54<br />55<br />56<br />57<br />58<br />59<br />60<br />61<br />62<br />63<br />64<br />65<br />66<br />67<br />68<br />69<br />70<br />71<br />72<br />73<br />74<br />75<br />76<br />77<br />78<br />79<br />80<br />81<br />82<br />83<br />84<br />85<br />86<br />87<br />88<br />89<br />90<br />91<br />92<br />93<br />94<br />95<br />96<br />97<br />98<br />99<br />100<br />101<br />102<br />103<br />104<br />105<br />106<br />107<br />108<br />109<br />110<br />111<br />112<br />113<br />114<br />115<br />116<br />117<br />118<br />119<br />120<br />121<br />122<br />123<br />124<br />125<br />126<br />127<br />128<br />129<br />130<br />131<br />132<br />133<br />134<br />135<br />136<br />137<br />138<br />139<br />140<br />141<br />142<br />143<br />144<br />145<br />146<br /></div></td><td valign="top"><pre style="margin: 0">def distribuer_element_v1(partitions, element):
    # fonction permettant de distribuer l'élément sur les partitions et leurs sous-ensembles pour former les nouvelles partitions :
    # {{e1}, {e2}} -&gt; {{e1}, {e2}, {e3}} ; {{e1, e3}, {e2}} ; {{e1}, {e2, e3}} ; etc.
 
    # initialisation de la nouvelle liste de partitions
    parts=[]
 
    # parcours de la liste des partitions passée en argument
    for partition in partitions:
        # ajout d'une nouvelle partition constituée de la partition d'origine à laquelle on ajoute l'élément : {{e1}, {e2}} -&gt; {{e1}, {e2}, {e3}}
        parts += [partition + [[element]]]
        # parcours des sous-ensembles des partitions (subset)
        for i, subset in enumerate(partition):
            # ajout d'une partition constituée du sous-ensemble subset auquel on ajoute l'élément : {{e1}, {e2}} -&gt; {{e1, e3}, {e2}}
            parts += [partition[:i] + [subset + [element]] + partition[i+1:]]
 
    # renvoie la liste des partitions résultat de la distribution de l'élément sur les partitions et leurs sous-ensembles
    return parts
 
 
def generer_partitions(elements):
    # version n°1 : génère la liste des partitions de l'ensemble de départ représenté par la liste elements
 
    # initialisation de la liste des partitions
    partitions = [[]]
 
    # parcours des éléments de la liste passée en argument
    for ei in elements:
        # génération des partitions de l'ensemble Ei = {e1, e2, ..., ei} 
        partitions = distribuer_element_v1(partitions, ei)
 
    # renvoie la liste des partitions de l'ensemble de départ représenté par elements
    return partitions
 
 
#---------------------------------------------------------------
#------------------- fonction génératrice ----------------------
#---------------------------------------------------------------
 
 
def distribuer_element_v2(gen_partitions, element):
    # fonction génératrice permettant de distribuer l'élément sur les partitions et leurs sous-ensembles pour former les nouvelles partitions :
    # {{e1}, {e2}} -&gt; {{e1}, {e2}, {e3}} ; {{e1, e3}, {e2}} ; {{e1}, {e2, e3}} ; etc.
 
    # parcours des partitions une à une
    for partition in gen_partitions:
        # ajout d'une nouvelle partition constituée de la partition d'origine à laquelle on ajoute l'élément : {{e1}, {e2}} -&gt; {{e1}, {e2}, {e3}}
        yield partition + [[element]]
        # parcours des sous-ensembles des partitions (subset)
        for i, subset in enumerate(partition):
            # ajout d'une partition constituée du sous-ensemble subset auquel on ajoute l'élément : {{e1}, {e2}} -&gt; {{e1, e3}, {e2}}
            yield partition[:i] + [subset + [element]] + partition[i+1:]
 
 
def generateur_partitions(elements):
    # version n°2 : crée un générateur permettant de parcourir les partitions une à une
 
    # initialisation de la variable gen_partitions : [] -&gt; {}
    gen_partitions = iter([[]])
 
    # parcours des éléments de la liste passée en argument
    for ei in elements:
        # création du générateur permettant de parcourir les partitions de l'ensemble Ei = {e1, e2, ..., ei}
        gen_partitions = distribuer_element_v2(gen_partitions, ei)
 
    # renvoie le générateur permettant de parcourir les partitions une à une
    return gen_partitions
 
 
#---------------------------------------------------------------
#--------------------- fonction récursive ----------------------
#---------------------------------------------------------------
 
 
def generateur_partitions_recur(elements):
    # fonction récursive : crée un générateur permettant de parcourir les partitions une à une
    # source : https://stackoverflow.com/questions/65845727/time-complexity-of-finding-all-partitions-of-a-set
 
    # si la liste contient 1 élément
    if len(elements) == 1:
        yield [elements]
        return # sortie de la fonction
 
    #1er élément de la liste
    element = elements[0]
 
    # parcours des partitions une à une
    for partition in generateur_partitions_recur(elements[1:]):
 
         # parcours des sous-ensembles des partitions (subset)
        for i, subset in enumerate(partition):
            # ajout d'une partition constituée du sous-ensemble subset auquel on ajoute l'élément : {{e1}, {e2}} -&gt; {{e1, e3}, {e2}}
            yield partition[:i] + [[element] + subset] + partition[i+1:]
 
        # ajout d'une nouvelle partition constituée de la partition d'origine à laquelle on ajoute l'élément : {{e1}, {e2}} -&gt; {{e1}, {e2}, {e3}}
        yield [[element]] + partition
 
 
def format_ensemble(elements):
    # convertit une liste d'éléments en une chaîne représentant un emsemble :
    # ['a', ['b', 'c']] -&gt; {a, {b, c}}
 
    # remplace les crochets par des accolades
    s = str(elements).replace(&quot;[&quot;,&quot;{&quot;).replace(&quot;]&quot;,&quot;}&quot;)
 
    # supprime les apostrophes
    s = s.replace(&quot;'&quot;,&quot;&quot;)
 
    # renvoie la chaîne de caractère représentant l'ensemble : {a, {b, c}}
    return s
 
 
print(&quot;Enemble de départ :\n&quot;)
 
# création de la liste des éléments de l'ensemble de départ E = {1, 2, 3}
elements = [1, 2, 3]
 
# affiche l'ensemble E = {1, 2, 3}
print(&quot;E = &quot; + format_ensemble(elements))
print()

print(&quot;Génération des partitions de l'ensemble..\n&quot;)

print(&quot;I. Version n°1 : méthode classique\n&quot;)
 
# version n°1 : génère la liste des partitions de l'ensemble représenté par la liste elements
partitions = generer_partitions(elements)

print(&quot;Liste des partitions de l'ensemble :\n&quot;)
 
# affiche les partitions une à une
for partition in partitions:
    print(format_ensemble(partition))

print()

print(&quot;II. Version n°2 : fonction génératrice avec yield\n&quot;)
 
# version n°2 : crée le générateur permettant de parcourir la liste des partitions de l'ensemble de départ
gen_partitions = generateur_partitions(elements)
 
print(&quot;Liste des partitions de l'ensemble :\n&quot;)
 
# affiche les partitions une à une
for partition in gen_partitions:
    print(format_ensemble(partition))</pre></td></tr></table></pre>
</div><br />
Il contient également la version récursive de la fonction génératrice.<br />
<br />
<br />
<br />
<b>IV. Conclusion</b><br />
<br />
Après avoir montré comment obtenir successivement les partitions d'un ensemble à 1, 2, ..., n éléments, on a donc pu générer en Python la liste des partitions d'un ensemble quelconque.<br />
<br />
Enfin, on a créer une fonction génératrice à partir de ce code, pour éviter les problèmes de mémoire insuffisante.<br />
<br />
<br />
<b>Sources :</b><br />
<br />
<a href="https://fr.wikipedia.org/wiki/Partition_d%27un_ensemble" target="_blank">https://fr.wikipedia.org/wiki/Partition_d%27un_ensemble</a><br />
<a href="https://fr.wikipedia.org/wiki/Ensemble" target="_blank">https://fr.wikipedia.org/wiki/Ensemble</a><br />
<a href="https://fr.wikipedia.org/wiki/Nombre_de_Bell" target="_blank">https://fr.wikipedia.org/wiki/Nombre_de_Bell</a><br />
<a href="https://fr.wikipedia.org/wiki/Nombre_de_Stirling" target="_blank">https://fr.wikipedia.org/wiki/Nombre_de_Stirling</a><br />
<a href="https://gayerie.dev/docs/python/python3/iterateur_generateur.html#les-generateurs" target="_blank">https://gayerie.dev/docs/python/pyth...es-generateurs</a></font></blockquote>

]]></content:encoded>
			<dc:creator>User</dc:creator>
			<guid isPermaLink="true">https://www.developpez.net/forums/blogs/44027-user/b10537/python-generer-partitions-d-ensemble/</guid>
		</item>
	</channel>
</rss>
