مسیریابی در هزارتو (عقبگرد)
از گوشهی بالا-چپ تا گوشهی پایین-راست راه پیدا میکند: جلو میرود و هر جا بنبست بود علامت میزند و عقب برمیگردد.
هزارتو یک جدول است: 0 خانهی باز و 1 دیوار. از گوشهی بالا-چپ شروع میکنیم و به ترتیب راست، پایین، چپ و بالا را امتحان میکنیم:
- زمان:
O(rows · cols) - حافظه:
O(rows · cols) - هوروویتز–ساهنی، فصل ۳
هزارتوی ۵×۵؛ اول شاخهی سمت راست امتحان میشود و به بنبست میرسد (x)، بعد راه پایین تا خروجی میرود (o).
def solve_maze(grid):# 0 is open and 1 is a wall; find a way from the top-left to the bottom-right corner.rows, cols = len(grid), len(grid[0])board = [["█" if cell else "·" for cell in row] for row in grid]if grid[0][0] or grid[rows - 1][cols - 1]:return Falsereturn walk(board, 0, 0, rows, cols)def walk(board, r, c, rows, cols):if r < 0 or r >= rows or c < 0 or c >= cols or board[r][c] != "·":return Falseboard[r][c] = "o"if r == rows - 1 and c == cols - 1:return Truefor dr, dc in [(0, 1), (1, 0), (0, -1), (-1, 0)]:if walk(board, r + dr, c + dc, rows, cols):return Trueboard[r][c] = "x"return False
شروع اجرا
جدول هنوز خالی است.
درخت فراخوانیهای بازگشتی
نارنجی پر = فراخوانی در حال اجرا · حاشیهی نارنجی = هنوز روی پشته · خاکستری = تمام شده
متغیرهای محلی
نارنجی = در همین گام عوض شد
grid list
Call stack
- solve_maze()خط 1
توضیح
ایده
هزارتو یک جدول است: 0 خانهی باز و 1 دیوار. از گوشهی بالا-چپ شروع میکنیم و به ترتیب راست، پایین، چپ و بالا را امتحان میکنیم:
- اگر خانهی بعدی باز و ندیده باشد، واردش میشویم (
o). - اگر از خانهای هیچ راهی جلو نبود، آن را بنبست علامت میزنیم (
x) و یک خانه عقب برمیگردیم.
این همان جستوجوی عمقاول روی گراف خانههاست؛ پشتهی فراخوانیها همان مسیر فعلی است.
هزینه
هر خانه حداکثر یک بار وارد میشود: O(سطرها × ستونها). مسیری که پیدا میشود لزوماً کوتاهترین نیست؛ برای کوتاهترین باید جستوجوی سطحاول زد.
در trace به چه چیزی نگاه کنی
- جدول همان هزارتوست:
█دیوار،oمسیر فعلی وxبنبستها. درخت فراخوانیها شاخههای امتحانشده را نشان میدهد.