Fichiers
typo-cpge/python/afficher_graphe.py

65 lignes
2.9 KiB
Python

## Export dot
# La fonction importante est afficher_graphe (les autres sont auxiliaires)
# afficher_graphe(graphe, oriente, wait, distances=None, parents=None, bfn=None)
# graphe est une matrice qui représente un graphe pondéré comme ci-dessous :
# c'est une liste de listes Python ; l'absence d'arc est dénotée par un None
# orienté : True si le graphe est orienté, False sinon (la matrice graphe doit alors ^etre symétrique)
# wait : True s'il faut suspendre le programme jusqu'à ce que la fen^etre de visu soit fermée
# (pratique si on insère la visu dans la boucle de Dijkstra : on fige étape par étape)
# marques, distance, parents : comme dans Dijsktra ; si absent ou None : ne sera pas pris en compte
# bfn : le nom de fichier à utiliser ; si absent, un fichier temporaire sera utilisé.
def export(graphe, oriente, fn, marques=None, distances=None, parents=None) :
f = open(fn, "w")
if oriente :
print("digraph {", file = f)
lien = " -> "
else :
print("graph {", file = f)
lien = " -- "
print("""rankdir="LR";""", file=f)
for noeud in range(len(graphe)) : # énumération des noeuds
label = str(noeud)
if marques != None and marques[noeud] :
label += "*"
if distances != None :
label += " ("
if distances[noeud] == PlusInfty :
label += "∞)"
else :
label += str(distances[noeud]) + ")"
print(str(noeud) + '[label="' + label + '"];', file = f)
for origine in range(0, len(graphe)) : # énumérationd des arcs
for arrivee in range(0, len(graphe)) :
if (oriente or origine < arrivee) and graphe[origine][arrivee] is not None :
if parents != None and parents[arrivee] == origine or not oriente and parents[origine] == arrivee :
style = ", penwidth=2, color=red"
else :
style = ""
print(str(origine) + lien + str(arrivee) + '[label="' + str(graphe[origine][arrivee]) + '"' + style + "];", file=f)
print("}", file=f)
f.close()
import subprocess
def dot(fn_in, fn_out) :
"""Lance le programme dot sur le fichier fn_in, en lui demandant de produire le fichier fn_out.
Ne fonctionne que si le programme dot est installé sur la machine !!"""
subprocess.call(["dot", "-Tpdf", '-o'+fn_out+'', fn_in])
def evince(fn, wait=False) :
"""Lance le visualiseur PDF evince sur le fichier fn, et n'attend pas que celui-ci termine son exécution.
Ne fonctionne que si evince est installé."""
evince = subprocess.Popen(["evince", fn])
if wait :
evince.wait()
import tempfile
def afficher_graphe(graphe, oriente, wait, marques=None, distances=None, parents=None, bfn=None) :
if bfn == None :
bfn = tempfile.mktemp()
export(graphe, oriente, bfn+".dot", marques, distances, parents)
dot(bfn+".dot", bfn+".pdf")
evince(bfn+".pdf", wait)