Séance du 9/01

This commit is contained in:
Klafyvel 2018-01-09 17:53:28 +01:00
parent 4e5bea7322
commit 3c48f975b2
23 changed files with 434 additions and 134 deletions

View file

@ -0,0 +1,6 @@
\relax
\select@language{french}
\@writefile{toc}{\select@language{french}}
\@writefile{lof}{\select@language{french}}
\@writefile{lot}{\select@language{french}}
\@writefile{toc}{\contentsline {part}{I\hspace {1em}Objectifs de ce TL}{3}}

View file

@ -0,0 +1 @@
\select@language {french}

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,25 @@
\documentclass[french]{article}
\usepackage{pgfplots}
\usepackage{tikz}
\usetikzlibrary{arrows,automata}
\usepackage{MyPack2}
\usepackage{diagbox}
\geometry{top=2cm, bottom=2cm, left=2cm, right=2cm}
\title{Étude de laboratoire - ASD}
\author{Binôme A11 \\ \bsc{Simon} Léo, \bsc{Levy--Falk} Hugo \\ Supélec, promo 2020}
\date{\today}
\begin{document}
\maketitle
\tableofcontents
\clearpage
\listoffigures
\newpage
\initPage{TL - ASD}{\today}{\bsc{Simon}, \bsc{Levy--Falk}}
\part{Objectifs de ce TL}
\end{document}

View file

@ -0,0 +1,2 @@
\select@language {french}
\contentsline {part}{I\hspace {1em}Objectifs de ce TL}{3}

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

BIN
compte_rendu/images/3_6.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

View file

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 36 KiB

View file

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

View file

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

View file

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

View file

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 34 KiB

146
graphe.py
View file

@ -1,10 +1,15 @@
import random import random
import triangulation import triangulation
import tas
class Graphe: class Graphe:
"""Implémente un graphe non orienté.""" """Implémente un graphe non orienté."""
class Cout:
CARBURANT = 0
TEMPS = 1
def __init__(self, nom): def __init__(self, nom):
"""Initialise un graphe vide. """Initialise un graphe vide.
@ -13,6 +18,7 @@ class Graphe:
self.nom = nom self.nom = nom
self.sommets = [] self.sommets = []
self.aretes = [] self.aretes = []
self.cout = Graphe.Cout.TEMPS
def renomme(self, nom): def renomme(self, nom):
"""Renome le graphe """Renome le graphe
@ -43,7 +49,7 @@ class Graphe:
:return: L'arête créée. :return: L'arête créée.
""" """
a = Arete(s1, s2, longueur, v_moyenne) a = Arete(s1, s2, longueur, v_moyenne, self)
self.aretes.append(a) self.aretes.append(a)
return a return a
@ -67,6 +73,7 @@ class Graphe:
:param dest: instance de Afficheur. :param dest: instance de Afficheur.
""" """
dest.renomme(self.nom)
for s in self.sommets: for s in self.sommets:
dest.changeCouleur(s.couleur) dest.changeCouleur(s.couleur)
dest.tracePoint((s.x(), s.y())) dest.tracePoint((s.x(), s.y()))
@ -111,6 +118,123 @@ class Graphe:
a.couleur = (1., 1., 0.) a.couleur = (1., 1., 0.)
return a return a
def dijkstra(self, depart=None):
"""Calcule les plus courts chemins depuis le sommet `depart` (attention,
effets de bord).
:param depart: Sommet de départ.
"""
for s in self.sommets:
s.cumul = None
s.precedent = None
sommets = [depart or self.sommets[0]]
sommets[0].cumul = 0
while sommets:
i, s = min(enumerate(sommets), key=lambda x: x[1].cumul)
sommets.pop(i)
for arete in s.aretes:
voisin = arete.voisin(s)
if voisin.cumul is None: # cumul infini
sommets.append(voisin)
if voisin.cumul is None or s.cumul + arete.cout < voisin.cumul:
voisin.cumul = s.cumul + arete.cout
voisin.precedent = arete
def dijkstraAvecTas(self, depart=None):
"""Calcule les plus courts chemins depuis le sommet `depart` (attention,
effets de bord).
:param depart: Sommet de départ.
"""
for s in self.sommets:
s.cumul = None
s.precedent = None
sommets = tas.Tas(lambda x: -x.cumul)
depart = depart or self.sommets[0]
depart.cumul = 0
depart.cle = sommets.ajoute(depart)
while not sommets.empty():
s = sommets.pop()
for arete in s.aretes:
voisin = arete.voisin(s)
inf = voisin.cumul is None
if inf or s.cumul + arete.cout < voisin.cumul:
voisin.cumul = s.cumul + arete.cout
if inf: # cumul infini
voisin.cle = sommets.ajoute(voisin)
else:
sommets.actualise(voisin.cle)
voisin.precedent = arete
def dijkstraPartiel(self, depart, arrivee):
"""Calcule les plus courts chemins depuis le sommet `depart` vers
`arrivee` (attention, effets de bord).
:param depart: Sommet de départ.
"""
for s in self.sommets:
s.cumul = None
s.precedent = None
sommets = tas.Tas(lambda x: -x.cumul)
depart = depart or self.sommets[0]
depart.cumul = 0
depart.cle = sommets.ajoute(depart)
while not sommets.empty():
s = sommets.pop()
for arete in s.aretes:
voisin = arete.voisin(s)
inf = voisin.cumul is None
if inf or s.cumul + arete.cout < voisin.cumul:
voisin.cumul = s.cumul + arete.cout
if inf: # cumul infini
voisin.cle = sommets.ajoute(voisin)
else:
sommets.actualise(voisin.cle)
voisin.precedent = arete
def traceArbreDesChemins(self):
"""Change la couleur des chemins optimaux en violet-rose
(252, 17, 189) et le départ en bleu (10, 98, 252).
"""
for s in self.sommets:
if s.precedent:
s.precedent.couleur = (252/255, 17/255, 189/255)
if not s.cumul: # sommet de départ
s.couleur = (10/255, 98/255, 252/255)
def fixeCarburantCommeCout(self):
"""Fixe le carburant pour cout lors du calcul de plus court chemin."""
self.cout = Graphe.Cout.CARBURANT
def fixeTempsCommeCout(self):
"""Fixe le temps pour cout lors du calcul de plus court chemin."""
self.cout = Graphe.Cout.TEMPS
def cheminOptimal(self, arrivee):
"""Donne le chemin optimal pour aller à `arrivee` depuis le point
de départ donné à `dijkstra`.
:param arrivee: Sommet d'arrivee
:return: le chemin (liste des arêtes)
"""
chemin = []
suivant = arrivee
while suivant.cumul:
chemin.append(suivant.precedent)
suivant = suivant.precedent.voisin(suivant)
chemin.reverse()
return chemin
def colorieChemin(self, chemin, c):
"""Colorie le chemin.
:param chemin: une liste d'arrêtes
:param c: une couleur
"""
for a in chemin:
a.couleur = c
class Sommet: class Sommet:
"""Implémente un sommet de graphe.""" """Implémente un sommet de graphe."""
@ -125,6 +249,9 @@ class Sommet:
self.pos = pos self.pos = pos
self.num = num self.num = num
self.couleur = couleur self.couleur = couleur
self.aretes = set()
self.cumul = None
self.precedent = None
def __str__(self): def __str__(self):
return "v{} (x = {} km y = {} km)".format( return "v{} (x = {} km y = {} km)".format(
@ -152,7 +279,8 @@ class Sommet:
class Arete: class Arete:
"""Implémente une arête de graphe.""" """Implémente une arête de graphe."""
def __init__(self, s1, s2, longueur, v_moyenne, couleur=(0., 0., 0.)): def __init__(
self, s1, s2, longueur, v_moyenne, graph, couleur=(0., 0., 0.)):
"""Initialise une arête. """Initialise une arête.
:param s1: sommet 1. :param s1: sommet 1.
@ -160,12 +288,16 @@ class Arete:
:param longueur: longueur de l'arête. :param longueur: longueur de l'arête.
:param v_moyenne: vitesse moyenne sur l'arête. :param v_moyenne: vitesse moyenne sur l'arête.
:param couleur: couleur de l'arête. :param couleur: couleur de l'arête.
:param graph: le graphe de l'arête.
""" """
self.s1 = s1 self.s1 = s1
self.s2 = s2 self.s2 = s2
s1.aretes.add(self)
s2.aretes.add(self)
self.longueur = longueur self.longueur = longueur
self.v_moyenne = v_moyenne self.v_moyenne = v_moyenne
self.couleur = couleur self.couleur = couleur
self.graph = graph
def voisin(self, s): def voisin(self, s):
"""Retourne le sommet voisin de s dans l'arête. """Retourne le sommet voisin de s dans l'arête.
@ -177,6 +309,16 @@ class Arete:
else: else:
return self.s1 return self.s1
@property
def cout(self):
"""Retourne le cout de l'arête."""
if self.graph.cout is Graphe.Cout.TEMPS:
return self.longueur / self.v_moyenne
elif self.graph.cout is Graphe.Cout.CARBURANT:
return self.longueur
else:
return 1
def __str__(self): def __str__(self):
return " v{v1}, v{v2} (long. = {lon} km vlim. = {v} km/h)".format( return " v{v1}, v{v2} (long. = {lon} km vlim. = {v} km/h)".format(
v1=str(self.s1.num), v1=str(self.s1.num),

View file

@ -30,7 +30,7 @@ class Afficheur(qtgui.QWidget):
self.centre = np.array(centre) self.centre = np.array(centre)
self.crayon = None self.crayon = None
self.sujet = sujet self.sujet = sujet
self.setStyleSheet("background-color: gray") self.setStyleSheet("background-color: white")
self.center = np.array(Afficheur.size) / 2. self.center = np.array(Afficheur.size) / 2.
self.setGeometry(Afficheur.coord[0] + screen.x(), Afficheur.coord[1] + screen.y(), Afficheur.size[0], Afficheur.size[1]) self.setGeometry(Afficheur.coord[0] + screen.x(), Afficheur.coord[1] + screen.y(), Afficheur.size[0], Afficheur.size[1])
Afficheur.coord += Afficheur.decalage Afficheur.coord += Afficheur.decalage
@ -151,7 +151,7 @@ class Afficheur(qtgui.QWidget):
qtgui.QApplication.quit() qtgui.QApplication.quit()
L = 100.; L = 100.;
x = 20; y = 20; x = 20; y = 20;
self.crayon.setPen('white') self.crayon.setPen('black')
msg = '{0:.2f} km'.format(L / self.ech) msg = '{0:.2f} km'.format(L / self.ech)
l = self.crayon.fontMetrics().boundingRect(msg).width() l = self.crayon.fontMetrics().boundingRect(msg).width()
self.crayon.drawText(x + (L-l)/2, y-2, msg); self.crayon.drawText(x + (L-l)/2, y-2, msg);

6
tas.py
View file

@ -1,5 +1,6 @@
# coding: utf-8 # coding: utf-8
class Tas: class Tas:
class Element: class Element:
def __init__(self, valeur, priorite, index): def __init__(self, valeur, priorite, index):
@ -100,8 +101,10 @@ class Tas:
# Tri de tâches par ordre chronologique # # Tri de tâches par ordre chronologique #
######################################### #########################################
class Tache: class Tache:
'''Tache devant être effectuée avant une date limite''' '''Tache devant être effectuée avant une date limite'''
def __init__(self, jour, nom): def __init__(self, jour, nom):
self.jour = jour self.jour = jour
self.nom = nom self.nom = nom
@ -111,6 +114,7 @@ class Tache:
def __str__(self): def __str__(self):
return self.nom + " ({})".format(self.jour) return self.nom + " ({})".format(self.jour)
if __name__ == "__main__": if __name__ == "__main__":
# Le niveau de priorité d'un événement x est -x.jour : on trie donc les événements par ordre chronologique # Le niveau de priorité d'un événement x est -x.jour : on trie donc les événements par ordre chronologique
@ -132,5 +136,3 @@ if __name__ == "__main__":
# Retirons dans l'ordre chronologie les éléments du tas # Retirons dans l'ordre chronologie les éléments du tas
while(not T.empty()): while(not T.empty()):
print(T.pop()) print(T.pop())

126
test.py
View file

@ -1,3 +1,12 @@
"""Test des fonctions du TL.
Pour tester la question x_y : `python3 test.py x_y`.
Donc pour la question 3_4 : `python3 test.py 3_4`.
"""
import sys
import graphe import graphe
import graphique import graphique
import copy import copy
@ -5,7 +14,6 @@ import numpy as np
import matplotlib.pyplot as pl import matplotlib.pyplot as pl
import time import time
def creerGrapheFigure1(): def creerGrapheFigure1():
""" Crée le graphe de la figure 1 """ """ Crée le graphe de la figure 1 """
g = graphe.Graphe("Graphe de la figure 1") g = graphe.Graphe("Graphe de la figure 1")
@ -159,7 +167,115 @@ def testQuestion2_9():
pl.show() pl.show()
def testQuestion3_1():
"""Trace le plus court chemin avec dijkstra."""
g = graphe.pointsAleatoires(30, 30)
g.renomme("Dijkstra")
graphe.reseauRapide(g)
g.dijkstra(g.sommets[0])
g.traceArbreDesChemins()
graphique.affiche(g, (0, 0), 10.)
def testQuestion3_2():
"""Trace le plus court chemin avec dijkstra."""
g = graphe.pointsAleatoires(30, 30)
g.renomme("Dijkstra")
graphe.reseauRapide(g)
g.fixeTempsCommeCout()
g.dijkstra(g.sommets[0])
g.traceArbreDesChemins()
g.renomme("Temps")
graphique.affiche(g, (0, 0), 10., blocage=False)
g.fixeCarburantCommeCout()
g.dijkstra(g.sommets[0])
g.traceArbreDesChemins()
g.renomme("Carburant")
graphique.affiche(g, (0, 0), 10.)
def testQuestion3_3():
"""Mesure le temps d'exécution de Dijkstra."""
prepare = lambda p : graphe.reseauRapide(graphe.pointsAleatoires(p, 100))
valeurs_n = list(map(lambda x: int(x), np.logspace(1, 4, 10)))
temps = chronometre(graphe.Graphe.dijkstra, prepare, valeurs_n)
pl.close('all')
pl.title("Temps d'exécution en fonction de la taille du graphe.")
pl.plot(valeurs_n, temps, label='reseau')
pl.legend(loc='best')
pl.xlabel("n")
pl.ylabel("temps")
pl.show()
pl.title("Temps d'exécution en fonction de la taille du graphe.")
pl.loglog(valeurs_n, temps, label='reseau')
pl.legend(loc='best')
pl.xlabel("n")
pl.ylabel("temps")
pl.show()
def testQuestion3_4():
"""Trace le plus court chemin avec dijkstra."""
g = graphe.pointsAleatoires(30, 30)
g.renomme("Plus court chemin")
graphe.reseauRapide(g)
g.fixeTempsCommeCout()
g.dijkstra(g.sommets[0])
c = g.cheminOptimal(g.sommets[-1])
g.colorieChemin(c, (0.,1.,0.))
g.renomme("Temps")
graphique.affiche(g, (0, 0), 10.)
def testQuestion3_5():
"""Trace le plus court chemin avec dijkstra."""
g = graphe.pointsAleatoires(30, 30)
g.fixeTempsCommeCout()
graphe.reseauRapide(g)
g.dijkstra(g.sommets[0])
g.traceArbreDesChemins()
g.renomme("Liste")
graphique.affiche(g, (0, 0), 10., blocage=False)
g.dijkstraAvecTas(g.sommets[0])
g.traceArbreDesChemins()
g.renomme("Tas")
graphique.affiche(g, (0, 0), 10.)
def testQuestion3_6():
"""Compare Dijkstra avec et sans tas."""
prepare = lambda p : graphe.reseauRapide(graphe.pointsAleatoires(p, 10))
valeurs_n = list(map(lambda x: int(x), np.logspace(1, 3, 10)))
temps1 = chronometre(graphe.Graphe.dijkstra, prepare, valeurs_n)
temps2 = chronometre(graphe.Graphe.dijkstraAvecTas, prepare, valeurs_n)
pl.close('all')
pl.title("Comparaison du temps d'exécution de `dijkstra` et `dijkstraAvecTas`.")
pl.plot(valeurs_n, temps1, label='Dijkstra')
pl.plot(valeurs_n, temps2, label='Dijkstra avec tas')
pl.legend(loc='best')
pl.xlabel("n")
pl.ylabel("temps")
pl.show()
pl.title("Comparaison du temps d'exécution de `reseau` et `reseauRapide`.")
pl.loglog(valeurs_n, temps1, label='Dijkstra')
pl.loglog(valeurs_n, temps2, label='Dijkstra avec tas')
pl.legend(loc='best')
pl.xlabel("n")
pl.ylabel("temps")
pl.show()
if __name__ == '__main__':
n = sys.argv[1]
if n in ('--help', '-h'):
print(__doc__)
else:
print('Question ', n)
locals()['testQuestion'+n]()
# testQuestion1_2() # testQuestion1_2()
# testQuestion1_3() # testQuestion1_3()
# testQuestion1_4() # testQuestion1_4()
@ -169,4 +285,10 @@ def testQuestion2_9():
# testQuestion2_6() # testQuestion2_6()
# testQuestion2_7() # testQuestion2_7()
# testQuestion2_8() # testQuestion2_8()
testQuestion2_9() # testQuestion2_9()
# testQuestion3_1()
# testQuestion3_2()
# testQuestion3_3()
# testQuestion3_4()
# testQuestion3_5()
# testQuestion3_6()