edit et corrections d'erreurs factuelles, de calculs et de mise en page
This commit is contained in:
@@ -14,10 +14,9 @@ Les enfants d'un noeud sont lus de **gauche à droite** et sont appelés **fils
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
### Exercice 1:
|
### Exercice 1 :
|
||||||
Parmi les arbres du cours précédent, lesquels sont binaires ?
|
Parmi les arbres du cours précédent, lesquels sont binaires ?
|
||||||
|
|
||||||
Réponse
|
|
||||||
|
|
||||||
### Remarque:
|
### Remarque:
|
||||||
Les arbres binaires forment une structure de données qui peut se définir de façon récursive.
|
Les arbres binaires forment une structure de données qui peut se définir de façon récursive.
|
||||||
@@ -61,7 +60,7 @@ Il possède 3 niveaux, sa hauteur ou profondeur est donc de 2. La taille du tabl
|
|||||||
|
|
||||||
*Il faut compter le nombre de noeuds, y compris les noeuds "fantômes" des feuilles.*
|
*Il faut compter le nombre de noeuds, y compris les noeuds "fantômes" des feuilles.*
|
||||||
|
|
||||||
### Exercice :
|
### Exercice 2 :
|
||||||
1. Quelle est la taille du tableau qui permet de représenter cet arbre ?
|
1. Quelle est la taille du tableau qui permet de représenter cet arbre ?
|
||||||
|
|
||||||

|

|
||||||
@@ -83,7 +82,7 @@ Le dessiner. Que peut-il représenter ?
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
> Voici un code python Python qui crée la liste représentant l'arbre de l'exercice 2
|
> Voici un code Python qui crée la liste représentant l'arbre de l'exercice 2
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -124,7 +123,7 @@ print(arbre)
|
|||||||
['r', 'a', 'b', 'c', 'd', 'e', 'f', None, 'h', 'i', 'j', 'k', None, None, None, None, None, None, None, None, None, 'm', None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None]
|
['r', 'a', 'b', 'c', 'd', 'e', 'f', None, 'h', 'i', 'j', 'k', None, None, None, None, None, None, None, None, None, 'm', None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None]
|
||||||
|
|
||||||
|
|
||||||
### Exercice 3:
|
### Exercice 3 :
|
||||||
1. Ecrire une fonction qui retourne le parent d'un noeud s'il est dans l'arbre et None sinon.
|
1. Ecrire une fonction qui retourne le parent d'un noeud s'il est dans l'arbre et None sinon.
|
||||||
2. Ecrire une fonction qui retourne **True** si l'arbre est vide
|
2. Ecrire une fonction qui retourne **True** si l'arbre est vide
|
||||||
3. Ecrire une fonction qui retourne les enfants d'un noeud.
|
3. Ecrire une fonction qui retourne les enfants d'un noeud.
|
||||||
@@ -132,11 +131,13 @@ print(arbre)
|
|||||||
5. Même question pour le fils droit
|
5. Même question pour le fils droit
|
||||||
6. Ecrire une fonction qui renvoie **True** si le noeud est la racine de l'arbre
|
6. Ecrire une fonction qui renvoie **True** si le noeud est la racine de l'arbre
|
||||||
7. Ecrire une fonction qui renvoie **True** si le noeud est une feuille
|
7. Ecrire une fonction qui renvoie **True** si le noeud est une feuille
|
||||||
8. Ecrire une fonction qui renvoie **true** si le noeud comporte un frère gauche ou droit.
|
8. Ecrire une fonction qui renvoie **True** si le noeud comporte un frère gauche ou droit.
|
||||||
|
|
||||||
**<u>Rappel : dans un tableau, si on note i l'indice d'un noeud, alors ses fils auront comme indice 2i +1 et 2i +2.</u>**
|
**<u>Rappel : dans un tableau, si on note i l'indice d'un noeud, alors ses fils auront comme indice 2i +1 et 2i +2.</u>**
|
||||||
|
|
||||||
**<u>Inversement, pour trouver le parent d'un noeud, il faut vérifier : i - 1 //2</u>**
|
**<u>Inversement, pour trouver le parent d'un noeud, il faut calculer : (i - 1) // 2</u>**
|
||||||
|
|
||||||
|
*Attention aux parenthèses : en Python, `i - 1 // 2` vaut `i` (la division est prioritaire sur la soustraction) !*
|
||||||
|
|
||||||
---------
|
---------
|
||||||
|
|
||||||
@@ -152,7 +153,7 @@ Cet arbre se représente par le tableau:
|
|||||||
|
|
||||||
['r', ['a', [ ], [ ]], ['b', [ ], [ ]]]
|
['r', ['a', [ ], [ ]], ['b', [ ], [ ]]]
|
||||||
|
|
||||||
### Exercice :
|
### Exercice 4 :
|
||||||
Ecrire le tableau représentant l'arbre ci-dessous et le stocker dans une variable **t**
|
Ecrire le tableau représentant l'arbre ci-dessous et le stocker dans une variable **t**
|
||||||
|
|
||||||

|

|
||||||
@@ -194,7 +195,7 @@ print(arbre1)
|
|||||||
['r', ['a', ['c', [], ['h', [], []]], ['d', ['i', [], []], ['j', ['m', [], []], []]]], ['b', ['e', ['k', [], []], []], ['f', [], []]]]
|
['r', ['a', ['c', [], ['h', [], []]], ['d', ['i', [], []], ['j', ['m', [], []], []]]], ['b', ['e', ['k', [], []], []], ['f', [], []]]]
|
||||||
|
|
||||||
|
|
||||||
### Exercice :
|
### Exercice 5 :
|
||||||
Ecrire toutes les fonctions de l'exercice 3 dans le cas de cette implémentation de l'arbre.
|
Ecrire toutes les fonctions de l'exercice 3 dans le cas de cette implémentation de l'arbre.
|
||||||
|
|
||||||
--------
|
--------
|
||||||
@@ -215,7 +216,7 @@ Voici l'algorithme:
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
### Exercice :
|
### Exercice 6 :
|
||||||
1. Ecrire cette fonction pour l'arbre précédent et vérifier que sa profondeur est de 4.
|
1. Ecrire cette fonction pour l'arbre précédent et vérifier que sa profondeur est de 4.
|
||||||
|
|
||||||
|
|
||||||
@@ -246,7 +247,7 @@ Voici l'algorithme:
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
### Exercice 7
|
### Exercice 7 :
|
||||||
|
|
||||||
1. Rappeler les fonction permettant de définir une structure de file en python.
|
1. Rappeler les fonction permettant de définir une structure de file en python.
|
||||||
2. Implémenter alors cette fonction et l'essayer sur l'arbre précédent.
|
2. Implémenter alors cette fonction et l'essayer sur l'arbre précédent.
|
||||||
@@ -261,7 +262,7 @@ On se balade autour de l'arbre en suivant les pointillés
|
|||||||
Voici un algorithme permettant de réaliser ce parcours:
|
Voici un algorithme permettant de réaliser ce parcours:
|
||||||

|

|
||||||
|
|
||||||
### Exercice
|
### Exercice 8 :
|
||||||
1. Proposer une fonction permettant de réaliser le parcours en profondeur d'un arbre
|
1. Proposer une fonction permettant de réaliser le parcours en profondeur d'un arbre
|
||||||
|
|
||||||
|
|
||||||
@@ -278,7 +279,7 @@ Dans le schéma ci-dessus, on a rajouté des "noeuds fantômes" pour montrer que
|
|||||||
Dans un parcours **préfixe**, on liste le noeud la première fois qu'on le rencontre.
|
Dans un parcours **préfixe**, on liste le noeud la première fois qu'on le rencontre.
|
||||||
|
|
||||||
|
|
||||||
### Exercice
|
### Exercice 9 :
|
||||||
1. Ecrire les sommets dans l'ordre d'un parcours préfixe
|
1. Ecrire les sommets dans l'ordre d'un parcours préfixe
|
||||||
|
|
||||||
|
|
||||||
@@ -290,7 +291,7 @@ Ce qui correspond à:
|
|||||||
* On liste chaque noeud ayant un fils gauche la seconde fois qu'on le voit
|
* On liste chaque noeud ayant un fils gauche la seconde fois qu'on le voit
|
||||||
* on liste chaque noeud sans fils gauche la première fois qu'on le voit
|
* on liste chaque noeud sans fils gauche la première fois qu'on le voit
|
||||||
|
|
||||||
### Exercice
|
### Exercice 10 :
|
||||||
1. Ecrire les sommets dans l'ordre d'un parcours infixe
|
1. Ecrire les sommets dans l'ordre d'un parcours infixe
|
||||||
|
|
||||||
|
|
||||||
@@ -298,12 +299,12 @@ Ce qui correspond à:
|
|||||||
### Definition:
|
### Definition:
|
||||||
Dans un parcours **suffixe**, on note le noeud la dernière fois qu'on le rencontre.
|
Dans un parcours **suffixe**, on note le noeud la dernière fois qu'on le rencontre.
|
||||||
|
|
||||||
Exercice 11
|
### Exercice 11 :
|
||||||
1. Ecrire les sommets dans l'ordre d'un parcours suffixe
|
1. Ecrire les sommets dans l'ordre d'un parcours suffixe
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### Exercice
|
### Exercice 12 :
|
||||||
1. Voici trois algorithmes récursifs, dire pour chacun d'entre eux à quel parcours il correspond.
|
1. Voici trois algorithmes récursifs, dire pour chacun d'entre eux à quel parcours il correspond.
|
||||||

|

|
||||||

|

|
||||||
@@ -319,7 +320,7 @@ Nous allons créer une classe **Noeud** dont les attributs d'instances seront:
|
|||||||
* son fils gauche (None par défaut) ou de type Noeud
|
* son fils gauche (None par défaut) ou de type Noeud
|
||||||
* son fils droit (None par défaut) ou de type Noeud
|
* son fils droit (None par défaut) ou de type Noeud
|
||||||
|
|
||||||
### Exercice
|
### Exercice 13 :
|
||||||
1. Implémentez cette classe Noeud
|
1. Implémentez cette classe Noeud
|
||||||
2. Stocker l'arbre comme étant l'objet de type "Noeud" correspondant à la racine.
|
2. Stocker l'arbre comme étant l'objet de type "Noeud" correspondant à la racine.
|
||||||
3. Ecrire une méthode estFeuille qui renvoie True si le noeud est une feuille et False sinon
|
3. Ecrire une méthode estFeuille qui renvoie True si le noeud est une feuille et False sinon
|
||||||
|
|||||||
@@ -56,8 +56,10 @@ On parle également de **hauteur d'un arbre** :
|
|||||||
|
|
||||||
- Elle correspond à la **profondeur maximale** d’un nœud dans l’arbre, c’est-à-dire le **plus grand nombre d’arêtes** depuis la racine jusqu’à une feuille.
|
- Elle correspond à la **profondeur maximale** d’un nœud dans l’arbre, c’est-à-dire le **plus grand nombre d’arêtes** depuis la racine jusqu’à une feuille.
|
||||||
- La hauteur est le nombre maximum de niveaux dans l’arbre, en partant de la racine jusqu’à la feuille la plus profonde.
|
- La hauteur est le nombre maximum de niveaux dans l’arbre, en partant de la racine jusqu’à la feuille la plus profonde.
|
||||||
- Selon les points de vue, la hauteur est parfois définie différemment :
|
- Selon les conventions, la hauteur est parfois définie différemment :
|
||||||
- On peut considérer la hauteur d'un arbre vide à 0, soit à 1.
|
- Si on compte le nombre d'**arêtes** du plus long chemin (convention utilisée dans ce cours), un arbre réduit à sa racine a une hauteur de 0, et l'arbre vide une hauteur de -1.
|
||||||
|
- Si on compte le nombre de **niveaux**, un arbre réduit à sa racine a une hauteur de 1, et l'arbre vide une hauteur de 0.
|
||||||
|
- Les sujets de bac précisent toujours la convention choisie : lisez bien l'énoncé !
|
||||||
|
|
||||||
**Question** : *Quelle est la hauteur de l'arbre du dessus ?*
|
**Question** : *Quelle est la hauteur de l'arbre du dessus ?*
|
||||||
|
|
||||||
@@ -89,7 +91,7 @@ Comprendre ces caractéristiques nous aidera à explorer comment manipuler effic
|
|||||||
|
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
Auteurs : Florian Mathieu, Timothée Decoster, Enzo Frémaux
|
Auteurs : Florian Mathieu, Timothée Decoster, Enzo Frémeaux
|
||||||
|
|
||||||
Licence CC BY NC
|
Licence CC BY NC
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ Dans les années 1970, un certain **Edgar F. Codd**, mathématicien chez IBM, in
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
Avec le big data, il a fallu trouver une solution pour permettre aux entreprises de manipuler ces données entrantes. C'est alors que sont nés les premiers **S**ystème de **G**estion de **B**ases de **D**onnées, appelé **SGBD**.
|
Dès les années 1960-1970, bien avant qu'on parle de « big data », les entreprises et administrations ont eu besoin de manipuler des volumes de données croissants (réservations aériennes, banques, recensements...). C'est alors que sont nés les premiers **S**ystèmes de **G**estion de **B**ases de **D**onnées, appelés **SGBD**.
|
||||||
|
|
||||||
Ces derniers ont plusieurs fonctions dont 4 qui sont primordiales :
|
Ces derniers ont plusieurs fonctions dont 4 qui sont primordiales :
|
||||||
|
|
||||||
|
|||||||
@@ -105,9 +105,9 @@ Si l’attribut `Age` est défini comme un entier positif, une valeur comme `-3`
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Anecdote : Le bug de la clé étrangère oubliée
|
## Expérience de pensée : Le bug de la clé étrangère oubliée
|
||||||
|
|
||||||
Dans les années 1990, une banque a oublié d’appliquer la contrainte d’intégrité référentielle dans sa base de données. Résultat : des milliers de transactions faisaient référence à des comptes clients inexistants. Moralité : quand on parle d'argent, mieux vaut éviter les erreurs de clé étrangère !
|
Imaginez une banque qui oublierait d'appliquer la contrainte d'intégrité référentielle dans sa base de données. Rien n'empêcherait alors d'enregistrer des virements vers des comptes clients... inexistants. Où irait l'argent ? Personne ne le sait. Moralité : quand on parle d'argent, mieux vaut éviter les erreurs de clé étrangère !
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ On peut par exemple prendre des problèmes assez élémentaires :
|
|||||||
|
|
||||||
- X est il un nombre pair ?
|
- X est il un nombre pair ?
|
||||||
- Y est il une puissance de 3 ?
|
- Y est il une puissance de 3 ?
|
||||||
- Dans un graphe, quel est le chemin le plus court passant par tous les sommets ?
|
- Dans un graphe, existe-t-il un chemin passant par tous les sommets de longueur inférieure à k ?
|
||||||
|
|
||||||
Dans notre premier cas, nous avons en **instance de départ :** un entier naturel, qui, après être traité via le **paramètre** choisi (Si reste = 0 après une division par 2, alors nombre est pair) dans **l'algorithme**, ressortira en une réponse simple : *Oui* ou *Non* selon la **décision** prise.
|
Dans notre premier cas, nous avons en **instance de départ :** un entier naturel, qui, après être traité via le **paramètre** choisi (Si reste = 0 après une division par 2, alors nombre est pair) dans **l'algorithme**, ressortira en une réponse simple : *Oui* ou *Non* selon la **décision** prise.
|
||||||
|
|
||||||
@@ -39,11 +39,9 @@ En informatique ou mathématiques, on peut parler d'une **fonction algorithmique
|
|||||||
|
|
||||||
Un ***prédicat*** est une fonction qui ne prendra que des valeurs booléennes.
|
Un ***prédicat*** est une fonction qui ne prendra que des valeurs booléennes.
|
||||||
|
|
||||||
> La réponse à un problème de décision est donc soit un booléen, soit une valeur qui permet de répondre à un prédicat.
|
> La réponse à un problème de décision est donc un booléen : oui ou non.
|
||||||
>
|
>
|
||||||
> **Exemple** : Dans un graphe, connaître le nombre de sommets permet de répondre à la question : « Le chemin que j'ai choisi est-il le plus court passant par tous les sommets de ce graphe ? »
|
> **Exemple** : « Ce chemin passe-t-il par tous les sommets du graphe ? » est une question dont la réponse est Vrai ou Faux : la fonction qui y répond est bel et bien un prédicat.
|
||||||
>
|
|
||||||
> Question dont la réponse est bel et bien un prédicat.
|
|
||||||
|
|
||||||
### Définition : Décidabilité
|
### Définition : Décidabilité
|
||||||
|
|
||||||
@@ -68,7 +66,7 @@ Quel rapport avec la calculabilité ? Et bien une fonction mathématique, que l'
|
|||||||
|
|
||||||
### Un peu d'histoire
|
### Un peu d'histoire
|
||||||
|
|
||||||
En 1943, un mathématicien américain, du nom d'Alonzo Church définit une thèse dite "thèse de Church" qui affirme la notion de calculabilité : Tout traitement d'un système réalisable par un processus quel qu'il soit, peut être exprimé par un ensemble de règles de calcul.
|
En 1936, un mathématicien américain, du nom d'Alonzo Church, formule ce qu'on appellera la "thèse de Church" (la même année, Alan Turing arrive indépendamment à un résultat équivalent avec sa machine). Cette thèse affirme la notion de calculabilité : Tout traitement d'un système réalisable par un processus quel qu'il soit, peut être exprimé par un ensemble de règles de calcul.
|
||||||
|
|
||||||
Cet ensemble est défini lui même par les règles de calcul dont on prouve mathématiquement l'équivalence.
|
Cet ensemble est défini lui même par les règles de calcul dont on prouve mathématiquement l'équivalence.
|
||||||
|
|
||||||
@@ -155,21 +153,23 @@ Par exemple :
|
|||||||
|
|
||||||
```python
|
```python
|
||||||
def est_pair2(n):
|
def est_pair2(n):
|
||||||
|
reste = n % 2
|
||||||
if (n % 2) == 0:
|
if reste == 0:
|
||||||
return("{0} est Pair".format(n))
|
return True
|
||||||
else:
|
else:
|
||||||
return("{0} est Impair".format(n))
|
return False
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
```python
|
```python
|
||||||
>>>est_pair2(113)
|
>>>est_pair2(113)
|
||||||
>>>'113 est Impair'
|
>>>False
|
||||||
>>>est_pair2(42)
|
>>>est_pair2(42)
|
||||||
>>>'42 est Pair'
|
>>>True
|
||||||
```
|
```
|
||||||
|
|
||||||
|
*Remarque : cette version renvoie bien un booléen, comme la première. Une fonction qui renverrait une chaîne de caractères comme `"42 est Pair"` ne serait pas un prédicat !*
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Nous avons bien la preuve que le problème " Peut-on prouver qu'un nombre est pair" est bel et bien décidable.
|
Nous avons bien la preuve que le problème " Peut-on prouver qu'un nombre est pair" est bel et bien décidable.
|
||||||
@@ -182,7 +182,7 @@ La question qui se pose à nous est de savoir comment reconnaitre un problème i
|
|||||||
|
|
||||||
Et à l'heure actuelle, nous ne disposons pas de machine magique permettant de nous donner cette information.
|
Et à l'heure actuelle, nous ne disposons pas de machine magique permettant de nous donner cette information.
|
||||||
|
|
||||||
Pour déduire l'indécidabilité d'un programme, il faut un algorithme répondant à ce problème et également la preuve qu'il se termine.
|
Pour prouver qu'un problème est *décidable*, il suffit d'exhiber un algorithme qui le résout et qui se termine toujours. Mais pour prouver qu'un problème est *indécidable*, c'est bien plus difficile : il faut démontrer qu'**aucun** algorithme, même parmi ceux qu'on n'a pas encore inventés, ne pourra jamais le résoudre.
|
||||||
|
|
||||||
En informatique, le plus célèbre de ces problèmes indécidables est le ***problème de l'arrêt***.
|
En informatique, le plus célèbre de ces problèmes indécidables est le ***problème de l'arrêt***.
|
||||||
|
|
||||||
|
|||||||
@@ -43,7 +43,9 @@ def bfs(graphe, depart):
|
|||||||
|
|
||||||
### Illustration du parcours en largeur
|
### Illustration du parcours en largeur
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
*Source : [Gilles Lassus](https://glassus.github.io/terminale_nsi/)*
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -53,12 +55,11 @@ def bfs(graphe, depart):
|
|||||||
|
|
||||||
Le parcours en profondeur explore un chemin le plus loin possible avant de revenir en arrière. C’est une approche de type pile (LIFO).
|
Le parcours en profondeur explore un chemin le plus loin possible avant de revenir en arrière. C’est une approche de type pile (LIFO).
|
||||||
|
|
||||||
#### Algorithme DFS :
|
#### Algorithme DFS (version récursive) :
|
||||||
1. Choisir un sommet de départ et l’empiler.
|
1. Marquer le sommet courant comme visité.
|
||||||
2. Marquer ce sommet comme visité.
|
2. Pour chaque voisin non encore visité, relancer le parcours depuis ce voisin.
|
||||||
3. Tant que la pile n’est pas vide :
|
|
||||||
- Retirer le sommet du sommet de la pile.
|
> On peut aussi écrire DFS de manière itérative avec une pile explicite (en remplaçant la file du BFS par une pile). Dans la version récursive ci-dessous, c'est la **pile d'appels** de Python qui joue ce rôle : chaque appel récursif "empile" un sommet, chaque retour le "dépile".
|
||||||
- Ajouter tous ses voisins non encore visités dans la pile et les marquer comme visités.
|
|
||||||
|
|
||||||
#### Implémentation en Python :
|
#### Implémentation en Python :
|
||||||
```python
|
```python
|
||||||
@@ -78,7 +79,9 @@ def dfs(graphe, depart, visite=None):
|
|||||||
|
|
||||||
### Illustration
|
### Illustration
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
*Source : [gaudry.be](https://www.gaudry.be/)*
|
||||||
|
|
||||||
----------
|
----------
|
||||||
|
|
||||||
|
|||||||
@@ -184,6 +184,39 @@ A = np.matrix(A)
|
|||||||
|
|
||||||
Ecrire la matrice d'adjacence du réseau social de l'introduction
|
Ecrire la matrice d'adjacence du réseau social de l'introduction
|
||||||
|
|
||||||
|
### Liste d'adjacence
|
||||||
|
|
||||||
|
La matrice n'est pas la seule représentation possible. On peut aussi associer à chaque sommet la **liste de ses voisins** (ou de ses **successeurs** dans le cas d'un graphe orienté). En Python, un dictionnaire est parfait pour cela :
|
||||||
|
|
||||||
|
```python
|
||||||
|
adjacence = {
|
||||||
|
'A': ['B', 'C', 'E'],
|
||||||
|
'B': ['A', 'C', 'D'],
|
||||||
|
'C': ['A', 'B', 'D'],
|
||||||
|
'D': ['B', 'C'],
|
||||||
|
'E': ['A']
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
C'est cette représentation que nous utiliserons pour les parcours (voir [PARCOURS.md](PARCOURS.md)) et l'implémentation en POO (voir [POO.md](POO.md)).
|
||||||
|
|
||||||
|
**Quelle représentation choisir ?**
|
||||||
|
|
||||||
|
| | Matrice d'adjacence | Liste d'adjacence |
|
||||||
|
|---|---|---|
|
||||||
|
| Tester si deux sommets sont voisins | Immédiat (une case) | Parcours de la liste |
|
||||||
|
| Mémoire | n × n cases, même si peu d'arêtes | Proportionnelle au nombre d'arêtes |
|
||||||
|
| Usage naturel | Graphes denses (beaucoup d'arêtes) | Graphes creux (peu d'arêtes) |
|
||||||
|
|
||||||
|
### Exercice 3:
|
||||||
|
|
||||||
|
Le programme officiel demande de savoir **passer d'une représentation à l'autre**.
|
||||||
|
|
||||||
|
1. Écrire à la main la liste d'adjacence correspondant à la matrice de l'exemple du cours.
|
||||||
|
2. Écrire une fonction `matrice_vers_liste(matrice, sommets)` qui prend la matrice (liste de listes) et la liste des noms de sommets, et renvoie le dictionnaire d'adjacence.
|
||||||
|
3. Écrire la fonction inverse `liste_vers_matrice(adjacence, sommets)`.
|
||||||
|
4. Vérifier vos deux fonctions : `matrice_vers_liste` suivie de `liste_vers_matrice` doit redonner la matrice de départ.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -299,7 +299,7 @@ python arithmetique.py
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
Auteurs : Florian Mathieu, Enzo Frémeaux, Thimothée Decooster
|
Auteurs : Florian Mathieu, Enzo Frémeaux, Timothée Decoster
|
||||||
|
|
||||||
Licence CC BY NC
|
Licence CC BY NC
|
||||||
|
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ Néanmoins, la postérité aura attribué ce mot à la développeuse, qui aurait
|
|||||||
|
|
||||||
------
|
------
|
||||||
|
|
||||||
Auteur : Florian Mathieu, Enzo Frémeaux, Thimothée Decooster.
|
Auteur : Florian Mathieu, Enzo Frémeaux, Timothée Decoster.
|
||||||
|
|
||||||
Licence CC BY NC
|
Licence CC BY NC
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ Intéressons-nous au code Python ci-dessous. Ici, la structure compte plus que l
|
|||||||
|
|
||||||
```python
|
```python
|
||||||
## importations
|
## importations
|
||||||
from math import *
|
from math import sqrt
|
||||||
import doctest
|
import doctest
|
||||||
|
|
||||||
## variables
|
## variables
|
||||||
@@ -77,7 +77,7 @@ Intéressons nous au programme vu précédemment :
|
|||||||
|
|
||||||
```python
|
```python
|
||||||
## importations
|
## importations
|
||||||
from math import *
|
from math import sqrt
|
||||||
import doctest
|
import doctest
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -169,6 +169,8 @@ def somme(n):
|
|||||||
>>> somme(5)
|
>>> somme(5)
|
||||||
15
|
15
|
||||||
>>> somme(-1)
|
>>> somme(-1)
|
||||||
|
Traceback (most recent call last):
|
||||||
|
...
|
||||||
AssertionError: erreur
|
AssertionError: erreur
|
||||||
"""
|
"""
|
||||||
assert type(n)==int, "erreur"
|
assert type(n)==int, "erreur"
|
||||||
@@ -187,7 +189,7 @@ L'attribut *verbose* de la fonction testmod nous permet de dire à ce dernier de
|
|||||||
|
|
||||||
----------
|
----------
|
||||||
|
|
||||||
Auteurs : Florian Mathieu, Enzo Frémeaux, Thimothée Decooster
|
Auteurs : Florian Mathieu, Enzo Frémeaux, Timothée Decoster
|
||||||
|
|
||||||
Licence CC BY NC
|
Licence CC BY NC
|
||||||
|
|
||||||
|
|||||||
@@ -562,7 +562,7 @@ def aire_cercle(rayon):
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
Auteurs : Florian Mathieu, Enzo Frémeaux, Thimothée Decooster
|
Auteurs : Florian Mathieu, Enzo Frémeaux, Timothée Decoster
|
||||||
|
|
||||||
Licence CC BY NC
|
Licence CC BY NC
|
||||||
|
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ Question 10 - Ajouter la doctest de ces fonctions.
|
|||||||
|
|
||||||
-------
|
-------
|
||||||
|
|
||||||
Auteurs : Florian Mathieu, Enzo Frémeaux, Thimothée Decooster
|
Auteurs : Florian Mathieu, Enzo Frémeaux, Timothée Decoster
|
||||||
|
|
||||||
Licence CC BY NC
|
Licence CC BY NC
|
||||||
|
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ Le constructeur est une méthode(fonction) permettant d'initialiser votre type.
|
|||||||
|
|
||||||
```python
|
```python
|
||||||
class Etudiant :
|
class Etudiant :
|
||||||
def __init__(self,nom_etu,prenom_etu,spe1_etu,age_etu) :
|
def __init__(self,nom_etu,prenom_etu,spe1_etu,age_etu) :
|
||||||
self.nom = nom_etu
|
self.nom = nom_etu
|
||||||
self.prenom = prenom_etu
|
self.prenom = prenom_etu
|
||||||
self.spe1 = spe1_etu
|
self.spe1 = spe1_etu
|
||||||
@@ -110,7 +110,7 @@ Supposons que l'étudiant change de spécialité. Bob voudrait arrêter de faire
|
|||||||
|
|
||||||
```python
|
```python
|
||||||
def change_spe(self,nouvelle_spe) :
|
def change_spe(self,nouvelle_spe) :
|
||||||
self.spe1 = nouvelle_spe
|
self.spe1 = nouvelle_spe
|
||||||
```
|
```
|
||||||
|
|
||||||
<u>Pour appeler la méthode :</u>
|
<u>Pour appeler la méthode :</u>
|
||||||
@@ -126,9 +126,9 @@ On pourrait créer une méthode *anniversaire* par exemple :
|
|||||||
|
|
||||||
```python
|
```python
|
||||||
def anniversaire(self) :
|
def anniversaire(self) :
|
||||||
self.age = self.age + 1
|
self.age = self.age + 1
|
||||||
if self.age == 18 :
|
if self.age == 18 :
|
||||||
self.peut_avoir_son_permis = True
|
self.peut_avoir_son_permis = True
|
||||||
```
|
```
|
||||||
|
|
||||||
Si l'anniversaire de l'étudiant passe, alors il gagne 1 an et s'il a 18 ans alors il est éligible au permis de conduire.
|
Si l'anniversaire de l'étudiant passe, alors il gagne 1 an et s'il a 18 ans alors il est éligible au permis de conduire.
|
||||||
@@ -137,7 +137,7 @@ Imaginons maintenant qu'il soit possible d'avoir une nouvelle spécialité.
|
|||||||
|
|
||||||
```python
|
```python
|
||||||
def nouvelle_spe(self,new_spe):
|
def nouvelle_spe(self,new_spe):
|
||||||
self.spe2 = new_spe
|
self.spe2 = new_spe
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
@@ -169,7 +169,7 @@ Actuellement il est impossible de faire la même chose avec nos étudiants. C'es
|
|||||||
|
|
||||||
```python
|
```python
|
||||||
def __eq__(self,obj2):
|
def __eq__(self,obj2):
|
||||||
return self.spe1 == obj2.spe1
|
return self.spe1 == obj2.spe1
|
||||||
```
|
```
|
||||||
|
|
||||||
Cette méthode propre à python permet d'effectuer l'opération suivante.
|
Cette méthode propre à python permet d'effectuer l'opération suivante.
|
||||||
@@ -222,7 +222,7 @@ En utilisant des types privés il n'est plus possible d'accéder directement aux
|
|||||||
|
|
||||||
```python
|
```python
|
||||||
class Etudiant :
|
class Etudiant :
|
||||||
def __init__(self,nom_etu,prenom_etu,spe1_etu,age_etu) :
|
def __init__(self,nom_etu,prenom_etu,spe1_etu,age_etu) :
|
||||||
self.__nom = nom_etu
|
self.__nom = nom_etu
|
||||||
self.__prenom = prenom_etu
|
self.__prenom = prenom_etu
|
||||||
self.spe1 = spe1_etu
|
self.spe1 = spe1_etu
|
||||||
@@ -238,10 +238,10 @@ Ici l'attribut \_\_nom et \_\_prenom sont privés. Pour accéder/modifier à leu
|
|||||||
|
|
||||||
```python
|
```python
|
||||||
def get_nom(self):
|
def get_nom(self):
|
||||||
return self.__nom
|
return self.__nom
|
||||||
|
|
||||||
def set_nom(self,nouveau_nom):
|
def set_nom(self,nouveau_nom):
|
||||||
self.__nom = nouveau_nom
|
self.__nom = nouveau_nom
|
||||||
```
|
```
|
||||||
|
|
||||||
Ces méthodes sont appelées des accesseurs et modificateurs. Elles sont optionnelles selon les cas.
|
Ces méthodes sont appelées des accesseurs et modificateurs. Elles sont optionnelles selon les cas.
|
||||||
@@ -332,7 +332,7 @@ True
|
|||||||
|
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
Auteurs : Florian Mathieu, Enzo Frémeaux, Thimothée Decooster
|
Auteurs : Florian Mathieu, Enzo Frémeaux, Timothée Decoster
|
||||||
|
|
||||||
Licence CC BY NC
|
Licence CC BY NC
|
||||||
|
|
||||||
|
|||||||
@@ -244,7 +244,7 @@ def livres_par_auteur(self, nom_auteur):
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
Auteurs : Florian Mathieu, Enzo Frémeaux, Thimothée Decooster
|
Auteurs : Florian Mathieu, Enzo Frémeaux, Timothée Decoster
|
||||||
|
|
||||||
Licence CC BY NC
|
Licence CC BY NC
|
||||||
|
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ Il faut s'entraîner, essayer d'aller le plus loin possible. Alors essayez, test
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
Auteurs : Florian Mathieu, Enzo Frémeaux, Thimothée Decooster
|
Auteurs : Florian Mathieu, Enzo Frémeaux, Timothée Decoster
|
||||||
|
|
||||||
Licence CC BY NC
|
Licence CC BY NC
|
||||||
|
|
||||||
|
|||||||
@@ -536,7 +536,7 @@ print(sacha)
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
Auteurs : Florian Mathieu, Enzo Frémeaux, Thimothée Decooster
|
Auteurs : Florian Mathieu, Enzo Frémeaux, Timothée Decoster
|
||||||
|
|
||||||
Licence CC BY NC
|
Licence CC BY NC
|
||||||
|
|
||||||
|
|||||||
@@ -426,7 +426,7 @@ print(wrapped)
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
Auteurs : Florian Mathieu, Enzo Frémeaux, Thimothée Decooster
|
Auteurs : Florian Mathieu, Enzo Frémeaux, Timothée Decoster
|
||||||
|
|
||||||
Licence CC BY NC
|
Licence CC BY NC
|
||||||
|
|
||||||
|
|||||||
@@ -150,9 +150,11 @@ En Python, la fonction lambda se définit à l'aide du mot-clé **lambda** :
|
|||||||
```python
|
```python
|
||||||
add_a_b = lambda a,b: a + b
|
add_a_b = lambda a,b: a + b
|
||||||
|
|
||||||
entre_10_et_20 = lambda x : True if (x > 10 and x < 20) else False
|
entre_10_et_20 = lambda x: 10 < x < 20
|
||||||
```
|
```
|
||||||
|
|
||||||
|
*Remarque : inutile d'écrire `True if condition else False` - la condition **est** déjà un booléen, on la renvoie directement.*
|
||||||
|
|
||||||
Appelée aussi fonction anonyme, il ne faut pas en abuser en Python, elle :
|
Appelée aussi fonction anonyme, il ne faut pas en abuser en Python, elle :
|
||||||
|
|
||||||
- est utile pour définir une fonction simple, proche d’une définition mathématique, en une ligne ;
|
- est utile pour définir une fonction simple, proche d’une définition mathématique, en une ligne ;
|
||||||
@@ -171,17 +173,21 @@ Appliquer une fonction à chaque élément d'une liste.
|
|||||||
```python
|
```python
|
||||||
f = lambda x: x*5
|
f = lambda x: x*5
|
||||||
liste = [2, 7, -1]
|
liste = [2, 7, -1]
|
||||||
resultat = map(f, liste)
|
resultat = list(map(f, liste)) # [10, 35, -5]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
*Remarque : `map` renvoie un itérateur, pas une liste. Sans le `list()`, un `print(resultat)` afficherait `<map object at 0x...>`.*
|
||||||
|
|
||||||
__La réduction__
|
__La réduction__
|
||||||
|
|
||||||
Combiner les éléments d’une liste en appliquant une fonction à l’aide d’un accumulateur (à l’état initial, acc prend la première valeur de la liste et x la deuxième, le résultat est stocké dans acc).
|
Combiner les éléments d’une liste en appliquant une fonction à l’aide d’un accumulateur (à l’état initial, acc prend la première valeur de la liste et x la deuxième, le résultat est stocké dans acc).
|
||||||
|
|
||||||
```python
|
```python
|
||||||
|
import functools
|
||||||
|
|
||||||
liste = [1, 3, 5, 6, 2]
|
liste = [1, 3, 5, 6, 2]
|
||||||
f_somme = lambda acc, x: acc + x
|
f_somme = lambda acc, x: acc + x
|
||||||
somme = functools.reduce(f_somme, liste)
|
somme = functools.reduce(f_somme, liste) # 17
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
@@ -197,7 +203,7 @@ Sélectionne les éléments d'une liste vérifiant un certain critère.
|
|||||||
```python
|
```python
|
||||||
liste = [1, 3, 5, 6, 2]
|
liste = [1, 3, 5, 6, 2]
|
||||||
f_filtre = lambda x: x >= 3
|
f_filtre = lambda x: x >= 3
|
||||||
liste_filtree = filter(f_filtre, liste)
|
liste_filtree = list(filter(f_filtre, liste)) # [3, 5, 6]
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Boucler en programmation fonctionnelle
|
#### Boucler en programmation fonctionnelle
|
||||||
@@ -451,7 +457,7 @@ Voici une tâche simple : nous voulons faire cuire des pâtes.
|
|||||||
|
|
||||||
------
|
------
|
||||||
|
|
||||||
Auteurs : Florian Mathieu, Enzo Frémeaux, Thimothée Decooster
|
Auteurs : Florian Mathieu, Enzo Frémeaux, Timothée Decoster
|
||||||
|
|
||||||
Licence CC BY NC
|
Licence CC BY NC
|
||||||
|
|
||||||
|
|||||||
@@ -406,7 +406,7 @@ print(f"Somme : {total}") # 15
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
Auteurs : Florian Mathieu, Enzo Frémeaux, Thimothée Decooster
|
Auteurs : Florian Mathieu, Enzo Frémeaux, Timothée Decoster
|
||||||
|
|
||||||
Licence CC BY NC
|
Licence CC BY NC
|
||||||
|
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ L'utilisateur a l'impression que les programmes s'exécutent simultanément grâ
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
Auteurs : Florian Mathieu, Enzo Frémeaux, Thimothée Decooster
|
Auteurs : Florian Mathieu, Enzo Frémeaux, Timothée Decoster
|
||||||
|
|
||||||
Licence CC BY NC
|
Licence CC BY NC
|
||||||
|
|
||||||
|
|||||||
@@ -49,7 +49,7 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
Auteurs : Florian Mathieu, Enzo Frémeaux, Thimothée Decooster
|
Auteurs : Florian Mathieu, Enzo Frémeaux, Timothée Decoster
|
||||||
|
|
||||||
Licence CC BY NC
|
Licence CC BY NC
|
||||||
|
|
||||||
|
|||||||
BIN
Processus/HEUeaOHX0AA1EBP.jpeg
Normal file
BIN
Processus/HEUeaOHX0AA1EBP.jpeg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 244 KiB |
@@ -18,9 +18,16 @@ Tous ces programmes sont en réalité des lignes immenses de code et le processe
|
|||||||
|
|
||||||
## 1. Notion de processus
|
## 1. Notion de processus
|
||||||
|
|
||||||
Lorsqu'un programme est exécuté, il crée plusieurs processus. En effet, un programme est composé de diverses instructions (lignes de code) qui elles-mêmes forment diverses parties (processus) de celui-ci.
|
Un **processus** est un programme **en cours d'exécution** : lorsqu'on lance un programme, le système d'exploitation crée un processus, c'est-à-dire une instance vivante du programme avec tout ce dont elle a besoin (instructions chargées en mémoire, données, ressources allouées).
|
||||||
|
|
||||||
Ces processus sont donc stockés dans une file (tout cela est géré par l'OS [Rappel 1ère]) et sont exécutés un à un.
|
Il ne faut pas confondre les deux :
|
||||||
|
|
||||||
|
- le **programme** est un fichier statique posé sur le disque (la recette de cuisine) ;
|
||||||
|
- le **processus** est son exécution en mémoire (le plat en train de cuire).
|
||||||
|
|
||||||
|
Un même programme peut d'ailleurs être lancé plusieurs fois et donner plusieurs processus distincts (deux fenêtres du même navigateur, par exemple). Un processus peut aussi créer lui-même d'autres processus, appelés **processus fils**.
|
||||||
|
|
||||||
|
Les processus prêts à s'exécuter sont placés dans une file (tout cela est géré par l'OS [Rappel 1ère]) et le processeur les traite à tour de rôle.
|
||||||
|
|
||||||
*Exemple de répartition de deux programmes par l'OS :*
|
*Exemple de répartition de deux programmes par l'OS :*
|
||||||
|
|
||||||
@@ -57,6 +64,14 @@ Il existe aussi deux autres états :
|
|||||||
|
|
||||||
<img src="assets/etat.png" style="zoom:50%;" />
|
<img src="assets/etat.png" style="zoom:50%;" />
|
||||||
|
|
||||||
|
### L'ordonnanceur
|
||||||
|
|
||||||
|
C'est **l'ordonnanceur** (*scheduler* en anglais), un composant du système d'exploitation, qui décide quel processus prêt devient élu, et pour combien de temps.
|
||||||
|
|
||||||
|
La politique la plus simple est le **tourniquet** (*round-robin*) : chaque processus reçoit à tour de rôle une petite tranche de temps processeur (quelques millisecondes), appelée **quantum**. Quand son quantum est écoulé, le processus élu repasse à l'état prêt et retourne dans la file. C'est cette alternance très rapide qui donne l'illusion que tout s'exécute en même temps.
|
||||||
|
|
||||||
|
D'autres politiques existent (par priorité, par plus court travail d'abord...), c'est ce que vous manipulerez dans le TP Ordonnanceur.
|
||||||
|
|
||||||
## 3. Interblocage :
|
## 3. Interblocage :
|
||||||
|
|
||||||
L'interblocage intervient lorsque plusieurs processus sont bloqués les uns par les autres.
|
L'interblocage intervient lorsque plusieurs processus sont bloqués les uns par les autres.
|
||||||
@@ -176,7 +191,7 @@ Pour voir les processus, ici, on utilisera plutôt **TOP** (dispo sous linux ég
|
|||||||
|
|
||||||
---------
|
---------
|
||||||
|
|
||||||
Auteurs : Florian Mathieu, Enzo Frémeaux, Thimothée Decooster
|
Auteurs : Florian Mathieu, Enzo Frémeaux, Timothée Decoster
|
||||||
|
|
||||||
Licence CC BY NC
|
Licence CC BY NC
|
||||||
|
|
||||||
|
|||||||
@@ -245,19 +245,22 @@ def traitement(motif):
|
|||||||
def morris_pratt(texte, motif):
|
def morris_pratt(texte, motif):
|
||||||
m = len(motif)
|
m = len(motif)
|
||||||
n = len(texte)
|
n = len(texte)
|
||||||
i = 0
|
|
||||||
j = 0
|
|
||||||
sol = [] # Tableau pour stocker les solutions
|
|
||||||
s = traitement(motif) # Pré-traitement du motif
|
s = traitement(motif) # Pré-traitement du motif
|
||||||
while i < m and j < n:
|
sol = [] # Tableau pour stocker les positions trouvées
|
||||||
if i >= 0 and motif[i] != texte[j]:
|
i = 0 # indice dans le motif
|
||||||
i = s[i]
|
j = 0 # indice dans le texte
|
||||||
else:
|
while j < n:
|
||||||
|
if motif[i] == texte[j]:
|
||||||
i += 1
|
i += 1
|
||||||
j += 1
|
j += 1
|
||||||
if i >= m: # Si le motif est présent
|
if i == m: # Le motif est présent
|
||||||
sol.append(j - m) # La position dans le texte est ajoutée à la liste
|
sol.append(j - m) # La position dans le texte est ajoutée à la liste
|
||||||
i = 0 # Une nouvelle recherche commence après le motif trouvé
|
i = s[i - 1] + 1 # On poursuit la recherche (occurrences suivantes)
|
||||||
|
else:
|
||||||
|
if i == 0:
|
||||||
|
j += 1 # Échec dès le premier caractère : on avance dans le texte
|
||||||
|
else:
|
||||||
|
i = s[i - 1] + 1 # On reprend la comparaison au bon endroit du motif
|
||||||
return sol
|
return sol
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -265,9 +268,7 @@ Ici, par rapport à recherche2, on modifie les instructions dans le cas où ***m
|
|||||||
|
|
||||||
Dans le programme naïf, les indices i et j sont modifiés par ***j = j - i + 1*** pour décaler le motif d'une unité et ***i = 0*** pour recommencer les comparaisons à partir du premier caractère du motif.
|
Dans le programme naïf, les indices i et j sont modifiés par ***j = j - i + 1*** pour décaler le motif d'une unité et ***i = 0*** pour recommencer les comparaisons à partir du premier caractère du motif.
|
||||||
|
|
||||||
Dans ce nouveau programme, j n'est pas modifié. On reste donc sur le caractère posant problème, on ne revient pas en arrière.
|
Dans ce nouveau programme, j ne revient jamais en arrière : en cas d'échec à la position i du motif, ce sont les i premiers caractères du motif qui ont coïncidé. Le tableau s nous dit alors où reprendre : ***s[i - 1] + 1*** est la nouvelle valeur de i (la longueur du plus long bord du préfixe déjà reconnu). Si l'échec a lieu dès le premier caractère (i = 0), on avance simplement dans le texte.
|
||||||
|
|
||||||
Pour la valeur de i, qui permet d'effectuer le bon décalage, on effectue une fois le traitement s = traitement (motif), s est alors un tableau, et s[i] est la nouvelle valeur de i.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ Si un routeur (et donc un réseau) n'est plus accessible passé 3 minutes, il se
|
|||||||
- Au-delà de 15 sauts, on considère un routeur inaccessible.
|
- Au-delà de 15 sauts, on considère un routeur inaccessible.
|
||||||
- Utilise l’algorithme à vecteur de distance de Bellman-Ford et est simple à configurer, mais limité en performance.
|
- Utilise l’algorithme à vecteur de distance de Bellman-Ford et est simple à configurer, mais limité en performance.
|
||||||
- Convient aux petits réseaux
|
- Convient aux petits réseaux
|
||||||
- Premier algorithme de routage de l'histoire
|
- L'un des premiers protocoles de routage déployés à grande échelle (années 1980)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -97,6 +97,8 @@ Exemple de masque de sous-réseau en IPv4 :
|
|||||||
- `255.255.0.0` (notation `/16`) → 65 536 adresses possibles
|
- `255.255.0.0` (notation `/16`) → 65 536 adresses possibles
|
||||||
- `255.0.0.0` (notation `/8`) → 16 777 216 adresses possibles
|
- `255.0.0.0` (notation `/8`) → 16 777 216 adresses possibles
|
||||||
|
|
||||||
|
> **Attention** : parmi ces adresses, deux sont réservées et ne peuvent pas être attribuées à des machines : l'adresse du **réseau** (partie hôte à 0) et l'adresse de **diffusion** ou *broadcast* (partie hôte à 1). Un réseau en `/24` peut donc accueillir 256 - 2 = **254 machines**. C'est un calcul classique au bac !
|
||||||
|
|
||||||
Chaque **bit à 1** dans le masque représente la partie réseau, et chaque **bit à 0** représente la partie hôte.
|
Chaque **bit à 1** dans le masque représente la partie réseau, et chaque **bit à 0** représente la partie hôte.
|
||||||
|
|
||||||
#### Calcul d’un sous-réseau
|
#### Calcul d’un sous-réseau
|
||||||
|
|||||||
@@ -232,9 +232,9 @@ Le recyclage des composants électroniques reste un défi :
|
|||||||
|
|
||||||
L'architecture des SoC connaît en 2025-2026 une rupture majeure : les puces ne sont plus seulement conçues pour le calcul généraliste ou le graphisme, mais pour **exécuter des modèles d'intelligence artificielle localement**, sans passer par le cloud.
|
L'architecture des SoC connaît en 2025-2026 une rupture majeure : les puces ne sont plus seulement conçues pour le calcul généraliste ou le graphisme, mais pour **exécuter des modèles d'intelligence artificielle localement**, sans passer par le cloud.
|
||||||
|
|
||||||
### 6.1. Nvidia RTX Spark (2026)
|
### 6.1. Nvidia DGX Spark (2025)
|
||||||
|
|
||||||
Annoncé au Computex 2026, le **Nvidia RTX Spark** est un superchip qui illustre parfaitement l'évolution vers les SoC unifiés hautes performances.
|
Annoncé sous le nom « Project DIGITS » au CES de janvier 2025, puis rebaptisé au GTC de mars 2025, le **Nvidia DGX Spark** est un superchip qui illustre parfaitement l'évolution vers les SoC unifiés hautes performances.
|
||||||
|
|
||||||
**Architecture :**
|
**Architecture :**
|
||||||
|
|
||||||
@@ -243,27 +243,27 @@ Annoncé au Computex 2026, le **Nvidia RTX Spark** est un superchip qui illustre
|
|||||||
| CPU | 20 cœurs ARM Grace (Neoverse V2), co-développé avec MediaTek |
|
| CPU | 20 cœurs ARM Grace (Neoverse V2), co-développé avec MediaTek |
|
||||||
| GPU | Blackwell - 6 144 CUDA cores, Tensor Cores Gen 5 |
|
| GPU | Blackwell - 6 144 CUDA cores, Tensor Cores Gen 5 |
|
||||||
| Mémoire | Jusqu'à 128 Go de LPDDR5X **unifiée** (partagée CPU/GPU) |
|
| Mémoire | Jusqu'à 128 Go de LPDDR5X **unifiée** (partagée CPU/GPU) |
|
||||||
| Bande passante | ~300 Go/s |
|
| Bande passante | 273 Go/s |
|
||||||
| Interconnexion | NVLink-C2C (technologie issue des serveurs Nvidia) |
|
| Interconnexion | NVLink-C2C (technologie issue des serveurs Nvidia) |
|
||||||
| Performances IA | 1 petaflop en FP4, modèles jusqu'à 120 milliards de paramètres |
|
| Performances IA | 1 petaflop en FP4, modèles jusqu'à 200 milliards de paramètres |
|
||||||
|
|
||||||
> **Lien avec le cours :** Le RTX Spark est un SoC au sens strict - CPU, GPU et mémoire sur la même puce, reliés par un bus interne ultra-rapide (NVLink-C2C). La mémoire unifiée signifie que CPU et GPU accèdent aux mêmes données sans copie, ce qui élimine un goulot d'étranglement classique.
|
> **Lien avec le cours :** Le DGX Spark est un SoC au sens strict - CPU, GPU et mémoire sur la même puce, reliés par un bus interne ultra-rapide (NVLink-C2C). La mémoire unifiée signifie que CPU et GPU accèdent aux mêmes données sans copie, ce qui élimine un goulot d'étranglement classique.
|
||||||
|
|
||||||
**Ce qui est nouveau :**
|
**Ce qui est nouveau :**
|
||||||
|
|
||||||
- **ARM + GPU Nvidia** : la convergence ARM/GPU, déjà amorcée par Apple (M-series), s'étend au monde PC et gaming.
|
- **ARM + GPU Nvidia** : la convergence ARM/GPU, déjà amorcée par Apple (M-series), s'étend au monde PC et gaming.
|
||||||
- **IA locale** : exécuter un modèle de 120 milliards de paramètres sur un laptop (l'équivalent de GPT-3) sans connexion internet était impensable en 2023.
|
- **IA locale** : exécuter un modèle de 200 milliards de paramètres sur une machine de bureau compacte (plus grand que GPT-3 et ses 175 milliards) sans connexion internet était impensable en 2023.
|
||||||
- **Usage prévu** : agents IA personnels, création de contenu (Adobe), gaming 1440p avec ray tracing et DLSS.
|
- **Usage prévu** : agents IA personnels, création de contenu (Adobe), gaming 1440p avec ray tracing et DLSS.
|
||||||
|
|
||||||
*Disponibilité : laptops et mini-PC prévus pour l'automne 2026.*
|
*Disponibilité : commercialisé depuis fin 2025 sous forme de mini-PC de bureau (15 cm × 15 cm).*
|
||||||
|
|
||||||
### 6.2. Contexte : la course aux puces IA
|
### 6.2. Contexte : la course aux puces IA
|
||||||
|
|
||||||
Le RTX Spark s'inscrit dans une tendance plus large :
|
Le DGX Spark s'inscrit dans une tendance plus large :
|
||||||
|
|
||||||
| Fabricant | Puce | Spécialité |
|
| Fabricant | Puce | Spécialité |
|
||||||
|-----------|------|------------|
|
|-----------|------|------------|
|
||||||
| **Nvidia** | RTX Spark (2026) | IA + gaming, ARM + Blackwell, usage personnel |
|
| **Nvidia** | DGX Spark (2025) | IA locale, ARM + Blackwell, usage personnel |
|
||||||
| **Apple** | M4 Pro/Max (2024) | SoC universel, efficacité énergétique, écosystème Apple |
|
| **Apple** | M4 Pro/Max (2024) | SoC universel, efficacité énergétique, écosystème Apple |
|
||||||
| **Qualcomm** | Snapdragon X Elite (2024) | PC Windows ARM, NPU 45 TOPS |
|
| **Qualcomm** | Snapdragon X Elite (2024) | PC Windows ARM, NPU 45 TOPS |
|
||||||
| **AMD** | Strix Halo (2025) | x86 + GPU RDNA4, gaming portable |
|
| **AMD** | Strix Halo (2025) | x86 + GPU RDNA4, gaming portable |
|
||||||
@@ -276,11 +276,11 @@ Le RTX Spark s'inscrit dans une tendance plus large :
|
|||||||
|
|
||||||
### 6.3. Exercice d'actualité
|
### 6.3. Exercice d'actualité
|
||||||
|
|
||||||
Le RTX Spark intègre 20 cœurs ARM alors que les PC traditionnels utilisent du x86 (Intel/AMD).
|
Le DGX Spark intègre 20 cœurs ARM alors que les PC traditionnels utilisent du x86 (Intel/AMD).
|
||||||
|
|
||||||
1. En vous appuyant sur la section 3 (ARM vs x86), expliquer pourquoi Nvidia a choisi ARM plutôt que x86 pour ce superchip.
|
1. En vous appuyant sur la section 3 (ARM vs x86), expliquer pourquoi Nvidia a choisi ARM plutôt que x86 pour ce superchip.
|
||||||
2. La mémoire du RTX Spark est dite "unifiée". En quoi cela diffère-t-il de l'architecture Von Neumann vue en Première, où CPU et GPU ont chacun leur propre mémoire ?
|
2. La mémoire du DGX Spark est dite "unifiée". En quoi cela diffère-t-il de l'architecture Von Neumann vue en Première, où CPU et GPU ont chacun leur propre mémoire ?
|
||||||
3. "1 petaflop = 10¹⁵ opérations par seconde." Un modèle d'IA de 120 milliards de paramètres nécessite environ 240 milliards d'opérations pour générer un seul token. Combien de tokens par seconde le RTX Spark peut-il théoriquement produire ?
|
3. "1 petaflop = 10¹⁵ opérations par seconde." Un modèle d'IA de 200 milliards de paramètres nécessite environ 400 milliards d'opérations pour générer un seul token. Combien de tokens par seconde le DGX Spark peut-il théoriquement produire ?
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ Une pile est une structure de données dans laquelle les derniers éléments ent
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
Ici seul le premier élément est accessible.
|
Ici, seul le **sommet** de la pile (le dernier élément empilé) est accessible.
|
||||||
|
|
||||||
### 3. 2. Interface
|
### 3. 2. Interface
|
||||||
|
|
||||||
@@ -95,7 +95,7 @@ La suite du chapitre se concentrera sur l'utilisation de ces structures et leurs
|
|||||||
|
|
||||||
---------
|
---------
|
||||||
|
|
||||||
Auteurs : Florian Mathieu, Enzo Frémeaux, Thimothée Decooster
|
Auteurs : Florian Mathieu, Enzo Frémeaux, Timothée Decoster
|
||||||
|
|
||||||
Licence CC BY NC
|
Licence CC BY NC
|
||||||
|
|
||||||
|
|||||||
@@ -174,7 +174,7 @@ Enfile(8)
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
Auteurs : Florian Mathieu, Enzo Frémeaux, Thimothée Decooster
|
Auteurs : Florian Mathieu, Enzo Frémeaux, Timothée Decoster
|
||||||
|
|
||||||
Licence CC BY NC
|
Licence CC BY NC
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ Le but du TD est de manipuler des piles et des files sans avoir d'implémentatio
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
Auteurs : Florian Mathieu, Enzo Frémeaux, Thimothée Decooster
|
Auteurs : Florian Mathieu, Enzo Frémeaux, Timothée Decoster
|
||||||
|
|
||||||
Licence CC BY NC
|
Licence CC BY NC
|
||||||
|
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ Un fichier carte.py contient la classe carte et les fonctions suivantes :
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
Auteurs : Florian Mathieu, Enzo Frémeaux, Thimothée Decooster
|
Auteurs : Florian Mathieu, Enzo Frémeaux, Timothée Decoster
|
||||||
|
|
||||||
Licence CC BY NC
|
Licence CC BY NC
|
||||||
|
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ Le but ici est de trier une pile. Pour cela nous utiliserons une autre pile temp
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
Auteurs : Florian Mathieu, Enzo Frémeaux, Thimothée Decooster
|
Auteurs : Florian Mathieu, Enzo Frémeaux, Timothée Decoster
|
||||||
|
|
||||||
Licence CC BY NC
|
Licence CC BY NC
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user