Auto commit

This commit is contained in:
2025-02-16 20:29:43 +01:00
parent 57dfc1e18f
commit 961f977067
5 changed files with 190 additions and 68 deletions

View File

@@ -1,5 +1,140 @@
# https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm
def dijkstra(graph: dict, start: any) -> tuple:
"""
L'algorithme de Dijkstra pour trouver les plus courts chemins depuis un sommet de départ.
Args:
graph (dict): Le graphe à parcourir sous forme de dictionnaire, où les clés sont les sommets
et les valeurs sont des listes de tuples (voisin, poids).
start (any): Le sommet de départ.
Returns:
tuple: Un tuple contenant deux dictionnaires :
- Le premier associe à chaque sommet la distance minimale depuis le sommet de départ.
- Le second associe à chaque sommet (sauf le départ) son prédécesseur sur le chemin le plus court.
Exemples:
>>> graph = {
... 'A': [('B', 4), ('C', 2)],
... 'B': [('C', 5), ('D', 10)],
... 'C': [('D', 3), ('E', 8)],
... 'D': [('E', 4), ('F', 11)],
... 'E': [('G', 6)],
... 'F': [('G', 2)],
... 'G': []
... }
>>> distances, predecesseur = dijkstra(graph, 'A')
>>> distances['A']
0
>>> distances['B']
4
>>> distances['C']
2
>>> distances['D']
5
>>> distances['E']
9
>>> distances['F']
16
>>> distances['G']
15
>>> predecesseur['B']
'A'
>>> predecesseur['C']
'A'
>>> predecesseur['D']
'C'
>>> predecesseur['E']
'D'
>>> predecesseur['F']
'D'
>>> predecesseur['G']
'E'
"""
distances, predecesseur, unvisited = {}, {}, {}
for sommet in graph:
distances[sommet] = float('inf')
unvisited[sommet] = distances[sommet]
distances[start] = 0
while unvisited:
current = min(unvisited, key=unvisited.get)
del unvisited[current]
for voisin, poid in graph[current]:
new_distance = distances[current] + poid
if new_distance < distances[voisin]:
distances[voisin] = new_distance
predecesseur[voisin] = current
if voisin in unvisited:
unvisited[voisin] = new_distance
return distances, predecesseur
def reconstruire_chemin(predecesseur: dict, start: any, end: any) -> list:
"""reconstruit le chemin grace au predecesseur
Args:
predecesseur (dict): les predecesseurs
start (any): le debut
end (any): la fin
Returns:
list: renvoie une liste contenant le chemin le plus court (si aucun trouver alors renvoie liste vide)
Examples:
>>> pred = {'B': 'A', 'C': 'A', 'D': 'C', 'E': 'D', 'F': 'D', 'G': 'E'}
>>> reconstruire_chemin(pred, 'A', 'F')
['A', 'C', 'D', 'F']
>>> reconstruire_chemin(pred, 'A', 'G')
['A', 'C', 'D', 'E', 'G']
"""
chemin = [end]
current = end
while current != start:
if current not in predecesseur:
return []
current = predecesseur[current]
chemin.append(current)
chemin.reverse()
return chemin
def solutions_dijkstra(graph: dict, start: any) -> dict:
"""elle renvoie le dictionnaire des noeud et distances grace au chemin
Args:
graph (dict): le graphe
start (any): le debut
Returns:
dict: contenant les noeuds et leurs distances
Exemples:
>>> graph = {
... 'A': [('B', 4), ('C', 2)],
... 'B': [('C', 5), ('D', 10)],
... 'C': [('D', 3), ('E', 8)],
... 'D': [('E', 4), ('F', 11)],
... 'E': [('G', 6)],
... 'F': [('G', 2)],
... 'G': []
... }
>>> sol = solutions_dijkstra(graph, 'A')
>>> sol['F']
{'distance': 16, 'chemin': ['A', 'C', 'D', 'F']}
>>> sol['G']
{'distance': 15, 'chemin': ['A', 'C', 'D', 'E', 'G']}
"""
distances, predecesseur = dijkstra(graph, start)
solutions = {}
for sommet in graph:
if sommet == start:
chemin = [start]
else:
chemin = reconstruire_chemin(predecesseur, start, sommet)
if not chemin:
chemin = None
solutions[sommet] = {"distance": distances[sommet], "chemin": chemin}
return solutions
if __name__ == "__main__":
import doctest
doctest.testmod(verbose=True)
graph = {
'A': [('B', 4), ('C', 2)],
'B': [('C', 5), ('D', 10)],
@@ -9,66 +144,7 @@ graph = {
'F': [('G', 2)],
'G': []
}
solution = solutions_dijkstra(graph, 'A')
for sommet, info in solution.items():
print(f"sommet: {sommet} ----- Distance: {info['distance']} ------- chemin: {info['chemin']}")
p = {}
def chemin(predecesseur, debut, fin):
chemin = []
courant = fin
while courant != debut:
chemin.insert(0, courant)
courant = predecesseur.get(courant)
if courant is None:
return None
chemin.insert(0, debut)
return chemin
def initialisation(G, debut):
distances = {key: float('inf') for key in G}
distances[debut] = 0
return distances
def trouve_min(Q, distances):
mini = float('inf')
sommet = None
for s in Q:
if distances[s] < mini:
mini = distances[s]
sommet = s
return sommet
def poid(s1, s2):
for voisin, poids in graph[s1]:
if voisin == s2:
return poids
return float('inf')
def distances_update(s1, s2, distances, predecesseur):
poids = poid(s1, s2)
if distances[s2] > distances[s1] + poids:
distances[s2] = distances[s1] + poids
predecesseur[s2] = s1
def dijkstra(G, debut='A'):
distances = initialisation(G, debut)
predecesseur = {}
Q = set(G.keys())
while Q:
s1 = trouve_min(Q, distances)
if s1 is None:
break
Q.remove(s1)
for voisin, _ in G[s1]:
if voisin in Q:
distances_update(s1, voisin, distances, predecesseur)
return distances, predecesseur
if __name__ == "__main__":
distances, predecesseur = dijkstra(graph, 'A')
print("Distances depuis A :", distances)
print("Chemin le plus court de A à G :", chemin(predecesseur, 'A', 'G'))

46
Dijkstra/fonctions.md Normal file
View File

@@ -0,0 +1,46 @@
# Dijkstra
## Fonctions
### `dijkstra(graph: dict, start: any) -> tuple`
- **Paramètres :**
- `graph` : Dictionnaire représentant le graphe. Chaque clé est un noeud et sa valeur est une liste de tuples `(voisin, poids)`.
- `start` : Le noeud de départ.
- **Retourne :**
- Un tuple contenant :
- `distances` : Un dictionnaire associant à chaque noeud la distance minimale depuis `start`.
- `predecesseur` : Un dictionnaire associant à chaque noeud son prédécesseur dans le chemin le plus court.
---
### `reconstruct_chemin(predecesseur: dict, start: any, end: any) -> list`
- **Paramètres :**
- `predecesseur` : Dictionnaire des prédécesseurs.
- `start` : Le noeud de départ.
- `end` : Le noeud d'arrivée.
- **Retourne :**
- Une liste représentant le chemin le plus court de `start` à `end`.
Si aucun chemin n'est trouvé, la fonction renvoie une liste vide.
---
### `solutions_dijkstra(graph: dict, start: any) -> dict`
- **Paramètres :**
- `graph` : Dictionnaire représentant le graphe.
- `start` : Le noeud de départ.
- **Retourne :**
- Un dictionnaire où chaque clé est un noeud du graphe et la valeur associée est un sous-dictionnaire contenant :
- `"distance"` : La distance minimale depuis `start`.
- `"chemin"` : Le chemin le plus court sous forme de liste de noeuds None si pas trouver.
---
## Utilisation
Le graphe doit être défini sous forme de dictionnaire. Exemple :
```python
graph = {
'A': [('B', 4), ('C', 2)],
'B': [('C', 5), ('D', 10)],
'C': [('D', 3), ('E', 8)],
'D': [('E', 4), ('F', 11)],
'E': [('G', 6)],
'F': [('G', 2)],
'G': []
}

Binary file not shown.

Binary file not shown.