TP ALGORITHMIQUE EN SAGE 1. Complexité et tris Exercice 1. On

publicité
M1
TP ALGORITHMIQUE EN SAGE
CHRISTOPHE RITZENTHALER
1. Complexité et tris
Exercice 1. On propose le programme SAGE suivant de recherche d’un maximal dans
une liste d’entiers.
def plus_grand_element(liste):
resultat = liste[0]
for i in range(1, len(liste)):
if liste[i] > resultat:
resultat = liste[i]
return resultat
(1) Implémenter le.
(2) À l’aide des fonctions ZZ.random_element(), créer des listes aléatoires de longueur
croissante et donner le temps pour le calcul de la fonction avec cputime().
(3) Automatiser la procédure précédente et tracer le graphe du temps dans le pire des
cas (en prenant le maximum pour 5 tirages à longueur donnée) pour des longueurs
entre 104 et 106 (avec un pas de 104 ). On pourra avoir besoin de list_plot() et
de stocker des éléments dans une liste avec la fonction append.
(4) Qu’en pensez-vous ?
Exercice 2.
(1) Implémenter le tri rapide avec l’implémentation ci-dessous
def quicksort(aList):
theList = aList
if len(theList)==1:
return theList
else:
early = []
late = []
pivot=floor(random()*len(theList))
pivotValue=theList[pivot]
del theList[pivot]
for j in [0..len(theList)-1]:
if theList[j]<pivotValue:
early.append(theList[j])
else:
late.append(theList[j])
if len(early)>=1:
sortEarly = quicksort(early)
else:
sortEarly = []
if len(late)>=1:
sortLate = quicksort(late)
1
else:
sortLate = []
sortEarly.append(pivotValue)
for j in [0..len(sortLate)-1]:
sortEarly.append(sortLate[j])
return sortEarly
(2) Comparer le temps de cette méthode avec l’implémentation où le pivot est choisi
à la dernière place (le dernier élément d’une liste a l’indice −1). On fera les tests
sur des listes aléatoires puis sur des listes triées de longueur 100 à 1000 avec un
pas de 10. Pour afficher deux graphes p1 et p2 superposés, on utilisera la fonction
show(p1+p2).
Exercice 3.
(1) Implémenter le tri par sélection et par insertion.
(2) Comparer les temps de ces méthodes sur des listes de longueur croissante avec le
temps du tri rapide. On pourra automatiser les tests comme précédemment.
2
2. Graphes
Sage possède des fonctions pour gérer les graphes, comme suit
• Initialiser un graphe orienté (resp. non orienté) vide avec le constructeur DiGraph()
(resp. Graph()).
• Ajouter les sommets avec la commande add_vertex ou add_vertices
• Ajouter les arcs (resp. arêtes) avec la commande add_edge ou add_edges.
Pour connaitre les fonctions implémentés sur les graphes, il suffit d’entrer le nom d’une
instance de graphe (par exemple ici on a initialisé G=Graph()), suivi du point ’.’ et faire
tab pour que s’affiche la liste des 257 fonctions prédéfinies dans la librairie. Par exemple
la fonction G.topological_sort() retourne une liste topologique si le graphe est sans
circuit.
Exercice 4. On rappelle que la matrice d’incidence d’un graphe orienté G = (S, A) est
la matrice ∆ tel que δxa = 1 si x est l’origine de l’arc a, −1 si x est l’extrémité de l’arc a
et 0 sinon.
(1) Construire et afficher le graphe

0 1
0 0

0 0

0 0

0 0
0 1
0 0
du TD donné par la matrice d’adjacence

0 0 0 1 0
1 1 0 0 0

0 0 0 0 0

0 0 1 0 0

0 0 0 0 1
0 0 1 0 1
1 0 0 0 0
On souhaite automatiser le passage de la matrice d’adjacence à la matrice d’incidence.
(2) Comment lit-on le nombre d’arêtes sur la matrice d’adjacence ?
(3) Donner un algorithme qui calcule la matrice d’adjacence à partir de la matrice
d’incidence. Quel est son coût ?
(4) Donner un algorithme qui calcule la matrice d’incidence à partir de la matrice
d’adjacence. Quel est son coût ?
On pourra utiliser les fonctions G.adjacency_matrix() ou G.incidence_matrix() déjà
implémentées pour obtenir des exemples à partir d’un graphe aléatoire donné par la
fonction digraphs.RandomDirectedGNM(10,20) (ici à 10 sommets et 20 arcs). On aura
besoin des fonctions Matrix(n,n), nrows(), augment() et delete_columns().
(5) On cherche maintenant à passer du graphe à la matrice d’adjacence. On utilisera
pour cela les fonctions neighbors_out(), stack() et delete_rows().
Soit n le nombre de sommets de G.
(6) Montrer que pour tout 1 ≤ k ≤ n, le coefficient (i,j), noté mkij , de la matrice M k
est égal au nombre de chemins de longueur k du sommet i au sommet j.
(7) Essayer sur un exemple. Comparer avec la fonction adjacency_matrix().
Exercice 5. Implémenter les algorithmes de Roy-Warshall et Floyd.
Exercice 6. Quelle est la taille du plus grand sous-ensemble S ⊂ {1, . . . , 100} qui ne
contient pas i, j tel que |i − j| soit un carré parfait ? Une fois le problème modélisé par un
graphe, on pourra utiliser la fonction independent_set() qui retourne un sous-ensemble
maximum d’éléments deux à deux non adjacents.
3
3. Multiplication rapide
Exercice 7. Implémenter la méthode de Karatsuba.
Exercice 8. On cherche à implémenter l’algorithme de la FFT. Notre exemple test sera
les polynômes
F = x4 + 3x3 + 2x2 + 6x + 7, G = x2 + 2x + 6
sur F17 (pourquoi ce corps ?). Pour trouver une racine n-ième de l’unité, on pourra
commencer par chercher un élément primitif avec primitive_element().
(1) Commencer par implémenter la procédure d’évaluation.
(2) Implémenter l’algorithme complet avec un choix de racine n-ième.
(3) Pour deux polynômes de degré quelconque sur un corps fini k, écrire un programme
pour faire la FFT de ces deux polynômes. On pourra avoir besoin des fonctions
parent(),
(4) Comparer la multiplication usuelle, Karatsuba et la FFT sur F29·257 +1 pour des
degrés croissants.
4. Séries formellles, division euclidienne
Exercice 9. Implémenter l’algorithme de calcul de la division euclidienne pour les polynômes
basé sur l’inversion des séries formelles. On utilisera PowerSeriesRing(QQ) pour définir
les séries formelles. L’opération de troncature est truncate().
Exercice 10. Soit F une série formelle de terme constant nul. Écrire un programme qui
calcule log(1 + F ) en utilisant l’expression
Z
F0
log(1 + F ) =
.
1+F
Exercice 11. Soient a > b deux entiers pour lesquels on veut effectuer la division euclidienne. On propose l’algorithme ci-dessous. Soit n le plus petit entier tel que 2n b > a.
B := b;
R := a;
Q := 0;
N := n;
Aux := 2N B;
while N > 0 do
Aux := Aux/2;
N := N − 1;
if R < Aux then
Q := 2 ∗ Q;
else
Q := 2Q + 1;
R := R − Aux;
end if;
end while;
(1) Vérifier qu’à chaque étape on a a = Aux · Q + R et 0 ≤ R < Aux et que si N = 0
on a Aux = B.
(2) Donner la complexité de l’algorithme.
(3) Écrire le programme correspondant en SAGE.
4
5. Évaluation, évaluation multi-points, interpolation
Exercice 12. Dans la méthode de pré-processing pour l’évaluation d’un polynôme de
degré 4
(1)
a4 x 4 +
=
=
+
a3 x3 + a2 x2 + a1 x + a0
a4 ((x(x + α0 ) + α1 )(x(x + α0 ) + x + α2 ) + α3 )
a4 x4 + a4 (2α0 + 1)x3 + a4 (α1 + α2 + α0 (α0 + 1))x2
a4 ((α1 + α2 )α0 + α1 )x + a4 (α1 α2 + α3 ).
trouver les αi en fonction des coefficients ai .
Exercice 13. Implémenter l’interpolation de Lagrange. On ne cherchera pas à optimer
le calcul des Ai .
Exercice 14. Implémenter l’évaluation multi-points rapide ainsi que l’interpolation rapide.
On pourra créer la structure arborescente de la manière suivante
class Tree(object):
def __init__(self):
self.left = None
self.right = None
self.data = None
Puis pour créer un arbre binaire A de racine un polynôme P et de sous-arbre gauche
(resp. droit) A0 (resp. A1 ), on écrit
A = Tree()
A.data = P
A.left = A0
A.right = A1
1
Exercice 15. On considère la fonction f (x) = 1+25x
On cherche à interpoler cette
2.
fonction aux points a0 = −1, a1 = −1 + h, . . . , ai+1 = ai + h, . . . , 1 avec h = 2/n et
n = 2s − 1. Dessiner pour plusieurs valeurs de s le polynôme de Lagrange obtenu et
comparer le dessin à celui de f . Qu’observe-t-on ?
6. PGCD - Résultant - Factorisation
Exercice 16. Écrire un algorithme qui étant données des listes (m1 , . . . , mr ) d’entiers
premiers entre eux deux à deux et une liste d’entiers (a1 , . . . , ar ) renvoie une solution x
au système


x ≡ a1 (mod m1 )
..
.


x ≡ ar (mod mr )
Exercice 17.
(1) Trouver les points d’intersection des ellipses d’équations P = 0 et
Q = 0 avec P = X 2 − XY + Y 2 − 1 et Q = 2X 2 + Y 2 − Y − 2. Tracer les courbes.
La fonction pour le résultant est P.resultant(Q,X).
(2) Même exercice dans le cas P = XY − 1 et Q = XY .
(3) Fabriquer l’équation implicite de la courbe paramétrée par x = t2 + t + 1, y =
(t2 − 1)/(t2 + 1).
√
√
√ √
Exercice 18. Calculer le polynôme
minimal
de
2
+
3
et
de
Q
Q 2 · 3. Conclusion.
Soit P (X) = X 4 + X + 1 = (X − αi ). Calculer le polynôme (X − αi5 ).
5
Exercice 19. Soit F une famille de courbes à un paramètre réel t. L’enveloppe de F est
l’ensemble des points (x, y) qui vérifient les deux équations
∂F (x, y, t)
=0
∂t
F (x, y, t) = 0,
pour au moins un t.
(1) Calculez l’enveloppe de la famille suivante, en faisant à chaque fois un graphique
contenant quelques courbes de la famille et le tracé de l’enveloppe :
F (x, y, t) = x2 + (y − t)2 − 1/2(t2 + 1).
(2) En supposant que l’enveloppe est une courbe, justifiez cette définition.
Exercice 20. On se propose de déterminer la formule donnant l’aire d’un triangle en
fonction des longueurs de ses trois côtés a, b, c. Grâce à des calculs de résultants, montrer
que
1
S 2 = (a + b − c)(b + a + c)(a − b + c)(−c + a − b).
16
7. Algèbre linéaire
Une matrice M de taille (m, n) sur un anneau A peut se définir avec la commande
matrix(A,m,n,L]) où L est une liste de coefficients dans A. On peut aussi définir l’espace
des matrices qu’on considère par R=MatrixSpace(A,m,n) puis un éléments par R(L), une
matrice aléatoire par R.random_matrix(), etc. On peut accéder à un coefficients (i, j)
de M par M[i,j]. On peut accéder/modifier toute la colonne j par M[: , j] ou une
partie (à partir de la ligne i) par M[i : , j].
Remark 7.1. Attention ! Comme pour les listes, les matrices sont indicées à partir de 0.
Exercice 21.
(1) En considérant le pivot de Gauss comme l’action de certaines matrices à gauche, effectuer celui-ci sur la matrice


6 2 2
5 4 4

M =
6 4 5
5 1 3
définie sur F7 . Pour échanger deux lignes, on pourra utiliser swap_rows.
Exercice 22. La résolution d’un système linéaire Av = b se fait avec la commande
solve_right.
(1) résoudre un système linéaire aléatoire sur Q.
(2) Calculer la décomposition de Dunford M = D + N (avec D diagonalisable, N
nilpotente et DN = N D) de la matrice


2
3
2
M = −1 −2 −6
1
1
5
à l’aide d’une suite d’itérations de Newton
P (Xn )
Xn+1 = Xn − 0
P (Xn )
où P est le radical du polynôme caractéristique de M en partant de M . Quand
la suite devient stationnaire, on obtient D.
6
Exercice 23. Implémenter la multiplication des matrices (de taille une puissance de 2)
par la méthode de Strassen. Implémenter ensuite l’inversion matricielle rapide.
Exercice 24. Implémenter l’algorithme de Keller-Gehrig pour le calcul du polynôme
caractéristique.
7
Téléchargement