ฉันรู้ว่าคุณอาจได้รับส่วนสำคัญจากคำตอบอื่น ๆ แต่มันเป็นคำถามที่สนุกและฉันรู้สึกเหมือนทำรหัส Python เล็กน้อย นี่คือวิธีการเชิงวัตถุของฉัน เยื้องกำหนดขอบเขต
การแทนกราฟ
สามารถจัดเก็บกราฟได้อย่างง่ายดายเป็นคีย์พจนานุกรมค่าที่คีย์คือรหัสห้องและค่าเป็นอาร์เรย์ของห้องที่นำไปสู่
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
ตัวแทนความรู้
เมื่อเอเจนต์เข้าสู่แผนที่เป็นครั้งแรกจะรู้เพียงจำนวนประตูในห้องและรหัสของห้องที่ใช้อยู่ในปัจจุบันฉันต้องสร้างโครงสร้างที่จะเก็บข้อมูลที่เอเจนต์ได้เรียนรู้เช่นประตูที่ไม่ได้รับ ผ่านและประตูที่นำไปสู่ที่เคยผ่าน
คลาสนี้แสดงข้อมูลเกี่ยวกับห้องเดี่ยว ฉันเลือกที่จะจัดเก็บประตูที่ไม่ได้set
เข้าชมเป็นประตูเอและที่เข้าเยี่ยมชมเป็นdictionary
ที่ที่สำคัญคือรหัสประตูและค่าเป็นรหัสของห้องที่จะนำไปสู่
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)
รองรับฟังก์ชั่น
ฉันต้องเขียนฟังก์ชั่นที่จะหากุญแจในพจนานุกรมที่ให้ค่าตั้งแต่เมื่อ backtracking เรารู้ 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))
หมายเหตุ
การย้อนรอยนั้นไม่มีประสิทธิภาพมากในกรณีที่เลวร้ายที่สุดมันสามารถผ่านทุกห้องเพื่อไปยังห้องที่อยู่ติดกันได้ แต่การย้อนรอยนั้นค่อนข้างหายาก - จากการทดสอบข้างต้นจะเป็นการย้อนรอยสามครั้งเท่านั้น ฉันหลีกเลี่ยงการใส่ข้อยกเว้นในการจัดการเพื่อให้รหัสกระชับ ความคิดเห็นใด ๆ เกี่ยวกับ Python ของฉันชื่นชม :)