J-0
00m
00j
00h
00min
00s

Version interactive avec LaTeX compilé

CCINP Informatique Commune TSI 2018

Notez ce sujet en cliquant sur l'étoile
0.0(0 votes)
Logo ccinp
2025_08_29_6410dba0e79d4689fc82g

CONCOURS COMMUNS

POLYTECHNIQUES

ÉPREUVE SPÉCIFIQUE - FILIÈRE TSI

INFORMATIQUE

Jeudi 3 mai : -

Abstract

N.B. : le candidat attachera la plus grande importance à la clarté, à la précision et à la concision de la rédaction. Si un candidat est amené à repérer ce qui peut lui sembler être une erreur d'énoncé, il le signalera sur sa copie et devra poursuivre sa composition en expliquant les raisons des initiatives qu'il a été amené à prendre.

Les calculatrices sont interdites

Le sujet est composé de 6 parties qui peuvent être traitées indépendamment. Il est néanmoins recommandé de les aborder dans l'ordre.
Le sujet comporte :
  • le texte du sujet, 13 pages,
  • l'annexe, 3 pages,
  • le document-réponse à rendre, 12 pages.
Dans tout le sujet, on considérera à chaque étape que les fonctions définies lors des questions précédentes sont utilisables pour la suite du sujet.
Vous devez répondre directement sur le document réponse, soit à l'emplacement prévu pour la réponse lorsque celle-ci implique une rédaction, soit en complétant les différents programmes en langage Python. Si vous manquez de place dans les cadres prévus, vous pouvez compléter sur la dernière page en précisant la question.

OPTIMISATION D'UN CORRECTEUR P.I.D. PAR UN ALGORITHME GENETIQUE

Partie I - Problématique

La correction d'un système asservi linéaire, en vue de répondre aux exigences de précision, rapidité et d'oscillations, n'est jamais aisée et est souvent réalisée à partir de méthodes pratiques plus ou moins empiriques.
Le correcteur Proportionnel, Dérivateur, Intégrateur (P.I.D.) est fréquemment employé afin d'améliorer le comportement des systèmes asservis. On se propose de mettre en œuvre une procédure d'optimisation du correcteur P.I.D. basée sur les algorithmes génétiques.

I. 1 - Présentation du problème

On considère le système asservi à retour unitaire décrit par le schéma-bloc ci-dessous :
  • on note la variable de Laplace, les grandeurs seront notées en minuscule dans le domaine temporel et en majuscule dans le domaine de Laplace tel que ;
  • le correcteur est un correcteur P.I.D. (parfait) de fonction de transfert ;
  • le système à réguler est connu par sa fonction de transfert et sont deux polynômes avec . On pose :
  • ,
  • .
Afin de déterminer la réponse temporelle du système corrigé, nous avons besoin de définir la fonction de transfert en boucle ouverte , puis la fonction de transfert en boucle fermée .
On rappelle que dans le cadre d'un système asservi à retour unitaire, on a :
On a alors
et la réponse temporelle s'obtient en recherchant la transformée inverse de Laplace de .
Pour réaliser cette étude, nous allons utiliser la librairie scipy.signal qui permet, à partir de la fonction de transfert d'un système :
  • d'obtenir la réponse temporelle à un échelon unitaire;
  • d'obtenir les racines d'un polynôme.
L'annexe A. 1 des pages 14 et 15, montre un exemple d'utilisation et précise les quelques commandes utiles de cette librairie dans le cadre de ce sujet.

I. 2 - Système à réguler

Le système que nous allons étudier est décrit par la fonction de transfert :
On note numG et denG les listes associées au numérateur et au dénominateur de la fonction de transfert .
Q1. À l'aide de l'annexe A.1, page 14 et de l'expression de , compléter les lignes 1 et 3 du listing de la page DR 1 du document réponse.
Afin d'optimiser la réponse temporelle on réalise un asservissement. Le schéma-bloc ci-dessous représente cet asservissement.
Pour ce premier essai, on considère . La réponse temporelle à un échelon unitaire de ce système est tracée sur la figure 1.
On constate que la réponse temporelle du système asservi (figure 1) présente à la fois un défaut de précision (la valeur de consigne n'est pas atteinte), un temps de réponse d'environ , des oscillations et un premier dépassement relativement important.
Il semble nécessaire de choisir un correcteur qui améliore notablement la réponse du système.
Figure 1 - Réponse temporelle à un échelon unitaire du système corrigé avec

Partie II - Correction du système

II. 1 - Définition du correcteur P.I.D.

On installe dans le système un correcteur P.I.D. :
Le système devient :
Q2. Mettre le correcteur sous la forme avec et deux polynômes à définir. Puis, sur le listing page DR 1, écrire la fonction correcteur(Kp,Ti,Td) qui renvoie les listes numC et denC associées au numérateur et au dénominateur du correcteur P.I.D.
Le numérateur et le dénominateur du correcteur seront nommés respectivement numC et denC pour la suite.

II. 2 - Détermination des fonctions de transfert en boucle ouverte et en boucle fermée

La détermination de la fonction de transfert en boucle ouverte et de la fonction de transfert en boucle fermée nécessite de développer deux fonctions : une fonction qui réalise le produit de deux polynômes et une autre qui en fait la somme.
Soit la fonction multi_listes( ) (listing page ) qui prend comme argument deux listes et .
Q3. Décrire l'exécution de la fonction multi_listes( ) lorsque les deux listes sont et en précisant sur le document réponse page dans le cadre correspondant à cette question, le contenu des variables suivantes :
  • de la liste Q1 avant la boucle for;
  • de la liste R pour et ;
  • de la liste R à la fin de l'exécution.
Que fait la fonction multi_listes( )?
Afin que le résultat du produit des deux listes corresponde au produit de deux polynômes, tels qu'ils sont définis par la librairie scipy.signal, il est nécessaire de ranger les termes de ce résultat dans l'ordre inverse.
Pour la suite, chaque fois qu'une liste sera l'image d'un polynôme, on considérera que les coefficients sont rangés dans l'ordre décroissant des puissances de (voir la définition de la fonction lti () en annexe A.1).
Q4. Écrire la fonction inverse(liste) qui prend comme argument une liste liste et renvoie une liste liste_r en inversant les coefficients sur le listing page DR 2 dans le cadre correspondant à cette question.
Soient et deux fonctions de transfert avec et des polynômes en . On cherche à déterminer .
On note num1, num2, den1, den2 les quatre listes représentant les polynômes et .
Q5. Écrire la fonction multi_FT(num1,den1,num2,den2) du listing page DR dans le cadre correspondant à cette question qui prend comme argument quatre listes représentant les polynômes du numérateur et du dénominateur de deux fonctions de transfert et renvoie deux listes représentant le produit de ces deux fonctions de transfert rangées comme des polynômes. Pour cela, vous utiliserez les deux fonctions multi_listes( ) et inverse(liste).
Il reste à déterminer la fonction qui réalise la somme de deux polynômes.
Q6. Écrire la fonction somme_poly(P,Q) qui prend en argument deux listes représentant les coefficients de deux polynômes et renvoie une liste des coefficients de la somme des deux polynômes. Ces deux polynômes sont de dimensions différentes.

II. 3 - Tracé de la réponse temporelle

Finalement, pour obtenir la réponse temporelle, il est nécessaire de compléter les fonctions définies précédemment par deux fonctions :
  • FTBF(num,den), fonction qui renvoie le numérateur et le dénominateur de la fonction de transfert en boucle fermée
  • rep_Temp(Kp,Ti,Td), fonction qui permet d'obtenir les deux listes (le temps) et l'amplitude de la sortie pour un échelon unitaire.
Figure 2 - Tracé de la réponse temporelle corrigée
Ces deux fonctions sont définies cidessous.
Le listing du programme de la page 6 montre une utilisation de ces fonctions permettant de tracer la réponse temporelle pour un échelon unitaire en prenant comme paramètres du correcteur , et . La figure représente le tracé de la réponse temporelle correspondante.
Sur cette figure, on retrouve la consigne d'entrée en trait pointillé, la sortie corrigée en trait fort et les deux limites à autour de la valeur finale en tracés fins.

Définition des fonctions FTBF() et rep_Temp()

def FTBF(num,den) :
    num_bf=num
    den_bf=somme_poly(num,den)
    return num_bf,den_bf
def rep_Temp(Kp,Ti,Td) :
    numC,denC=correcteur(Kp,Ti,Td)
    num_BO,den_BO=multi_FT(numG,denG,numC,denC)
    num_BF,den_BF=FTBF(num_BO,den_BO)
    BF=Iti(num_BF, den_BF)
    temps, sortie = step(BF)
    temps, sortie = step(BF, T = linspace(min(temps), temps[-1], 500))
    return temps,sortie

Programme de tracé de la réponse temporelle

numG $=[\ldots .$.
denG $=[\ldots \ldots \ldots . . \ldots . . \ldots . .$.$] \#Question 1$
\#définition du correcteur (valeurs quelconques)
$\mathrm{Kp}, \mathrm{Ti}, \mathrm{Td}=5,1.1,0.218$
t,s= rep_Temp(Kp,Ti,Td)
plt.plot(t[:60], s[:60])
plt.title('Réponse temporelle à un échelon')
plt.xlabel('Temps (s)')
plt.ylabel('Amplitude')
plt.hlines( $1, \min (\mathrm{t}), \mathrm{t}[60]$, colors='r')
plt.hlines(0.95, min(t), t[60], colors='g')
plt.hlines(1.05, min(t), t[60], colors='g')
plt.hlines( $0, \min (\mathrm{t}), \mathrm{t}[60]$ )
plt.grid()
plt.show()

Partie III - Détermination des critères d'optimisation

III. 1 - Réglage optimal pratique

Dans le cas qui nous intéresse, la présence d'une intégration garantit que l'erreur indicielle sera nulle à la condition que le système reste stable. Une méthode de réglage pratique (méthode de compensation des pôles) a permis de déterminer les valeurs suivantes pour le correcteur : , , .
Le tracé (figure 3) montre une réponse temporelle qui semble optimisée.
Figure 3 - Réponse temporelle optimisée obtenue par la méthode de compensation des pôles
L'objet de l'étude qui suit est de déterminer un réglage du correcteur P.I.D. qui améliore encore la réponse temporelle.

III. 2 - Stabilité

Avant de définir les différents critères d'optimisation de la réponse temporelle, il est nécessaire de vérifier que la réponse temporelle est convergente. La réponse est convergente si le système est stable. On rappelle la définition de la stabilité : une fonction de transfert est stable si toutes les racines du dénominateur (les pôles) sont à parties réelles strictement négatives.
On cherche donc à vérifier que la fonction de transfert obtenue est stable et ce, pour différentes valeurs de et .
Q7. Écrire la fonction stabilite(P) qui prend comme argument une liste représentant un polynôme et renvoie la valeur binaire True si la fonction de transfert, dont le dénominateur est , est stable et False dans l'autre cas. Vous utiliserez les fonctions roots(...) et real(...) de la librairie numpy (voir l'annexe A.2, page 15).

III. 3 - Critères usuels d'optimisation

Les critères usuels de réglage et d'optimisation d'un système asservi généralement retenus sont le temps de réponse à 'amplitude des dépassements et une erreur indicielle nulle. On tente souvent d'avoir une réponse temporelle analogue à la réponse d'un système du second ordre avec un temps de réponse minimal et un dépassement limité à .
On rappelle ici les définitions :
Temps de réponse à : le temps de réponse à est le temps mis par le système pour que la réponse temporelle atteigne la valeur finale à près;
Dépassement relatif : le dépassement relatif est défini par avec la valeur maximale de la fonction et la valeur finale en régime permanent.
Q8. Justifier que la fonction Temps_reponse(s,t) (listing page DR 4) qui prend comme argument deux listes, la réponse temporelle et le temps, renvoie une valeur approchée majorant le temps de réponse à .
Q9. Proposer une ré-écriture de la fonction Temps_reponse(s,t) en utilisant une seule boucle while à la place de la boucle for et du test.
Q10. Écrire la fonction depassement(s,t) qui prend en argument les listes et et qui renvoie le dépassement relatif.

III. 4 - Critère de la valeur absolue de l'intégrale de l'erreur

À ces critères, on peut en rajouter un qui va caractériser la réponse transitoire : il s'agit de l'intégrale de la valeur absolue de l'erreur (IAE) :
avec la réponse temporelle de la sortie, la consigne d'entrée et .
Ce critère permet d'évaluer l'aire de la surface entre la courbe de réponse et la consigne d'entrée (figure 4).
Figure 4 - Critère de la valeur absolue de l'erreur
Q11. Écrire la fonction critere_IAE(s,t) qui prend comme argument les listes et et qui renvoie l'intégrale de la valeur absolue de l'erreur. Vous préciserez la méthode utilisée.

III. 5 - Fonction coût

Si on applique ces trois critères à la fonction réglée par la méthode de compensation des pôles (figure 3) avec et , on obtient respectivement pour les critères de temps de réponse ( ), de dépassement relatif ( ) et d'écart (I AE) :
Ces trois critères sont ceux que notre algorithme doit permettre d'améliorer. On définit ainsi une fonction ponderation_cout(T5,D1,IAE) (listing page DR 5) qui renvoie le «coût» global associé à ces critères. Le réglage optimal du correcteur doit alors permettre de minimiser cette fonction.
Q12. Dans quel intervalle doit être la valeur retournée par ponderation_cout(T5,D1,IAE) afin que la configuration soit meilleure que la réponse de référence?
Nous allons chercher le meilleur triplet ( ) qui minimise la fonction coût.
Les domaines de définition de et sont :
  • ,
  • ,
  • .
Afin de limiter l'étude, nous considérerons que chacune des trois variables ne peut prendre que valeurs réparties uniformément dans l'intervalle de définition :
La fonction calcul_coef_correcteur(Ip,Ii,Id) renvoie les coefficients du correcteur et .
Q13. Compléter la fonction calcul_coef_correcteur(Ip,Ii,Id) qui détermine les coefficients du correcteur à partir des trois valeurs entières et . Estimer le nombre de combinaisons possibles pour le correcteur.
La fonction calcul_cout(Ip,Ii,Id) doit permettre, pour une combinaison des trois valeurs (Ip,Ii,Id) dans leur domaine de définition, de déterminer le coût de la combinaison. Pour cela, il faut :
  • déterminer les coefficients du correcteur P.I.D.;
  • déterminer le numérateur et le dénominateur de la fonction de transfert en boucle ouverte;
  • déterminer le numérateur et le dénominateur de la fonction de transfert en boucle fermée;
  • si la fonction de transfert en boucle fermée :
  • est stable, alors déterminer le temps de réponse, le dépassement et le critère IAE;
  • n'est pas stable, alors prendre pour le coût une valeur supérieure aux valeurs possibles (ici coût ).
    Finalement, la fonction doit renvoyer le coût.
Rappel des fonctions précédemment définies à utiliser :
stabilite , Temps_reponse(s,t), critere_IAE(s,t),
rep_Temp(Kp,Ti,Td), depassement(s,t), ponderation_cout(T5,D1,IAE).
Q14. Compléter la fonction calcul_cout(Ip,Ii,Id) en utilisant les fonctions précédemment définies.
Q15. Sachant que le temps de calcul de la fonction calcul_cout(Ip,Ii,Id) pour une combinaison est de , est-il envisageable de les tester toutes?
Pour la suite, nous utiliserons la fonction calcul_cout(Ip,Ii,Id) qui, à partir des trois valeurs entières et renvoie le coût de la combinaison. C'est cette quantité que nous chercherons à minimiser dans la partie suivante.

Partie IV - Résolution par un algorithme génétique

IV. 1 - Principe

Les algorithmes génétiques sont des processus d'optimisation itératifs évolutionnistes. Ils permettent d'approcher la solution d'un problème d'optimisation (ici de recherche d'un minimum) en reproduisant des mécanismes de «sélection naturelle». Le principe, décrit figure 5, consiste à initialiser un groupe de candidats possibles dont on va sélectionner les meilleurs éléments. Ces derniers sont conservés et croisés pour obtenir de nouveaux candidats. Ainsi, à chaque génération, la population se conserve et les caractéristiques du groupe s'améliorent jusqu'à converger vers un optimum.
Figure 5 - Principe d'un algorithme génétique
Nous nous intéressons ici au programme, présenté dans son ensemble dans l'annexe A.3, page 16, qui doit permettre de trouver une combinaison des paramètres et qui présente un optimum vis-à-vis de la minimisation de la fonction calcul_cout(Ip,Ii,Id) définie dans la partie précédente.
Nous utiliserons une population de 100 candidats. À chaque génération, seuls les 20 meilleurs sont sélectionnés et croisés de façon à générer 80 nouveaux candidats et conserver une population de 100 candidats. Afin d'éviter de converger trop rapidement vers un minimum local, les nouveaux candidats subissent une mutation aléatoire pour apporter de la diversité génétique.
Ce cycle est répété jusqu'à ce qu'un critère d'arrêt vienne l'interrompre. Pour le moment nous supposerons que 50 cycles permettent d'obtenir une bonne convergence. Le meilleur individu de la dernière génération servira alors pour le réglage des paramètres et .

IV. 2 - Initialisation des candidats

Chaque candidat possède trois gènes correspondant à chacun des paramètres et qui peuvent prendre valeurs distinctes (voir les équations (1), (2) et (3) page 8). Pour faciliter la manipulation des gènes et leurs croisements, ceux-ci sont codés sous la forme d'une chaîne de 16 caractères ' ' ou '1' correspondant à un nombre binaire.
Q16. Définir le rôle de la fonction genererGene(n) et le type du paramètre gen2 renvoyé. Quelle valeur de faut-il alors employer pour créer un gène?
Chaque candidat est pourvu de 3 gènes stockés sous la forme d'une liste Candidat de 3 chaînes de 16 caractères, par exemple :
Q17. Compléter la fonction generer_liste_initiale(n) de façon à générer une liste CandidatS de 100 candidats aléatoires sur le listing page DR 7.
Par ailleurs, pour employer la fonction calcul_cout(Ip,Ii,Id) définie page 8, il est nécessaire de traduire la valeur décimale associée au gène codé en binaire à l'aide d'une fonction décodage(). Soit un gène b2 codé sur n caractères binaires, la commande float(b2[0]) renvoie la valeur du bit de poids le plus faible (le premier) et float(b2[n-1]) renvoie la valeur du bit de poids le plus fort (le n-ième).
Q18. Calculer le nombre décimal associé à .
Q19. Compléter la fonction decodage(b2) qui prend en argument une chaîne de caractère b2 et qui renvoie le nombre décimal b10 associé.

IV. 3 - Tri et sélection des candidats

Parmi les candidats triés dans l'ordre croissant de leur performance, ne sont sélectionnés et stockés que les 20 meilleurs candidats dans la liste CandidatS_top (listing page DR 8). Cette liste doit permettre d'une part de stocker ces candidats dans une base de données et d'autre part de constituer et générer la génération suivante.
Q20. Quel est l'algorithme de tri utilisé dans la fonction tri(L) du listing page DR 8 pour trier contenant les candidats? Donner sa complexité dans le meilleur et le pire des cas.

IV. 4 - Croisement des candidats

La fonction croisement(P1,P2) doit permettre de générer deux nouveaux individus à partir de deux parents et . Les gènes des deux parents sont découpés, croisés et recombinés 2 à 2 de façon à générer deux nouveaux gènes.
Chacun des trois gènes des deux parents est donc découpé en trois morceaux (figure 6). La partie centrale allant du au bit est échangée de façon à créer les gènes de deux enfants. Ainsi, le couple de parents (P1, P2) ci-dessous génère, avant mutation, les deux enfants (E1, E2) :
Figure 6 - Principe du croisement
Q21. Compléter le listing de sorte que la fonction croisement(P1,P2) renvoie les deux enfants E1, E2 issus de deux parents P1, P2.
Avant d'être intégré à la nouvelle génération et afin de limiter le risque d'apparition de clone, chaque enfant subit une mutation sur l'un de ces gènes.
Q22. Pour Candidat=['1111111111111111','0000000000000000','1111111100000000'], donner ce que renvoie la commande mutation(Candidat,1,12) du listing page DR 9.
L'étape de croisement des 20 meilleurs candidats, qui sont conservés, doit permettre de générer 80 nouveaux candidats de façon à revenir à une population de 100 individus :
  1. 20 sont issus de 10 croisements du meilleur des 20 meilleurs candidats avec un des 19 autres candidats (première boucle for du listing page DR 9);
  2. 60 sont issus du croisement de 30 couples aléatoirement formés des 20 meilleurs candidats excepté le meilleur (deuxième boucle for du listing page DR 9).
    Q23. Compléter la fonction nouvGeneration(L) du listing page DR 9 de façon à traduire le point 2) ci-dessus.
Il est malgré tout possible que des clones apparaissent à chaque génération, d'autant plus que les candidats risquent de se ressembler au fur et à mesure des itérations. Pour éviter ce problème, on utilise une fonction doublons() qui repère les clones et qui les remplace par un candidat tiré aléatoirement.
Q24. Créer la fonction doublons(L) du listing page DR 10 qui prend en argument une liste de candidats et qui renvoie cette même liste débarrassée de ses clones et les remplace par un candidat tiré aléatoirement.

Partie V - Historique des candidats

Dans l'objectif d'étudier les paramètres qui permettent d'accélérer l'algorithme, nous décidons de stocker tous les meilleurs candidats de chaque itération dans une base de données. L'objectif est de déterminer un critère d'arrêt plus efficace que celui défini au-dessus.
La base de données est ainsi constituée d'une table Historique (tableau 1) qui permet de stocker les meilleurs candidats au fil des itérations. En plus de l'Id et des trois paramètres flottants et , elle permet de stocker trois autres attributs : score, apparition et disparition (tableau 1).
Historique
Id
gene_Kp
gene_Ti
gene_Td
score
apparition
disparition
Tableau 1 - Table Historique
L'attribut score est un flottant correspondant au résultat de la fonction coût du candidat. Les attributs apparition et disparition sont des entiers et correspondent respectivement au numéro de l'itération où le candidat est apparu et au numéro de celle où il a disparu. On se basera ici sur l'extrait de cette base de données fourni tableau 2.
Q25. Définir le but et le résultat de la requête SQL suivante :
SELECT min(score) FROM Historique.
Q26. Donner la requête SQL qui permet d'obtenir la longévité du meilleur candidat. Donner le résultat de cette requête et conclure sur la possibilité de stopper l'algorithme génétique avant la itération.
Q27. Définir le but et le résultat de la requête SQL suivante :
SELECT Id FROM Historique WHERE apparition AND disparition.
Q28. Donner la requête SQL qui renvoie la valeur moyenne des gènes et Td à la itération.

Partie VI - En conclusion

Figure 7 - Tracés comparés de la réponse temporelle déterminée par l'algorithme génétique et la réponse déterminée expérimentalement par la méthode de compensation des pôles
On retrouve sur la figure 7 le tracé de la réponse «pratique» pour laquelle les coefficients du correcteur P.I.D. ont été déterminés expérimentalement et le tracé de la réponse temporelle correspondant à la meilleure réponse de l'algorithme génétique ( ).
Q29. Conclure sur l'opportunité d'utiliser un algorithme génétique.
Id gene_Kp gene_Ti gene_Td score apparition disparition
1 65.0542311742 25.9980929274 8.0804150454 1.1465868477 0 2
2 94.0221130694 21.8343222705 12.8343633173 1.47592141334 0 0
3 62.1003799496 12.9620883497 13.1906614786 1.53111188552 0 0
4 63.3377628748 5.39437033646 0.718699931334 1.66453693499 0 0
5 86.7534419776 39.6642320897 7.62493324178 1.76681066691 0 0
6 68.0126596475 2.17198718242 1.37788967727 0.720574832859 1 5
7 49.5983877317 6.71109224079 9.67421988251 1.23600614063 1 2
8 44.8868729686 7.2237441062 10.4859998474 1.24050982879 1 1
9 81.7001593042 29.2158988327 7.68596932937 1.24876332573 1 1
10 65.0542311742 25.9980929274 8.07431143664 1.16317640581 2 2
11 46.4492405585 7.2237441062 10.4921034562 1.24017983164 2 2
12 62.9593769741 4.02729869535 1.43892576486 0.750913688522 3 5
13 68.2079555962 2.17198718242 1.37788967727 0.774983006043 3 4
... ... ... ... ...
43 65.1686623941 0.417375143053 1.37865262837 0.621608931066 10 10
44 65.1808683909 0.411272144656 1.37865262837 0.620980646341 11 11
45 65.1808683909 0.412797894255 1.37865262837 0.621000002184 11 11
46 65.2296923781 0.402117647059 1.37865262837 0.618622779634 12 16
47 65.2296923781 0.42652964065 1.37865262837 0.618936823201 12 13
48 65.1869713893 0.414323643854 1.37865262837 0.620742325779 12 12
49 65.1823941405 0.402117647059 1.37865262837 0.620793058622 12 12
50 65.2357953765 0.414323643854 1.37865262837 0.618499911309 13 18
51 65.2296923781 0.414323643854 1.37865262837 0.618782759248 13 13
52 65.1884971389 0.408220645457 1.37865262837 0.620595007049 13 13
53 65.2327438773 0.414323643854 1.37865262837 0.618641425052 14 15
54 65.2296923781 0.408220645457 1.37865262837 0.618703560070 14 14
55 65.2312181277 0.414323643854 1.37865262837 0.618712114622 14 14
56 65.2342696269 0.414323643854 1.37865262837 0.618570690595 15 16
57 65.2312181277 0.408220645457 1.37865262837 0.61863287033 15 15
58 65.2357953765 0.406694895857 1.37865262837 0.618400625578 16 18
59 65.2373211261 0.414323643854 1.37865262837 0.618429087253 16 18
60 65.2373211261 0.402117647059 1.37865262837 0.618268651270 17 49
61 65.2373211261 0.406694895857 1.37865262837 0.618329745253 17 20
62 65.2373211261 0.405169146258 1.37865262837 0.618309616353 19 49
63 65.2357953765 0.402117647059 1.37865262837 0.61833956633 19 20
64 65.2373211261 0.408220645457 1.37865262837 0.618349663168 19 20
65 65.2373211261 0.400591897459 1.37865262837 0.618248479198 21 49
66 65.2373211261 0.403643396658 1.37865262837 0.618289307302 21 49
67 65.2357953765 0.400591897459 1.37865262837 0.618319406010 21 49
Tableau 2 - Historique partiel des meilleurs candidats

FIN

ANNEXE

A. 1 Librairie scipy.signal

Le code ci-dessous illustre l'utilisation de cette librairie pour tracer la réponse temporelle d'un système du second ordre :
Exemple d'utilisation de la librairie scipy.signal
from numpy import min, max,zeros
from scipy import linspace
from scipy.signal import lti, step, bode
from matplotlib import pyplot as plt
z=0.3
wn=10
K=1.3
d0=1
d1=2*z/wn
d2=1/wn**2
#Numérateur
num = [K]
#Dénominateur
den = [d2, d1, d0]
# Fonction de transfert
G = lti(num, den) #déclaration de la fonction de transfert
t, s = step(G)
# Ici, on appelle de nouveau la fonction afin de préciser
# le nombre de points à afficher
t, s = step(G, T = linspace(min(t), t[-1], 1000))
#Affichage
plt.plot(t, s)
plt.title('Réponseபtemporelle')
plt.xlabel('Temps(s)')
plt.ylabel('Amplitude')
plt.hlines(1, min(t), max(t), colors='r') #tracé de l'échelon unitaire
plt.hlines(0, min(t), max(t))
plt.xlim(xmax = max(t))
plt.legend(('Réponseபtemporelle }\mp@subsup{}{\mp@code{a}|un\sqcupéchelon',), loc=0)}{
plt.grid()
plt.show()
Nous utiliserons dans ce sujet les deux fonctions définies sur la page suivante.
lti(num,den) : cette fonction (ligne 16 au-dessus) permet de définir la fonction de transfert, elle prend comme argument deux listes, l'une comportant les coefficients du numérateur, l'autre comportant les coefficients du dénominateur (lignes 12 et 14 ).
Les coefficients des deux listes sont rangés dans l'ordre décroissant.
Si les polynômes du numérateur et du dénominateur sont notés :
alors les deux listes représentant les polynômes utilisables par la fonction lti (num,den) sont notées :
Figure 8 - Exemple d'utilisation de la librairie scipy.signal
: cette fonction de la librairie scipy.signal renvoie deux listes, le temps et la réponse temporelle pour une entrée en échelon unitaire de la fonction de transfert . Si la fonction est appelée sans préciser la durée de simulation et le nombre de points, ceux-ci sont déterminés automatiquement par la librairie. Il est d'usage de l'appeler deux fois, la première sans paramètres pour laisser la librairie calculer le temps de simulation, puis une deuxième fois en reprenant le temps calculé et en imposant le nombre de points. La représentation temporelle est tracée sur la figure 8 .

A. 2 Librairie numpy

(liste), (liste) : ces deux fonctions qui prennent une liste comme argument, retournent respectivement le minimum et le maximum d'une liste.
roots( ) : cette fonction qui prend comme argument une liste dont les termes sont les coefficients d'un polynôme, renvoie une liste dont les termes sont les racines du polynômes.
$p=[1,-3,-2,-1]$ \# le polynôme $P(x)=x^{\wedge} 3-3 x^{\wedge} 2-2 x-1$
racines=roots (p)
print (racines)
Le script affiche :
real(Q) : fonction dont l'argument est une liste et qui renvoie une liste constituée de la partie réelle de chaque terme de la liste passée en argument.
print (real (racines))
Le script affiche : [3.62736508, -0.31368254, -0.31368254]
: retourne une liste de termes nuls.

A. 3 Programme d'optimisation génétique

Cette annexe présente la structure générale du programme d'optimisation génétique et les différentes fonctions que vous aurez à commenter ou à définir. Ce programme doit permettre de trouver un optimum à la fonction calcul_cout(Ip,Ii,Id) à l'aide d'algorithme génétique.
Programme d'optimisation par algorithme génétique
#-_-_-_-_-_-_Paramètres globaux-_------------
n=
cycle=50
#
def genererGene(n):
    # Détermination d'un gène
    return gen2
def generer_liste_initiale(n):
    # Génération de la liste initiale
        return liste_initiale
def decodage(b2):
    return b10
def perf(Li): # Li est la liste des attributs d'un candidat
    # Détermination de la perfomance d'une combinaison
    return calcul_cout(Ip,Ii,Id)
def tri(L): # L est la liste de tous les candidats
    # Tri croissant des différents candidats selon la performance
    return L
def croisement(P1,P2):
    # Fonction réalisant le croisement génétique
    return
def mutation (E,i,j):
    # Fonction réalisant une mutation
    return E
def nouvGeneration(L): # L la liste actuelle des candidats
    # Fonction déterminant la nouvelle génération
    return L_new
def doublons(L):
    # Fonction chargée d'éliminer les doublons
# Finalement le programme principal
CandidatS=Generer_liste_initiale(n)
for i in range(cycle):
    CandidatS_top=tri(CandidatS)[0:20]
    CandidatS=nouvGeneration ( CandidatS_top)
    CandidatS=doublons( CandidatS)
solution=CandidatS [0]
Note:
Appréciation du correcteur* :
20
  • Uniquement s'il s'agit d'un examen.
DOCUMENT RÉPONSE
TSIIN07
Pour l'ensemble du sujet, les bibliothèques usuelles sont chargées avec la syntaxe suivante :

Librairies

from numpy import min, max, zeros, roots, real
from scipy import linspace
from scipy.signal import lti, step
from matplotlib import pyplot as plt
from random import random

Question 1

numG
denG
numG,

Question 2






def correcteur(Kp,Ti,Td) :
...

...

7
8
9
10
11
12
return num,den
numC,denC=correcteur(Kp,Ti,Td) # appel de la fonction, numC et denC les deux listes de coefficients.

Question 3

def multi_listes :
deg_max=
P1=zeros(deg_max+1)
Q1=zeros(deg_max+1)
#P1 et Q1 deux listes de zéros de dimension deg_max+1
for in range :
P1[j]=P[j]
for in range(len(Q))
Q1[j]=Q[j]
R=zeros(deg_max+1)
for in range(deg_max+1)
for i in range :

return
Q1=
( et ) :


Que fait multi_listes?:

Question 4

def inverse(liste) :
...
...
...
...
...
...
...
...
...
...
return liste_r

Question 5

def multi_FT(num1,den1,num2,den2)
2 ...
3 ...
...
...
...
...
...
...
...
...
...
...
return
Question 6
def somme_poly( ) :
2 ...
...
...
...
...
...
...
...

...

...


return somme

Question 7

def stabilite :
2 ...
3 ...
...

...
...
"..
...
...
...
...

...
return ...

Question 8

def Temps_reponse(s,t)

s_fin
for tt in range(len(s)) :

if fin and fin or fin and fin
T5
break
return T5






Question 9

def Temps_reponse(s,t)









return T5

Question 10

def depassement(s,t)






...

return D1

Question 11

def critere_IAE(s,t)
...
...
...
...
.
...
...
return IAE







Question 12


D10=0.05
IAE0
def ponderation_cout(T5,D1,IAE)
k1=1
k2
k3
cout
return cout






Question 13

def calcul_coef_correcteur(Ip,Ii,Id)
...
...
...
...
...
...
...
...
...
return







Question 14

def calcul_cout(Ip,Ii,Id)
Kp,Ti,Td=coef_correcteur(lp,li,ld)
numC,denC=correcteur(Kp,Ti,Td)
num_BO, den_BO=multi_FT(numG,denG,numC,denC)
num_BF,den_BF=FTBF(num_BO,den_BO)
stable=.
...
"..




...
...







return cout

Question 15








Question 16


def genererGene( n )
b2
for in range
b2 int random( ))
return b2






Question 17

def generer_liste_initiale(n)
CandidatS=[]
for in .
Candidat=
CandidatS.append(Candidat)
return CandidatS

Question 18







Question 19

def decodage(b2)
b10=0
for...
return b10

Programme principal

cycle
#-Main
CandidatS=Generer_liste_initiale(n)
for i in range(cycle)
CandidatS_top=tri(CandidatS)[0:20]
CandidatS=nouvGeneration(CandidatS_top)
CandidatS=doublons(CandidatS)
solution=CandidatS[0]

Question 20

def perf(Li) : # Li est la liste des attributs d'un candidat
Ip,li,Id=decodage(Li[0]),decodage(Li[1]),decodage(Li[2])
return calcul_cout(lp,li,ld)
def tri(L) : # L est la liste de tous les candidats
for in range(1,len(L)) :
if perf(

while and :

X=L.pop(i)
L.insert(p,X)
return

Question 21

def croisement(P1,P2) :
E2=[]

return ...

Question 22

def mutation(E,i,j) :
if
は - 1 1 = =

else

return E




Question 23

def nouvGeneration(L) : # L la liste actuelle des candidats
L_new=L
for i in range(10) :
E1,E2=croisement(L[0],L[int(random()*19)+1])
L_new.append(mutation(E1,int(random()*3),int(random()*16)))
L_new.append(mutation(E2,int(random()*3),int(random()*16)))
for in
..
...
...
...
...
return L_new

Question 24

def doublons ...

Cadre réponse pour les questions 25 à 29

Préciser le numéro de la question, séparer les réponses.
























Cadre réponse pour les questions 25 à 29 (suite)

Préciser le numéro de la question, séparer les réponses.





































Cadre réponse libre

Préciser le numéro de la question, séparer les réponses.





































CCINP Informatique Commune TSI 2018 - Version Web LaTeX | WikiPrépa | WikiPrépa