Adloun

informatique (tronc commun des prépas scientifiques) · Chapitre 14 · Exercice de TD

A* contre Dijkstra, le match mesuré

Plus courts chemins : Dijkstra et au-delà · niveau 3 (difficile)

Énoncé

Écrire l'algorithme A* sur une grille plane à déplacements unitaires de coût 1 vers une cible donnée en utilisant la distance de Manhattan comme heuristique.

Corrigé

def a_etoile_grille(p: int, q: int, depart: tuple, cible: tuple):
    def h(x):
        return abs(x[0] - cible[0]) + abs(x[1] - cible[1])
    dist = {depart: 0}
    figes = set()
    candidats = {depart}
    while candidats:
        # Priorité f(x) = dist[x] + h(x)
        s = min(candidats, key=lambda x: (dist[x] + h(x), h(x)))
        candidats.remove(s)
        figes.add(s)
        if s == cible:
            return dist[s], len(figes)
        (i, j) = s
        for v in [(i-1, j), (i+1, j), (i, j-1), (i, j+1)]:
            if 0 <= v[0] < p and 0 <= v[1] < q and v not in figes:
                if v not in dist or dist[s] + 1 < dist[v]:
                    dist[v] = dist[s] + 1
                    candidats.add(v)
    return None, len(figes)

Sur une grille vide , Dijkstra fige l'intégralité des 10 000 cases de la grille. L'algorithme A* avec Manhattan ne fige que 199 cases (un chemin linéaire direct), car le terme d'heuristique cible immédiatement la bonne direction.

Exercices semblables

Le cours du chapitre · Tous les exercices du chapitre