67 lines
2.8 KiB
Python
67 lines
2.8 KiB
Python
|
def cout_mouvement(etat_actuel, nouvel_etat):
|
||
|
# Chaque mouvement a un coût constant de 1
|
||
|
return 1
|
||
|
|
||
|
etat_jeu1 = [3, 4, 5] # État initial
|
||
|
etat_jeu2 = [3, 3, 5] # Après avoir retiré 1 objet du deuxième tas
|
||
|
|
||
|
# Le coût de passer de l'état [3, 4, 5] à l'état [3, 3, 5]
|
||
|
print("Coût du mouvement :", cout_mouvement(etat_jeu1, etat_jeu2)) # 1
|
||
|
|
||
|
import heapq
|
||
|
|
||
|
def algorithme_a_star(etat_initial):
|
||
|
# File de priorité (tas) pour les nœuds à explorer
|
||
|
file_priorite = []
|
||
|
|
||
|
# Ajouter l'état initial dans la file de priorité (f(n), g(n), état)
|
||
|
heapq.heappush(file_priorite, (0 + heuristique(etat_initial), 0, etat_initial))
|
||
|
|
||
|
# Dictionnaire pour stocker le coût minimal pour atteindre chaque état
|
||
|
cout_minimal = {tuple(etat_initial): 0}
|
||
|
|
||
|
# Dictionnaire pour reconstruire le chemin
|
||
|
predecesseurs = {tuple(etat_initial): None}
|
||
|
|
||
|
while file_priorite:
|
||
|
# Extraire l'état avec le plus faible coût estimé f(n)
|
||
|
_, cout_actuel, etat_actuel = heapq.heappop(file_priorite)
|
||
|
|
||
|
# Vérifier si l'état actuel est l'état final
|
||
|
if est_etat_final(etat_actuel):
|
||
|
# Reconstruire le chemin optimal
|
||
|
chemin = []
|
||
|
while etat_actuel is not None:
|
||
|
chemin.append(etat_actuel)
|
||
|
etat_actuel = predecesseurs[tuple(etat_actuel)]
|
||
|
chemin.reverse() # On inverse le chemin pour l'avoir dans l'ordre
|
||
|
return chemin
|
||
|
|
||
|
# Générer tous les mouvements possibles à partir de l'état actuel
|
||
|
mouvements_possibles = generer_mouvements(etat_actuel)
|
||
|
|
||
|
for nouvel_etat in mouvements_possibles:
|
||
|
# Calculer le coût du mouvement (toujours 1 dans notre cas)
|
||
|
cout_mouvement_actuel = cout_actuel + cout_mouvement(etat_actuel, nouvel_etat)
|
||
|
|
||
|
# Si le nouvel état est rencontré avec un coût inférieur à celui déjà connu
|
||
|
if tuple(nouvel_etat) not in cout_minimal or cout_mouvement_actuel < cout_minimal[tuple(nouvel_etat)]:
|
||
|
cout_minimal[tuple(nouvel_etat)] = cout_mouvement_actuel
|
||
|
predecesseurs[tuple(nouvel_etat)] = etat_actuel
|
||
|
# Calculer f(n) = g(n) + h(n)
|
||
|
f_n = cout_mouvement_actuel + heuristique(nouvel_etat)
|
||
|
# Ajouter le nouvel état dans la file de priorité
|
||
|
heapq.heappush(file_priorite, (f_n, cout_mouvement_actuel, nouvel_etat))
|
||
|
|
||
|
# Si aucun chemin n'a été trouvé (ce qui ne devrait pas arriver dans le jeu de Nim)
|
||
|
return None
|
||
|
|
||
|
etat_initial = [3, 4, 5] # Exemple d'état initial
|
||
|
|
||
|
# Appel de l'algorithme A* pour trouver le chemin optimal
|
||
|
chemin_optimal = algorithme_a_star(etat_initial)
|
||
|
|
||
|
# Affichage du chemin
|
||
|
for etat in chemin_optimal:
|
||
|
print(etat)
|