Ich erkenne, dass Sie wahrscheinlich das Wesentliche aus anderen Antworten erhalten haben, aber es war eine lustige Frage und ich hatte Lust, ein wenig Python-Codierung zu machen. Dies ist mein objektorientierter Ansatz. Einrückung definiert den Umfang.
Diagrammdarstellung
Das Diagramm kann einfach als Schlüssel- und Wertewörterbuch gespeichert werden, wobei der Schlüssel die Raum-ID und der Wert ein Array der Räume ist, zu denen er führt.
map = {
1:[5, 2],
2:[1, 3, 5],
3:[2, 4],
4:[3, 5, 6],
5:[2, 4, 1],
6:[4]
}
Agentenschnittstelle
Zuerst sollten wir uns überlegen, welche Informationen der Agent aus der Umgebung lernen kann und welche Vorgänge er ausführen kann. Dies vereinfacht das Nachdenken über den Algorithmus.
In diesem Fall sollte der Agent in der Lage sein, die Umgebung nach der ID des Raums abzufragen, in dem er sich befindet. Er sollte in der Lage sein, die Anzahl der Türen in dem Raum zu ermitteln, in dem er sich befindet ( beachten Sie, dass dies nicht die ID der Räume ist, in denen er sich befindet Türen führen zu! ) und er sollte sich durch Angabe eines Türindex durch eine Tür bewegen können. Alles andere, was ein Agent weiß, muss vom Agenten selbst herausgefunden werden.
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
Agentenwissen
Wenn der Agent die Karte zum ersten Mal betritt, kennt er nur die Anzahl der Türen im Raum und die ID des Raums, in dem er sich gerade befindet. Ich musste eine Struktur erstellen, in der Informationen gespeichert werden, die der Agent gelernt hat, z. B. welche Türen er nicht war durch, und wohin die Türen dazu führen, war durch gewesen.
Diese Klasse repräsentiert die Informationen zu einem einzelnen Raum. Ich habe mich dafür entschieden, die nicht besuchten Türen als set
und die besuchten Türen als zu speichern dictionary
, wobei der Schlüssel die Tür-ID und der Wert die ID des Raums ist, zu dem er führt.
class RoomKnowledge(object):
def __init__(self, unvisited_door_count):
self.unvisited_doors = set(range(unvisited_door_count))
self.visited_doors = {}
Agentenalgorithmus
Jedes Mal, wenn der Agent einen Raum betritt, durchsucht er sein Wissenswörterbuch nach Informationen über den Raum. Wenn für diesen Raum keine Einträge vorhanden sind, wird ein neuer erstellt RoomKnowledge
und dieser dem Wissenswörterbuch hinzugefügt.
Es wird geprüft, ob der aktuelle Raum der Zielraum ist. Wenn ja, wird es zurückgegeben.
Wenn es Türen in diesem Raum gibt, die wir nicht besucht haben, gehen wir durch die Tür und lagern, wohin sie führen. Wir setzen dann die Schleife fort.
Wenn es keine nicht besuchten Türen gab, gehen wir zurück durch die Räume, die wir besucht haben, um eine mit nicht besuchten Türen zu finden.
Die Agent
Klasse erbt von der AgentInterface
Klasse.
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)
Unterstützende Funktionen
Ich musste eine Funktion schreiben, die einen Schlüssel in einem Wörterbuch mit einem bestimmten Wert findet, da wir beim Zurückverfolgen die ID des Raums kennen, zu dem wir gelangen möchten, aber nicht, welche Tür wir verwenden müssen, um dorthin zu gelangen.
def find_key(dictionary, value):
for key in dictionary:
if dictionary[key]==value:
return key
Testen
Ich habe alle Kombinationen der Start- / Endposition in der oben angegebenen Karte getestet. Für jede Kombination werden die besuchten Räume ausgedruckt.
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))
Anmerkungen
Das Backtracking ist nicht sehr effizient - im schlimmsten Fall könnte es durch jeden Raum gehen, um zu einem angrenzenden Raum zu gelangen, aber das Backtracking ist ziemlich selten - in den obigen Tests wird es nur dreimal zurückverfolgt. Ich habe es vermieden, Ausnahmebehandlungen einzufügen, um den Code kurz zu halten. Kommentare zu meinem Python sind willkommen :)