Je reconnais que vous avez probablement compris l'essentiel des autres réponses, mais c'était une question amusante et j'avais envie de faire un peu de codage Python. Ceci est mon approche orientée objet. L'indentation définit la portée.
Représentation graphique
Le graphique peut facilement être stocké sous forme de clé, dictionnaire de valeurs où la clé est l'identifiant de la pièce et la valeur est un tableau des pièces vers lesquelles elle mène.
map = {
1:[5, 2],
2:[1, 3, 5],
3:[2, 4],
4:[3, 5, 6],
5:[2, 4, 1],
6:[4]
}
Interface de l'agent
Nous devons d'abord réfléchir aux informations que l'agent devrait être en mesure d'apprendre de l'environnement et aux opérations qu'il devrait être en mesure d'effectuer. Cela simplifiera la réflexion sur l'algorithme.
Dans ce cas, l'agent devrait pouvoir interroger l'environnement pour l'identifiant de la pièce dans laquelle il se trouve, il devrait être en mesure d'obtenir un compte des portes de la pièce dans laquelle il se trouve ( notez qu'il ne s'agit pas de l'identifiant des pièces dans lesquelles il se trouve). portes mènent à! ) et il doit pouvoir se déplacer à travers une porte en spécifiant un index de porte. Tout ce qu'un agent sait doit être déterminé par l'agent lui-même.
class AgentInterface(object):
def __init__(self, map, starting_room):
self.map = map
self.current_room = starting_room
def get_door_count(self):
return len(self.map[self.current_room])
def go_through_door(self, door):
result = self.current_room = self.map[self.current_room][door]
return result
Connaissance des agents
Lorsque l'agent entre pour la première fois sur la carte, il ne connaît que le nombre de portes dans la pièce et l'identifiant de la pièce dans laquelle il se trouve actuellement. à travers, et où les portes mènent à cela était passé.
Cette classe représente les informations sur une seule pièce. J'ai choisi de stocker les portes non visitées comme un set
et les portes visitées comme un dictionary
, où la clé est l'identifiant de la porte et la valeur est l'identifiant de la pièce vers laquelle elle mène.
class RoomKnowledge(object):
def __init__(self, unvisited_door_count):
self.unvisited_doors = set(range(unvisited_door_count))
self.visited_doors = {}
Algorithme d'agent
Chaque fois que l'agent pénètre dans une pièce, il recherche dans son dictionnaire de connaissances des informations sur la pièce. S'il n'y a pas d'entrées pour cette salle, il en crée une nouvelle RoomKnowledge
et l'ajoute à son dictionnaire de connaissances.
Il vérifie si la pièce actuelle est la pièce cible, si c'est le cas, il revient.
S'il y a des portes dans cette pièce que nous n'avons pas visitées, nous passons par la porte et stockons où elles mènent. Nous continuons ensuite la boucle.
S'il n'y avait pas de portes non visitées, nous revenons en arrière dans les pièces que nous avons visitées pour en trouver une avec des portes non visitées.
La Agent
classe hérite de la AgentInterface
classe.
class Agent(AgentInterface):
def find_exit(self, exit_room_id):
knowledge = { }
room_history = [] # For display purposes only
history_stack = [] # Used when we need to backtrack if we've visited all the doors in the room
while True:
room_knowledge = knowledge.setdefault(self.current_room, RoomKnowledge(self.get_door_count()))
room_history.append(self.current_room)
if self.current_room==exit_room_id:
return room_history
if len(room_knowledge.unvisited_doors)==0:
# I have destination room id. I need door id:
door = find_key(room_knowledge.visited_doors, history_stack.pop())
self.go_through_door(door)
else:
history_stack.append(self.current_room)
# Enter the first unopened door:
opened_door = room_knowledge.unvisited_doors.pop()
room_knowledge.visited_doors[opened_door]=self.go_through_door(opened_door)
Fonctions de support
J'ai dû écrire une fonction qui trouverait une clé dans un dictionnaire étant donné une valeur, car lors du retour en arrière, nous connaissons l'identifiant de la pièce que nous essayons d'accéder, mais pas la porte à utiliser pour y accéder.
def find_key(dictionary, value):
for key in dictionary:
if dictionary[key]==value:
return key
Essai
J'ai testé toutes les combinaisons de position de début / fin dans la carte ci-dessus. Pour chaque combinaison, il imprime les pièces visitées.
for start in range(1, 7):
for exit in range(1, 7):
print("start room: %d target room: %d"%(start,exit))
james_bond = Agent(map, start)
print(james_bond.find_exit(exit))
Remarques
Le retour arrière n'est pas très efficace - dans le pire des cas, il pourrait traverser chaque pièce pour se rendre dans une pièce adjacente, mais le retour arrière est assez rare - dans les tests ci-dessus, il ne fait que revenir en arrière trois fois. J'ai évité de mettre la gestion des exceptions pour garder le code concis. Tout commentaire sur mon Python apprécié :)