ASD/tas.py
2018-01-09 17:53:28 +01:00

138 lines
3.7 KiB
Python

# coding: utf-8
class Tas:
class Element:
def __init__(self, valeur, priorite, index):
self.valeur = valeur
self.priorite = priorite
self.index = index
def __str__(self):
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):
i = 2 * elt.index + 2
if(i < len(self.L)):
return self.L[i]
else:
return None
def __deplace(self, elt, index):
assert isinstance(elt, Tas.Element)
ancien = elt.index
self.L[index] = elt
elt.index = index
return ancien
def __promeut(self, elt):
while(True):
parent = self.__parent(elt)
if(parent == None):
break
if(parent.priorite >= elt.priorite):
break
elt.index = self.__deplace(parent, elt.index)
self.__deplace(elt, elt.index)
def actualise(self, elt):
assert isinstance(elt, Tas.Element)
elt.priorite = self.fonctionPriorite(elt.valeur)
self.__promeut(elt)
def ajoute(self, valeur):
elt = Tas.Element(valeur, self.fonctionPriorite(valeur), len(self.L))
self.L.append(elt)
self.__promeut(elt)
return elt
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 #
# Tri de tâches par ordre chronologique #
#########################################
class Tache:
'''Tache devant être effectuée avant une date limite'''
def __init__(self, jour, nom):
self.jour = jour
self.nom = nom
# Cet attribut servira à accueillir la clé du tas
self.cle = None
def __str__(self):
return self.nom + " ({})".format(self.jour)
if __name__ == "__main__":
# Le niveau de priorité d'un événement x est -x.jour : on trie donc les événements par ordre chronologique
def calculePriorite(tache):
return -tache.jour
# On crée un tas dont les éléments sont des événements triés par ordre chronologique
T = Tas(calculePriorite)
# Ajoute des événements au tas
evts = [Tache(5, "T1"), Tache(10, "T2"), Tache(5, "T3"), Tache(3, "T4")]
for evt in evts:
evt.cle = T.ajoute(evt)
# Supposons que la tache 2 devienne soudain assez urgente
evts[1].jour = 4
T.actualise(evts[1].cle)
# Retirons dans l'ordre chronologie les éléments du tas
while(not T.empty()):
print(T.pop())