나는 당신이 아마 다른 답변에서 요점을 얻었음을 알고 있지만 재미있는 질문이었고 작은 파이썬 코딩을하고 싶다고 느꼈습니다. 이것은 내 객체 지향 접근 방식입니다. 들여 쓰기는 범위를 정의합니다.
그래프 표현
그래프는 키, 룸 ID, 값은 연결된 룸의 배열 인 키 사전으로 쉽게 저장할 수 있습니다.
map = {
1:[5, 2],
2:[1, 3, 5],
3:[2, 4],
4:[3, 5, 6],
5:[2, 4, 1],
6:[4]
}
에이전트 인터페이스
먼저 에이전트가 환경에서 배울 수있는 정보와 수행 할 수있는 작업에 대해 생각해야합니다. 이것은 알고리즘에 대한 생각을 단순화합니다.
이 경우 상담원은 자신이있는 방의 ID에 대해 환경을 쿼리 할 수 있어야하며, 그 방에있는 방의 문 수를 얻을 수 있어야합니다 ( 이것은 방의 ID가 아닙니다. 문으로 연결됩니다. ) 문 색인을 지정하여 문을 통과 할 수 있어야합니다. 에이전트가 알고있는 다른 것은 에이전트 자체가 파악해야합니다.
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
요원 지식
상담원이지도에 처음 들어가면 방의 출입문 수와 현재 출입 한 방의 ID 만 알 수 있습니다. 상담원이 배운 정보와 같은 정보를 저장하는 구조를 만들어야했습니다. 그 문으로 통하는 곳이 지나갔습니다.
이 클래스는 단일 방에 대한 정보를 나타냅니다. 방문하지 않은 문을로 set
방문하고 방문한 문을로 저장하기로 선택했습니다 dictionary
. 여기서 키는 문 ID이고 값은 연결된 방의 ID입니다.
class RoomKnowledge(object):
def __init__(self, unvisited_door_count):
self.unvisited_doors = set(range(unvisited_door_count))
self.visited_doors = {}
에이전트 알고리즘
상담원은 회의실에 입장 할 때마다 해당 지식 사전에서 회의실에 대한 정보를 검색합니다. 이 방에 대한 항목이없는 경우 새 방을 만들고 RoomKnowledge
이를 지식 사전에 추가합니다.
현재 방이 대상 방인지 확인한 다음 반환됩니다.
이 방에 우리가 방문하지 않은 문이 있다면, 우리는 문을 통과하여 문이 열리는 곳에 보관합니다. 그런 다음 루프를 계속합니다.
방문하지 않은 문이없는 경우 방문한 방을 되돌아 가서 방문하지 않은 문이있는 문을 찾습니다.
Agent
로부터 클래스의 상속 AgentInterface
클래스입니다.
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)
지원 기능
역 추적 할 때 우리가 얻으려고하는 방의 ID를 알고 있지만 그것을 얻는 데 사용할 문이 없기 때문에 값이 주어진 사전에서 키를 찾을 수있는 함수를 작성해야했습니다.
def find_key(dictionary, value):
for key in dictionary:
if dictionary[key]==value:
return key
테스팅
위의지도에서 시작 / 종료 위치의 모든 조합을 테스트했습니다. 각 조합마다 방문한 방을 인쇄합니다.
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))
노트
역 추적은 매우 효율적이지 않습니다. 최악의 시나리오에서는 모든 방을지나 인접 방으로 갈 수 있지만 역 추적은 매우 드문 경우입니다. 위의 테스트에서는 3 번만 역 추적합니다. 코드를 간결하게 유지하기 위해 예외 처리를 피했습니다. 내 파이썬에 대한 의견은 감사합니다 :)