Section 2.3: graphes d’objets #
Dans le cas général, des données orientées-objet forme un graphe.
2.3.1 Graphe film/personnage #
On peut compléter ainsi la modélisation des films et celle des personnages présentées aux chapitres précédents.

- Un
Personnageapparaît dans plusieursFilm. - Un
Filmcontient plusieursPersonnage.
Voici un exemple de données se conformant à cette modélisation.

- Le
PersonnageJames Bond apparaît dans deux films : Dr. No et Bon Baisers de Russie. - Le
FilmDr. No contient deux personnages : James Bond et Dr. No.
2.3.2 Exemple : Fibonacci #
Dans le cas général, il n’est pas facile de visualiser un graphe d’objet avec des cartes. Dans notre approche, il est donc nécessaire de s’en tenir à des cas particuliers. Comme exemple, nous développons une modélisation de la séquence de Fibonacci.
2.3.3 Définition #
Voici le début de la suite de Fibonacci :
0 1 1 2 3 5 8 13 21 34 55 89 144 ...
La définition mathématique est récursive :
\( F_0 = 0\\~\\
F_1 = 1\\~\\
F_n = F_{n-1} + F_{n-2}\\~\\
\)
Autrement dit :
0et1sont deux cas spéciaux.Sinon le prochain nombre de la suite est toujours l’addition deux nombres précédents
2.3.4 Nombre d’or #
La suite de Fibonacci est utilisée pour calculer le nombre d’or, soit environ
1.618- Le nombre d’or est reconnu, entre autres choses, comme une proportion hauteur/largeur agréable à l’oeil.
Comme pour π, on peut calculer le nombre d’or avec autant de précision que désirée, c.-à-d. avec autant de chiffres après le point que désiré.
Pour calculer une approximation du nombre d’or, on fait tout simplement :
\( \text{nombre d'or} \approx \dfrac{F_{n}}{F_{n-1}} \text{~~~pour~~~} n\geq 2 \)Plus on prend un
nélevé, plus la précision est bonne.Autrement dit, le nombre d’or est à peu près égal à un nombre de la suite de Fibonacci, divisé par le nombre qui le précède.
- Plus on prend un nombre loin dans la suite, plus l’approximation est bonne
2.3.5 Modéliser la suite de Fibonacci #
- Pour modéliser la suite en Java, on va créer une structure de données récursive :
Pour
n = 0, on a le graphe d’objets suivant :
Pour
n = 1, on a le graphe d’objets suivant :
Pour
n = 2, on a le graphe d’objets suivant :
- NOTE : la suite se lit de droite à gauche.
Pour
n = 3, on a le graphe d’objets suivant :
Et ainsi de suite.
2.3.6 Pour calculer la réponse et le nombre d’or #
Calculer la réponse pour
n >= 2est simple :reponse = moinsUn.getReponse() + moinsDeux.getReponse();Même chose pour le nombre d’or :
nombreOr = Double.valueOf(reponse) / Double.valueOf(moinsUn.getReponse());Le défi est qu’il faut d’abord construire le graphe d’objet.
2.3.7 Construire le graphe d’objets récursivement #
Avec des appels récursifs, on va construire d’abord, puis calculer :
- On crée d’abord l’objet
n, puisn-1, et ainsi de suite jusqu’à l’objet0
- On crée d’abord l’objet
Pour le cas
n >= 2, voici comment procéder :Créer un nouvel objet
MonFibonacciet le mémoriser dansmoinsUnEnregistrer que le
nde cemoinsUnestn-1(lencourant moins1).Créer le reste du graphe récursivement en appelant
moinsUn.construireGrapheRecursivement()Enregister que le
moinsDeuxcourant estmoinsUn.getMoinsUn()(lemoinsUndumoinsUncourant).Calculer la réponse courante à partir des réponses de
moinsUnetmoinsDeux
L’appel récursif est plus proche de la définition mathématique :
- Pour calculer la réponse en
n, il faut d’abord calculer la réponse enn-1
- Pour calculer la réponse en
L’inconvénient est qu’on peut déborder la pile d’appel :
Exception in thread "main" java.lang.StackOverflowError at ca.ntro.cards.fibonacci.solution.MonFibonacci.construireGrapheRecursivement(MonFibonacci.java:31) at ca.ntro.cards.fibonacci.solution.MonFibonacci.construireGrapheRecursivement(MonFibonacci.java:31) at ca.ntro.cards.fibonacci.solution.MonFibonacci.construireGrapheRecursivement(MonFibonacci.java:31) at ca.ntro.cards.fibonacci.solution.MonFibonacci.construireGrapheRecursivement(MonFibonacci.java:31) at ca.ntro.cards.fibonacci.solution.MonFibonacci.construireGrapheRecursivement(MonFibonacci.java:31) at ca.ntro.cards.fibonacci.solution.MonFibonacci.construireGrapheRecursivement(MonFibonacci.java:31) at ca.ntro.cards.fibonacci.solution.MonFibonacci.construireGrapheRecursivement(MonFibonacci.java:31) at ca.ntro.cards.fibonacci.solution.MonFibonacci.construireGrapheRecursivement(MonFibonacci.java:31) at ca.ntro.cards.fibonacci.solution.MonFibonacci.construireGrapheRecursivement(MonFibonacci.java:31) at ca.ntro.cards.fibonacci.solution.MonFibonacci.construireGrapheRecursivement(MonFibonacci.java:31) at ca.ntro.cards.fibonacci.solution.MonFibonacci.construireGrapheRecursivement(MonFibonacci.java:31) at ca.ntro.cards.fibonacci.solution.MonFibonacci.construireGrapheRecursivement(MonFibonacci.java:31) ...- RAPPEL : le code n’est pas bogué, mais limité par la mémoire attribuée à la pile d’appel.
2.3.8 Construire le graphe d’objets dynamiquement #
En programmation dynamique, on calcule en même temps qu’on construit :
- On crée d’abord l’objet
0, puis1, et ainsi de suite jusqu’à l’objetn
- On crée d’abord l’objet
L’idée est qu’on fait une boucle pour créer le graphe d’objets.
On crée une
nouvelleTeteLe
moinsUnde lanouvelleTeteest l’ancienneteteLe
moinsDeuxde lanouvelleTeteest lemoinsUnde l’anciennetete- c.-à-d. on insère la
nouvelleTeteà gauche, et on « pousse » les objets existants vers la droite.
- c.-à-d. on insère la
Pour le cas
n >= 2, voici comment procéder :Pour chaque
iallant de2àn(inclusivement) :Créer un nouvel objet
MonFibonaccipour représenter lanouvelleTeteEnregistrer que le
nde lanouvelleTeteestiEnregistrer que le
moinsUnde lanouvelleTeteest latetecourante.Enregistrer que le
moinsDeuxde lanouvelleTeteest lemoinsUnde latetecourante.Enregistrer que
tetepointe maintenant vers lanouvelleTeteCalculer la réponse pour
tete
Le calcul dynamique est moins intuitif (et moins proche de la définition mathématique), mais on a éliminé l’appel récursif, alors on ne peut plus déborder la pile d’appel.