TP : Révisions de 1ère année#

Pour programmer, vous pouvez soit utiliser Pyzo, soit Basthon en cliquant sur la “fusée” en haut à droite de chaque TP.

Commandes Basthon :

  • Ctrl + Entrée : exécuter la cellule

  • Shift + Entrée : exécuter la cellule puis passer à la suivante

  • Entrée : passer en mode édition

  • Échap : sortir du mode édition

Les commandes suivantes sont valables uniquement hors du mode édition :

  • A : créer une nouvelle cellule (en haut)

  • B : créer une nouvelle cellule (en bas)

  • D D : supprimer la cellule

Bases de Python#

Exercice

Calculer \(u_{10}\), où \(u_n\) est définie par \(u_0 = 42\) et \(u_{n+1} = \sqrt{u_n} + 3u_n\).
Il faut trouver 2787204.895558157.

Exercice

Écrire une fonction appartient telle que appartient(x, L) renvoie True si x appartient à la liste L, False sinon.

print(appartient(3, [1, 5, 3, 4, 1]))
print(appartient(3, [1, 5, 4, 2]))
True
False

Exercice

Écrire une fonction pour déterminer si une liste est triée par ordre croissant.

print(croissant([1, 2, 3, 4, 5]))
print(croissant([1, 2, 3, 5, 4]))
True
False

Dichotomie#

La méthode par dichotomie consiste à divise à chaque étape la taille du problème par 2.
L’exemple le plus classique est la recherche par dichotomie dans une liste triée : on souhaite savoir si un élément \(e\) appartient à une liste triée L.

Considérons par exemple L = \([-2, 1, 2, 4, 6, 7, 8, 9, 11, 12, 14, 15, 18, 22, 54]\) et \(e\) = \(14\).

Au lieu de commencer par regarder le 1er élément de L, on va regarder l’élément du milieu (ici \(9\)):

\[ [-2, 1, 2, 4, 6, 7, 8, \underline{\mathbf{9}}, 11, 12, 14, 15, 18, 22, 54] \]

Comme \(9 < 14\) et que la liste est triée par ordre croissant, on en déduit que \(e\), s’il est dans L, est forcément dans la partie droite :

\[ [-2, 1, 2, 4, 6, 7, 8, {9}, \boxed{11, 12, 14, {15}, 18, 22, 54}] \]

On se restreint donc par la suite à la partie de L qui est encadrée. On compare \(e\) au milieu de cette partie, c’est-à-dire \(15\) :

\[ [-2, 1, 2, 4, 6, 7, 8, {9}, \boxed{11, 12, 14, \underline{\textbf{15}}, 18, 22, 54}] \]

Comme \(e < 15\), on peut cette fois se restreinte à la partie gauche. On cherche donc maintenant \(e\) dans la zone suivante :

\[ [-2, 1, 2, 4, 6, 7, 8, {9}, \boxed{11, {12}, 14}, {15}, 18, 22, 54] \]

On compare encore une fois \(e\) au milieu :

\[ [-2, 1, 2, 4, 6, 7, 8, {9}, \boxed{11, \underline{\textbf{12}}, 14}, {15}, 18, 22, 54] \]

Comme \(e > 12\), on regarde à droite :

\[ [-2, 1, 2, 4, 6, 7, 8, {9}, 11, {12}, \boxed{\underline{\textbf{14}}}, {15}, 18, 22, 54] \]

On a trouvé \(e\) !

Exercice

Compléter le code suivant permettant de rechercher un élément dans une liste triée, par dichotomie.

def dichotomie(e, L):
    i, j = 0, len(L) - 1  # i et j sont les indices de L entre lesquels on cherche e
    while ...: # tant qu'il reste au moins 1 élément entre les indices i et j
        m = ... # milieu de i et j
        if e < L[m]:
            ... # regarder dans la partie gauche
        elif e > L[m]:
            ... # regarder dans la partie droite
        else:
            ... # on a trouvé e
    ... # e n'a pas été trouvé

Puis tester votre fonction avec le jeu de tests suivant (assert déclenche une erreur si son argument est False) :

L1, L2, L3 = [0, 2], [0, 2, 5], [-2, 1, 2, 4, 6, 7, 8, 9, 11, 12, 14, 15, 18, 22, 54]
assert (dichotomie(0, L1) and not dichotomie(1, L1))
assert (dichotomie(5, L2) and not dichotomie(7, L2))
assert (dichotomie(14, L3) and not dichotomie(-4, L3))

Matrices#

Exercice

Définir une fonction make_matrix telle que make_matrix(n, p) renvoie une matrice \(n\times p\) remplie de \(0\), sous forme de liste de listes.

make_matrix(3, 4)
[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]

Question

Écrire une fonction transposee(M) qui renvoie la transposée de la matrice M.

transposee([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
[[1, 4, 7], [2, 5, 8], [3, 6, 9]]

Question

Écrire une fonction symetrique(M) qui renvoie True si la matrice M est symétrique, False sinon.

print(symetrique([[1, 2, 3], [2, 4, 5], [3, 5, 6]])) # True
print(symetrique([[1, 2, 3], [2, 4, 7], [3, 5, 6]])) # False
True
False

Graphes#

Si besoin, vous pouvez revoir ce cours (Graphes : Représentations).

Représentation par matrice d’adjacence#

Exercice

Définir dans une variable G la matrice d’adjacence du graphe suivant (on pourra éventuellement utiliser les fonctions précédentes) :

Exercice

Définir une fonction voisins telle que voisins(G, v) renvoie la liste des voisins du sommet v.
Vérifier que les voisins du sommet \(2\) dans le graphe ci-dessus sont les sommets \(1\), \(4\), \(5\).

voisins(G, 2)
[1, 4, 5]

Exercice

En déduire une fonction deg telle que deg(G, v) renvoie le degré du sommet v.

deg(G, 2)
3

Exercice

Écrire une fonction n_aretes pour calculer le nombre d’arêtes d’un graphe donné par matrice d’adjacence. Tester avec le graphe G précédent. On pourra soit réutiliser deg, soit deux boucles for pour parcourir les éléments de la matrice.

n_aretes(G)
8

Représentation par liste d’adjacence#

Exercice

Écrire une fonction mat_to_list telle que mat_to_list(G) renvoie la liste d’adjacence du graphe G donné par matrice d’adjacence. Calculer la représentation par liste d’adjacence G_list du graphe G précédent.

G_list = mat_to_list(G)
G_list
[[6], [2, 3, 4], [1, 4, 5], [1, 4], [1, 2, 3, 5], [2, 4], [0]]

Parcours en profondeur#

Revoir ce cours si besoin

Exercice

Écrire une fonction dfs(G, s) renvoyant la liste des sommets de G (défini par liste d’adjacence) suivant un parcours en profondeur depuis le sommet s. Vérifier sur le graphe G_list précédent.
On pourra compléter le code ci-dessous. Ne regarder le cours que si cela est vraiment nécessaire.

def dfs(G, s):
    # définir une liste de booléens pour savoir si un sommet a été visité
    def aux(u): # fonction récursive
        # si u n'a pas été visité :
            # afficher u
            # marquer u comme visité
            # pour chaque voisin v de u
                # appeler aux(v)
    aux(s)
dfs(G_list, 0)
0
6
dfs(G_list, 2)
2
1
3
4
5

Exercice

En utilisant un parcours en profondeur, écrire une fonction connexe(G) qui renvoie True si le graphe G est connexe, False sinon.
Vérifier sur G_list (non connexe) et sur un graphe connexe de votre choix.

connexe(G_list)
False

Parcours en largeur#

Revoir ce cours si besoin

On rappelle l’utilisation d’une file en Python, avec la classe deque :

from collections import deque

q = deque() # file vide
q.appendleft(4) # ajoute 4 au début
q.appendleft(7)
q.pop() # supprime et renvoie le dernier élément (4)
q.appendleft(-5)
q.pop() # supprime et renvoie le dernier élément (7)
7

Exercice

Écrire une fonction bfs(G, s) affichant les sommets du graphe G lors d’un parcours en largeur depuis le sommet s. Vérifier sur le graphe G_list précédent.

from collections import deque

def bfs(G, s):
    # définir une file q contenant s
    # définir une liste visited contenant n False, où n est le nombre de sommets
    # tant que q est non vide
        # extraire le dernier élément de q dans une variable u
        # si u n'a pas été visité:
            # afficher u
            # mettre True dans visited[u]
            # pour chaque voisin v de u
                # ajouter v au début de q 
bfs(G_list, 2)
2
1
4
5
3

Exercice

Écrire une fonction distances(G, s) qui renvoie une liste dist telle que dist[v] soit la distance (en nombre d’arêtes) du sommet s au sommet v. Vérifier sur le graphe G_list précédent.

distances(G_list, 2)
[inf, 1, 0, 3, 2, 3, inf]