Adloun

Floyd-Warshall — toutes les distances d'un graphe en trois lignes

Exercice · informatique (tronc commun des prépas scientifiques), chapitre 18 — La programmation dynamique

Énoncé

(a) Soit un graphe pondéré à sommets. Définir comme la longueur du plus court chemin de à dont les sommets intermédiaires appartiennent tous à l'ensemble . Exprimer la récurrence. (b) Implémenter l'algorithme Floyd-Warshall en Python et vérifier son comportement sur le graphe piège comportant un arc de poids négatif vu au chapitre 14 : , et (la distance doit valoir ). (c) Comparer la complexité avec la répétition de l'algorithme de Dijkstra.

Corrigé

(a) Le plus court chemin de à passant par les sommets intermédiaires inférieurs à soit passe par le sommet (et se décompose en ), soit ne passe pas par . La récurrence s'écrit : avec initialisée à la valeur du poids de l'arc de à (ou en l'absence d'arc). (b)

def floyd_warshall(M: list) -> list:
    n = len(M)
    for k in range(n):
        for i in range(n):
            for j in range(n):
                if M[i][k] + M[k][j] < M[i][j]:
                    M[i][j] = M[i][k] + M[k][j]
    return M

INF = float("inf")
# Sommets s, a, b indexés par 0, 1, 2
M = [[0, 2, 3],
     [INF, 0, INF],
     [INF, -2, 0]]
floyd_warshall(M)
assert M[0][1] == 1  # s -> b -> a : poids 3 - 2 = 1

L'algorithme de Floyd-Warshall gère correctement les arcs de poids négatifs (contrairement à Dijkstra) tant qu'il n'y a pas de cycle de poids négatif. (c) Floyd-Warshall s'exécute en en temps et nécessite une simple matrice en espace. Dijkstra exécuté fois prend en temps avec une implémentation par tableau simple, mais peut descendre à avec un tas. Floyd-Warshall est donc préférable sur les graphes denses ou en présence d'arcs négatifs, tandis que Dijkstra répété est plus rapide sur les grands graphes creux sans arcs négatifs.

Les autres exercices de ce chapitre Le cours du chapitre

Un blocage sur cet exercice ? Le tuteur d'Adloun guide par questions, sans donner la réponse.