Séance du 9/01
6
compte_rendu/compte_rendu.aux
Normal 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}}
|
1
compte_rendu/compte_rendu.lof
Normal file
|
@ -0,0 +1 @@
|
||||||
|
\select@language {french}
|
BIN
compte_rendu/compte_rendu.pdf
Normal file
BIN
compte_rendu/compte_rendu.synctex.gz
Normal 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}
|
2
compte_rendu/compte_rendu.toc
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
\select@language {french}
|
||||||
|
\contentsline {part}{I\hspace {1em}Objectifs de ce TL}{3}
|
BIN
compte_rendu/images/3_2_carburant.png
Normal file
After Width: | Height: | Size: 25 KiB |
BIN
compte_rendu/images/3_2_temps.png
Normal file
After Width: | Height: | Size: 25 KiB |
BIN
compte_rendu/images/3_4_chemin.png
Normal file
After Width: | Height: | Size: 26 KiB |
BIN
compte_rendu/images/3_5_liste.png
Normal file
After Width: | Height: | Size: 26 KiB |
BIN
compte_rendu/images/3_5_tas.png
Normal file
After Width: | Height: | Size: 26 KiB |
BIN
compte_rendu/images/3_6.png
Normal file
After Width: | Height: | Size: 40 KiB |
BIN
compte_rendu/images/dijkstra_lin.png
Normal file
After Width: | Height: | Size: 27 KiB |
BIN
compte_rendu/images/dijkstra_log.png
Normal file
After Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 36 KiB |
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
156
graphe.py
|
@ -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,10 +73,11 @@ 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()))
|
||||||
dest.traceTexte((s.x(), s.y()), 'v'+str(s.num))
|
dest.traceTexte((s.x(), s.y()), 'v' + str(s.num))
|
||||||
|
|
||||||
for a in self.aretes:
|
for a in self.aretes:
|
||||||
dest.changeCouleur(a.couleur)
|
dest.changeCouleur(a.couleur)
|
||||||
|
@ -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(
|
||||||
|
@ -138,7 +265,7 @@ class Sommet:
|
||||||
|
|
||||||
:param v: Point de calcul de la distance.
|
:param v: Point de calcul de la distance.
|
||||||
"""
|
"""
|
||||||
return ((self.x()-v.x())**2 + (self.y()-v.y())**2)**(1/2)
|
return ((self.x() - v.x())**2 + (self.y() - v.y())**2)**(1 / 2)
|
||||||
|
|
||||||
def x(self):
|
def x(self):
|
||||||
"""Retourne l'abcisse de x."""
|
"""Retourne l'abcisse de x."""
|
||||||
|
@ -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),
|
||||||
|
@ -195,7 +337,7 @@ def pointsAleatoires(n, L):
|
||||||
"""
|
"""
|
||||||
g = Graphe("Graphe aléatoire")
|
g = Graphe("Graphe aléatoire")
|
||||||
for _ in range(n):
|
for _ in range(n):
|
||||||
x, y = random.uniform(-L/2, L/2), random.uniform(-L/2, L/2)
|
x, y = random.uniform(-L / 2, L / 2), random.uniform(-L / 2, L / 2)
|
||||||
g.ajouteSommet(x, y)
|
g.ajouteSommet(x, y)
|
||||||
return g
|
return g
|
||||||
|
|
||||||
|
@ -207,8 +349,8 @@ def test_gabriel(g, v1, v2):
|
||||||
:param v1: Premier sommet.
|
:param v1: Premier sommet.
|
||||||
:param v2: Deuxième sommet.
|
:param v2: Deuxième sommet.
|
||||||
"""
|
"""
|
||||||
milieu = Sommet(((v1.x()+v2.x())/2, (v1.y()+v2.y())/2), -1)
|
milieu = Sommet(((v1.x() + v2.x()) / 2, (v1.y() + v2.y()) / 2), -1)
|
||||||
rayon = v1.distance(v2)/2
|
rayon = v1.distance(v2) / 2
|
||||||
ajoute = True
|
ajoute = True
|
||||||
for v3 in g.sommets:
|
for v3 in g.sommets:
|
||||||
if v3 in [v1, v2]:
|
if v3 in [v1, v2]:
|
||||||
|
|
|
@ -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);
|
||||||
|
|
248
tas.py
|
@ -1,136 +1,138 @@
|
||||||
# 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):
|
||||||
self.valeur = valeur
|
self.valeur = valeur
|
||||||
self.priorite = priorite
|
self.priorite = priorite
|
||||||
self.index = index
|
self.index = index
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return str(self.valeur)
|
return str(self.valeur)
|
||||||
|
|
||||||
def __init__(self, fonctionPriorite):
|
|
||||||
self.L = []
|
|
||||||
self.fonctionPriorite = fonctionPriorite
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
s = "["
|
|
||||||
for elt in self.L:
|
|
||||||
s += " " + str(elt)
|
|
||||||
s += "]"
|
|
||||||
return s
|
|
||||||
|
|
||||||
def __parent(self, elt):
|
|
||||||
if(elt.index == 0):
|
|
||||||
return None
|
|
||||||
else:
|
|
||||||
return self.L[(elt.index-1) // 2]
|
|
||||||
|
|
||||||
def __fils_gauche(self, elt):
|
|
||||||
i = 2 * elt.index + 1
|
|
||||||
if(i < len(self.L)):
|
|
||||||
return self.L[i]
|
|
||||||
else:
|
|
||||||
return None
|
|
||||||
|
|
||||||
def __fils_droit(self, elt):
|
def __init__(self, fonctionPriorite):
|
||||||
i = 2 * elt.index + 2
|
self.L = []
|
||||||
if(i < len(self.L)):
|
self.fonctionPriorite = fonctionPriorite
|
||||||
return self.L[i]
|
|
||||||
else:
|
def __str__(self):
|
||||||
return None
|
s = "["
|
||||||
|
for elt in self.L:
|
||||||
def __deplace(self, elt, index):
|
s += " " + str(elt)
|
||||||
assert isinstance(elt, Tas.Element)
|
s += "]"
|
||||||
ancien = elt.index
|
return s
|
||||||
self.L[index] = elt
|
|
||||||
elt.index = index
|
def __parent(self, elt):
|
||||||
return ancien
|
if(elt.index == 0):
|
||||||
|
return None
|
||||||
def __promeut(self, elt):
|
else:
|
||||||
while(True):
|
return self.L[(elt.index - 1) // 2]
|
||||||
parent = self.__parent(elt)
|
|
||||||
if(parent == None):
|
def __fils_gauche(self, elt):
|
||||||
break
|
i = 2 * elt.index + 1
|
||||||
if(parent.priorite >= elt.priorite):
|
if(i < len(self.L)):
|
||||||
break
|
return self.L[i]
|
||||||
elt.index = self.__deplace(parent, elt.index)
|
else:
|
||||||
self.__deplace(elt, elt.index)
|
return None
|
||||||
|
|
||||||
def actualise(self, elt):
|
def __fils_droit(self, elt):
|
||||||
assert isinstance(elt, Tas.Element)
|
i = 2 * elt.index + 2
|
||||||
elt.priorite = self.fonctionPriorite(elt.valeur)
|
if(i < len(self.L)):
|
||||||
self.__promeut(elt)
|
return self.L[i]
|
||||||
|
else:
|
||||||
def ajoute(self, valeur):
|
return None
|
||||||
elt = Tas.Element(valeur, self.fonctionPriorite(valeur), len(self.L))
|
|
||||||
self.L.append(elt)
|
def __deplace(self, elt, index):
|
||||||
self.__promeut(elt)
|
assert isinstance(elt, Tas.Element)
|
||||||
return elt
|
ancien = elt.index
|
||||||
|
self.L[index] = elt
|
||||||
def empty(self):
|
elt.index = index
|
||||||
return len(self.L) == 0
|
return ancien
|
||||||
|
|
||||||
def pop(self):
|
def __promeut(self, elt):
|
||||||
n = len(self.L)
|
while(True):
|
||||||
if(n == 0):
|
parent = self.__parent(elt)
|
||||||
return None
|
if(parent == None):
|
||||||
|
break
|
||||||
tete = self.L[0]
|
if(parent.priorite >= elt.priorite):
|
||||||
elt = self.L[n - 1]
|
break
|
||||||
elt.index = 0
|
elt.index = self.__deplace(parent, elt.index)
|
||||||
|
self.__deplace(elt, elt.index)
|
||||||
while True:
|
|
||||||
filsGauche = self.__fils_gauche(elt)
|
def actualise(self, elt):
|
||||||
filsDroit = self.__fils_droit(elt)
|
assert isinstance(elt, Tas.Element)
|
||||||
plusPrioritaire = elt
|
elt.priorite = self.fonctionPriorite(elt.valeur)
|
||||||
if(filsGauche != None and filsGauche.priorite > plusPrioritaire.priorite):
|
self.__promeut(elt)
|
||||||
plusPrioritaire = filsGauche
|
|
||||||
if(filsDroit != None and filsDroit.priorite > plusPrioritaire.priorite):
|
def ajoute(self, valeur):
|
||||||
plusPrioritaire = filsDroit
|
elt = Tas.Element(valeur, self.fonctionPriorite(valeur), len(self.L))
|
||||||
elt.index = self.__deplace(plusPrioritaire, elt.index)
|
self.L.append(elt)
|
||||||
if(plusPrioritaire is elt):
|
self.__promeut(elt)
|
||||||
break
|
return elt
|
||||||
self.L.pop()
|
|
||||||
return tete.valeur
|
def empty(self):
|
||||||
|
return len(self.L) == 0
|
||||||
|
|
||||||
|
def pop(self):
|
||||||
|
n = len(self.L)
|
||||||
|
if(n == 0):
|
||||||
|
return None
|
||||||
|
|
||||||
|
tete = self.L[0]
|
||||||
|
elt = self.L[n - 1]
|
||||||
|
elt.index = 0
|
||||||
|
|
||||||
|
while True:
|
||||||
|
filsGauche = self.__fils_gauche(elt)
|
||||||
|
filsDroit = self.__fils_droit(elt)
|
||||||
|
plusPrioritaire = elt
|
||||||
|
if(filsGauche != None and filsGauche.priorite > plusPrioritaire.priorite):
|
||||||
|
plusPrioritaire = filsGauche
|
||||||
|
if(filsDroit != None and filsDroit.priorite > plusPrioritaire.priorite):
|
||||||
|
plusPrioritaire = filsDroit
|
||||||
|
elt.index = self.__deplace(plusPrioritaire, elt.index)
|
||||||
|
if(plusPrioritaire is elt):
|
||||||
|
break
|
||||||
|
self.L.pop()
|
||||||
|
return tete.valeur
|
||||||
|
|
||||||
#########################################
|
#########################################
|
||||||
# Exemple d'utilisatio de la classe Tas #
|
# Exemple d'utilisatio de la classe 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):
|
|
||||||
self.jour = jour
|
def __init__(self, jour, nom):
|
||||||
self.nom = nom
|
self.jour = jour
|
||||||
# Cet attribut servira à accueillir la clé du tas
|
self.nom = nom
|
||||||
self.cle = None
|
# Cet attribut servira à accueillir la clé du tas
|
||||||
|
self.cle = None
|
||||||
def __str__(self):
|
|
||||||
return self.nom + " ({})".format(self.jour)
|
def __str__(self):
|
||||||
|
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
|
||||||
def calculePriorite(tache):
|
def calculePriorite(tache):
|
||||||
return -tache.jour
|
return -tache.jour
|
||||||
|
|
||||||
# On crée un tas dont les éléments sont des événements triés par ordre chronologique
|
# On crée un tas dont les éléments sont des événements triés par ordre chronologique
|
||||||
T = Tas(calculePriorite)
|
T = Tas(calculePriorite)
|
||||||
|
|
||||||
# Ajoute des événements au tas
|
# Ajoute des événements au tas
|
||||||
evts = [ Tache(5, "T1"), Tache(10, "T2"), Tache(5, "T3"), Tache(3, "T4")]
|
evts = [Tache(5, "T1"), Tache(10, "T2"), Tache(5, "T3"), Tache(3, "T4")]
|
||||||
for evt in evts:
|
for evt in evts:
|
||||||
evt.cle = T.ajoute(evt)
|
evt.cle = T.ajoute(evt)
|
||||||
|
|
||||||
# Supposons que la tache 2 devienne soudain assez urgente
|
# Supposons que la tache 2 devienne soudain assez urgente
|
||||||
evts[1].jour = 4
|
evts[1].jour = 4
|
||||||
T.actualise(evts[1].cle)
|
T.actualise(evts[1].cle)
|
||||||
|
|
||||||
# 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
|
@ -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()
|
||||||
|
|