Tôi nhận ra rằng bạn có thể đã nhận được ý chính từ các câu trả lời khác, nhưng đó là một câu hỏi thú vị và tôi cảm thấy như đang thực hiện một mã hóa Python nhỏ. Đây là cách tiếp cận hướng đối tượng của tôi. Ấn độ xác định phạm vi.
Biểu diễn đồ thị
Biểu đồ có thể dễ dàng được lưu trữ dưới dạng khóa, từ điển giá trị trong đó khóa là id phòng và giá trị là một mảng các phòng mà nó dẫn đến.
map = {
1:[5, 2],
2:[1, 3, 5],
3:[2, 4],
4:[3, 5, 6],
5:[2, 4, 1],
6:[4]
}
Giao diện đại lý
Đầu tiên chúng ta nên suy nghĩ về những thông tin nào mà tác nhân có thể học được từ môi trường và các hoạt động mà nó sẽ có thể thực hiện. Điều này sẽ đơn giản hóa suy nghĩ về thuật toán.
Trong trường hợp này, nhân viên sẽ có thể truy vấn môi trường cho id của căn phòng mà nó đang ở, nó sẽ có thể lấy được số lượng cửa trong phòng mà nó đang ở ( lưu ý đây không phải là id của các phòng cánh cửa dẫn đến! ) và anh ta sẽ có thể di chuyển qua một cánh cửa bằng cách chỉ định một chỉ số cửa. Bất cứ điều gì khác mà một đại lý biết phải được tìm ra bởi chính các đại lý.
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
Kiến thức đại lý
Khi nhân viên lần đầu tiên vào bản đồ, nó chỉ biết số lượng cửa trong phòng và id của căn phòng hiện tại. Tôi cần tạo ra một cấu trúc lưu trữ thông tin mà nhân viên đã học được như cửa nào không có xuyên qua, và nơi những cánh cửa dẫn đến điều đó đã được thông qua.
Lớp này đại diện cho thông tin về một phòng duy nhất. Tôi đã chọn lưu trữ các cửa không mong muốn như một set
và các cửa được truy cập là một dictionary
, trong đó chìa khóa là id cửa và giá trị là id của căn phòng mà nó dẫn đến.
class RoomKnowledge(object):
def __init__(self, unvisited_door_count):
self.unvisited_doors = set(range(unvisited_door_count))
self.visited_doors = {}
Thuật toán đại lý
Mỗi khi nhân viên vào phòng, nó sẽ tìm kiếm từ điển kiến thức để biết thông tin về phòng. Nếu không có mục nào cho căn phòng này thì nó sẽ tạo một cái mới RoomKnowledge
và thêm nó vào từ điển kiến thức của nó.
Nó kiểm tra xem phòng hiện tại có phải là phòng mục tiêu không, nếu vậy thì nó trở lại.
Nếu có những cánh cửa trong căn phòng này mà chúng tôi chưa ghé thăm, chúng tôi sẽ đi qua cánh cửa và lưu trữ nơi nó dẫn đến. Chúng tôi sau đó tiếp tục vòng lặp.
Nếu không có bất kỳ cánh cửa nào không có cửa, chúng tôi quay lại các phòng mà chúng tôi đã ghé thăm để tìm một cánh cửa không có cửa.
Các Agent
kế thừa lớp từ AgentInterface
lớp.
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)
Chức năng hỗ trợ
Tôi đã phải viết một chức năng sẽ tìm thấy một khóa trong một từ điển được đưa ra một giá trị, vì khi quay lại, chúng tôi biết id của căn phòng mà chúng tôi đang cố gắng để đến, nhưng không sử dụng cửa nào để đi đến đó.
def find_key(dictionary, value):
for key in dictionary:
if dictionary[key]==value:
return key
Kiểm tra
Tôi đã thử nghiệm tất cả các kết hợp của vị trí bắt đầu / kết thúc trong bản đồ được đưa ra ở trên. Đối với mỗi sự kết hợp, nó in ra các phòng thăm.
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))
Ghi chú
Việc quay lui không hiệu quả lắm - trong trường hợp xấu nhất, nó có thể đi qua mọi phòng để đến phòng liền kề, nhưng quay lui là khá hiếm - trong các thử nghiệm ở trên, nó chỉ quay lại ba lần. Tôi đã tránh đưa xử lý ngoại lệ vào để giữ cho mã ngắn gọn. Mọi ý kiến về Python của tôi đều đánh giá cao :)