@ -4,6 +4,7 @@ import numpy as np
import triangulation
import triangulation
import tas
import tas
import stack
class Graphe :
class Graphe :
@ -21,7 +22,7 @@ class Graphe:
self . nom = nom
self . nom = nom
self . sommets = [ ]
self . sommets = [ ]
self . aretes = [ ]
self . aretes = [ ]
self . cout = None , Graphe . Cout . TEMPS
self . cout = Graphe . Cout . TEMPS
self . arrivee = None
self . arrivee = None
def renomme ( self , nom ) :
def renomme ( self , nom ) :
@ -55,6 +56,8 @@ class Graphe:
"""
"""
a = Arete ( s1 , s2 , longueur , v_moyenne , self )
a = Arete ( s1 , s2 , longueur , v_moyenne , self )
self . aretes . append ( a )
self . aretes . append ( a )
s1 . aretes . add ( a )
s2 . aretes . add ( a )
return a
return a
def n ( self ) :
def n ( self ) :
@ -303,18 +306,19 @@ class Graphe:
minCout = sys . float_info . max
minCout = sys . float_info . max
matrice = self . matriceCout ( tournee )
matrice = self . matriceCout ( tournee )
cout = 0
cout = 0
visite = [ False ] * len ( tournee )
visite = [ False ] * len ( tournee )
visite [ 0 ] = True
visite [ 0 ] = True
itineraire = [ 0 ]
itineraire = [ 0 ]
def backtrack ( ) :
def backtrack ( ) :
nonlocal meilleurItineraire , minCout , matrice , cout , visite , itineraire
nonlocal meilleurItineraire , minCout , matrice , cout , visite , itineraire
if cout < minCout :
if cout < minCout :
if len ( itineraire ) == len ( tournee ) :
if len ( itineraire ) == len ( tournee ) :
if cout + matrice [ 0 , itineraire [ - 1 ] ] < minCout :
if cout + matrice [ 0 , itineraire [ - 1 ] ] < minCout :
minCout = cout + matrice [ 0 , itineraire [ - 1 ] ]
minCout = cout + matrice [ 0 , itineraire [ - 1 ] ]
meilleurItineraire = [ tournee [ x ] for x in itineraire ]
meilleurItineraire = [ tournee [ x ] for x in itineraire ]
else :
else :
for i , sommet_visite in enumerate ( visite ) :
for i , sommet_visite in enumerate ( visite ) :
if not sommet_visite :
if not sommet_visite :
visite [ i ] = True
visite [ i ] = True
indicePrec = itineraire [ - 1 ]
indicePrec = itineraire [ - 1 ]
@ -328,12 +332,82 @@ class Graphe:
return minCout , meilleurItineraire
return minCout , meilleurItineraire
def traceItineraire ( self , itineraire ) :
def traceItineraire ( self , itineraire ) :
for i , x in enumerate ( itineraire ) :
for i , x in enumerate ( itineraire ) :
x . nom = " s " + str ( i )
x . nom = " s " + str ( i )
suivant = itineraire [ ( i + 1 ) % len ( itineraire ) ]
suivant = itineraire [ ( i + 1 ) % len ( itineraire ) ]
c , _ = self . astar ( x , suivant )
c , _ = self . astar ( x , suivant )
self . colorieChemin ( c , ( 0.8 , 0.1 , 0.8 ) )
self . colorieChemin ( c , ( 0.8 , 0.1 , 0.8 ) )
def Prim ( self ) :
for s in self . sommets :
s . selection = False
for a in self . aretes :
a . selection = False
aretes = tas . Tas ( lambda x : - x . cout )
for a in self . sommets [ 0 ] . aretes :
aretes . ajoute ( a )
self . sommets [ 0 ] . selection = True
arbre = [ ]
ptot = 0
while not aretes . empty ( ) :
a = aretes . pop ( )
s1 , s2 = a . s1 , a . s2
if not s1 . selection or not s2 . selection :
a . selection = True
ptot + = a . cout
if not s1 . selection :
s1 . selection = True
for a_1 in s1 . aretes :
aretes . ajoute ( a_1 )
if not s2 . selection :
s2 . selection = True
for a_2 in s2 . aretes :
aretes . ajoute ( a_2 )
return ptot
def colorieSelection ( self , couleur = ( 0.1 , 0.6 , 0.2 ) ) :
""" Colorie les sommets et arêtes avec le drapeau `selection` à True. """
for s in self . sommets :
if s . selection :
s . couleur = couleur
for s in self . aretes :
if s . selection :
s . couleur = couleur
def grapheDeCout ( self , tournee ) :
g = Graphe ( " Graphe de cout de " + self . nom )
for s in tournee :
s_a = g . ajouteSommet ( s . x ( ) , s . y ( ) )
s_a . image = s
s . image = s_a
for i , s in enumerate ( g . sommets ) :
self . dijkstraAvecTas ( s . image )
for s_v in g . sommets [ i : ] :
d = sum ( ( a . cout for a in self . cheminOptimal ( s_v . image ) ) )
g . connecte ( s , s_v , d , 1 )
return g
def tourneeApproximative ( self , tournee ) :
g_cout = self . grapheDeCout ( tournee )
g_cout . Prim ( )
pile = stack . Stack ( )
pile . add ( tournee [ 0 ] . image )
tournee [ 0 ] . image . selection = False
chemin = [ tournee [ 0 ] ]
while not pile . empty ( ) :
actuel = pile . pop ( )
fils = list ( filter ( lambda x : x . selection , actuel . aretes ) )
if fils :
a = fils . pop ( )
a . selection = False
nouveau = a . voisin ( actuel )
nouveau . selection = False
chemin . append ( nouveau . image )
pile . add ( actuel )
pile . add ( nouveau )
return chemin
class Sommet :
class Sommet :
""" Implémente un sommet de graphe. """
""" Implémente un sommet de graphe. """
@ -352,6 +426,8 @@ class Sommet:
self . cumul = None
self . cumul = None
self . precedent = None
self . precedent = None
self . graphe = graphe
self . graphe = graphe
self . selection = False
self . image = None
@property
@property
def minCumulRestant ( self ) :
def minCumulRestant ( self ) :
@ -409,6 +485,7 @@ class Arete:
self . v_moyenne = v_moyenne
self . v_moyenne = v_moyenne
self . couleur = couleur
self . couleur = couleur
self . graph = graph
self . graph = graph
self . selection = False
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.