ajout des maths TP3 graphs

master
antoine.perederii 2 years ago
parent 7232f92ae2
commit b96c5fe156

@ -0,0 +1,249 @@
import networkx as nx
import matplotlib.pyplot as plt
import random #pour des nombres al ́eatoires
G1 = nx.Graph()
G1.add_edge(0,1,weight=5)
G1.add_edge(0,2,weight=3)
G1.add_edge(0,3,weight=3)
G1.add_edge(0,4,weight=1)
G1.add_edge(1,2,weight=2)
G1.add_edge(2,3,weight=4)
G1.add_edge(3,4,weight=3)
G1.add_edge(3,5,weight=2)
G1.add_edge(4,5,weight=1)
dico_positions = {0:(0,0),1:(2,-1),2:(1.8,-3),3:(-0.3,-2),4:(-2,-1),5:(-2.5,-3)}
nx.draw(G1,dico_positions,with_labels=True)
2
nx.draw_networkx_edge_labels(G1,dico_positions,
edge_labels=nx.get_edge_attributes(G1,"weight"))
plt.show()
G2 = nx.Graph()
G2.add_edge("A", "B", weight=7)
G2.add_edge("A", "C", weight=8)
G2.add_edge("A", "J", weight=6)
G2.add_edge("B", "E", weight=4)
G2.add_edge("C", "I", weight=9)
G2.add_edge("C", "D", weight=5)
G2.add_edge("D", "E", weight=3)
G2.add_edge("D", "F", weight=5)
G2.add_edge("D", "G", weight=16)
G2.add_edge("E", "J", weight=3)
G2.add_edge("E", "K", weight=2)
G2.add_edge("F", "G", weight=8)
G2.add_edge("F", "H", weight=4)
G2.add_edge("G", "H", weight=12)
G2.add_edge("G", "J", weight=1)
G2.add_edge("G", "L", weight=12)
G2.add_edge("I", "J", weight=6)
G2.add_edge("K", "L", weight=10)
dico_positions2 = {"A":(0,0),"C":(2,0),"D":(4,0),"F":(6,0),"B":(1,-2),"E":(3,-2),"G":(5,-2),"H":(7,-2), "I":(1,-4), "J":(3,-4), "K":(5,-4), "L":(7,-4)}
nx.draw(G2, with_labels=True, pos=dico_positions2)
nx.draw_networkx_edge_labels(G2,dico_positions2,
edge_labels=nx.get_edge_attributes(G2,"weight"))
plt.show()
def aretes_traversantes(G, S):
""" Renvoie la liste des arêtes traversantes de G pour S
Entrées :
G : un graphe
S : une liste de sommets
Sortie :
L : la liste des arêtes traversantes de G pour S
"""
L = []
for i in S:
for j in G.edges(i):
if j not in S:
L.append(i,j)
return L
# Impl ́ementer une version simplifi ́ee de lalgorithme de Prim qui ne se soucie pas des
# poids des arˆetes, avec une fonction algo prim simple(G) qui calcule un arbre couvrant
# de G (pas forc ́ement de poids minimal). Pour cela, `a chaque ́etape, lalgorithme prendra
# une arˆete quelconque parmi les arˆetes autoris ́ees et lajoutera `a larbre calcul ́e jusqu`a
# pr ́esent.
# La fonction renverra la liste des arˆetes de larbre couvrant. Tester avec les graphes G1
# ou G2 des Figures 1 et 2, puis ́eventuellement avec des graphes al ́eatoires.
# Conseil : maintenir une liste sommets visites des sommets visit ́es et une liste des
# arˆetes s ́electionn ́ees. `A chaque ́etape il faudra consid ́erer toutes les arˆetes entre les som-
# mets visit ́es et les sommets non-visit ́es grˆace `a aretes traversantes(G,sommets visites).
def algo_prim_simple(G):
""" Renvoie la liste des arêtes de l'arbre couvrant de G
Entrée :
G : un graphe
Sortie :
L : la liste des arêtes de l'arbre couvrant de G
"""
L = []
sommets_visites = []
sommets_non_visites = list(G.nodes())
sommets_visites.append(sommets_non_visites[0])
sommets_non_visites.remove(sommets_non_visites[0])
while len(sommets_visites) != len(G.nodes()):
for i in sommets_visites:
for j in G.edges(i):
if j[1] not in sommets_visites:
L.append(j)
sommets_visites.append(j[1])
sommets_non_visites.remove(j[1])
break
return L, sum([G.get_edge_data(i[0],i[1])["weight"] for i in L])
# Impl ́ementer lalgorithme de Prim au complet, par une fonction algo prim(G) qui
# renvoie la liste des arˆetes de larbre couvrant de poids minimal de G calcul ́e par lalgo-
# rithme. Tester.
# Algorithme de Prim :
# • Initialiser T avec
# {
# sommets : un sommet de G quon choisit
# arˆetes : aucune
# • R ́ep ́eter tant que T ne couvre pas tous les sommets :
# ⋆ Trouver toutes les arˆetes de G qui relient un sommet de T et un
# sommet ext ́erieur `a T
# ⋆ Parmi celles-ci, choisir une arˆete de poids le plus petit possible
# ⋆ Ajouter `a T cette arˆete et le sommet correspondant
# • Sarrˆeter d`es que tous les sommets de G sont dans T
# • Retourner T
def algo_prim(G):
""" Renvoie la liste des arêtes de l'arbre couvrant de poids minimal de G
Entrée :
G : un graphe
Sortie :
L : la liste des arêtes de l'arbre couvrant de poids minimal de G
"""
L = []
sommets_visites = []
sommets_non_visites = list(G.nodes())
sommets_visites.append(sommets_non_visites[0])
sommets_non_visites.remove(sommets_non_visites[0])
while len(sommets_visites) != len(G.nodes()):
arretes_traversantes = []
for i in sommets_visites:
for j in G.edges(i):
if j[1] not in sommets_visites:
arretes_traversantes.append(j)
arrete_min = arretes_traversantes[0]
for i in arretes_traversantes:
if G.get_edge_data(i[0],i[1])["weight"] < G.get_edge_data(arrete_min[0],arrete_min[1])["weight"]:
arrete_min = i
L.append(arrete_min)
sommets_visites.append(arrete_min[1])
sommets_non_visites.remove(arrete_min[1])
# Return L et le poids total
return L, sum([G.get_edge_data(i[0],i[1])["weight"] for i in L])
# teste moi les algo precedents
print(algo_prim_simple(G1))
print(algo_prim(G1))
print(algo_prim_simple(G2))
print(algo_prim(G2))
# Exo 2 : Algorithme de Kruskal
# Impl ́ementer lalgorithme de Kruskal, par une fonction algo kruskal(G) qui renvoie
# la liste des arˆetes de larbre couvrant de poids minimal de G calcul ́e par lalgorithme.
# Tester.
# Algorithme de Kruskal :
# • Initialiser T avec
# {
# sommets : tous les sommets de G
# arˆetes : aucune
# • Tant que T nest pas un arbre couvrant :
# ⋆ Trouver une arˆete de poids minimal qui relie deux sommets de T
# ⋆ Ajouter `a T cette arˆete
# ⋆ Supprimer les arˆetes de T qui forment un cycle
# • Sarrˆeter d`es que T est un arbre couvrant
# • Retourner T
def algo_kruskal(G):
""" Renvoie la liste des arêtes de l'arbre couvrant de poids minimal de G
Entrée :
G : un graphe
Sortie :
L : la liste des arêtes de l'arbre couvrant de poids minimal de G
"""
L = []
sommets_visites = []
sommets_non_visites = list(G.nodes())
sommets_visites.append(sommets_non_visites[0])
sommets_non_visites.remove(sommets_non_visites[0])
while len(sommets_visites) != len(G.nodes()):
arretes_traversantes = []
for i in sommets_visites:
for j in G.edges(i):
if j[1] not in sommets_visites:
arretes_traversantes.append(j)
arrete_min = arretes_traversantes[0]
for i in arretes_traversantes:
if G.get_edge_data(i[0],i[1])["weight"] < G.get_edge_data(arrete_min[0],arrete_min[1])["weight"]:
arrete_min = i
L.append(arrete_min)
sommets_visites.append(arrete_min[1])
sommets_non_visites.remove(arrete_min[1])
return L, sum([G.get_edge_data(i[0],i[1])["weight"] for i in L])
print(algo_kruskal(G1))
print(algo_kruskal(G2))
# Il existe un autre algorithme darbre couvrant de poids minimal, lalgorithme de Bor ̊uvka. Le
# comprendre et limpl ́ementer.
# Algorithme de Bor ̊uvka :
# F ← vide
# Tant que G n'est pas réduit à un sommet faire
# Détruire les boucles de G (*)
# Remplacer les arêtes multiples entre deux sommets par une seule dont le poids est le minimum
# Pour tout x, sommet de G, faire
# Trouver l'arête e_x de poids minimum adjacente à x
# F ← F union e_x
# Contracter e_x (**)
# fin pour
# fin tant que
# renvoyer F
def algo_boruvka(G):
""" Renvoie la liste des arêtes de l'arbre couvrant de poids minimal de G
Entrée :
G : un graphe
Sortie :
L : la liste des arêtes de l'arbre couvrant de poids minimal de G
"""
L = []
while len(G.nodes()) != 1:
# (*) Détruire les boucles de G
for i in G.edges():
if i[0] == i[1]:
G.remove_edge(i[0],i[1])
# Remplacer les arêtes multiples entre deux sommets par une seule dont le poids est le minimum
for i in G.edges():
if len(G.edges(i[0],i[1])) > 1:
min = G.get_edge_data(i[0],i[1])["weight"]
for j in G.edges(i[0],i[1]):
if G.get_edge_data(j[0],j[1])["weight"] < min:
min = G.get_edge_data(j[0],j[1])["weight"]
for j in G.edges(i[0],i[1]):
if G.get_edge_data(j[0],j[1])["weight"] != min:
G.remove_edge(j[0],j[1])
# Pour tout x, sommet de G, faire
for i in G.nodes():
# Trouver l'arête e_x de poids minimum adjacente à x
min = 10000
return L, sum([G.get_edge_data(i[0],i[1])["weight"] for i in L])
print(algo_boruvka(G1))
print(algo_boruvka(G2))
Loading…
Cancel
Save