You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

249 lines
8.8 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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))