[英]Find the number of all possible path in a grid, from (0, 0) to (n, n)
我不知道如何找到網格中所有可能路徑的數量,從 A 點到 B 點。A 點在 (0,0) 上,B 點在 (n,n) 上。 A 可以上下左右移動,不能在訪問點上移動。 當 A 移動時,A(x,y) = (x,y|(0=<x=<n)∩(0=<y=<n))。
我建議用天真的遞歸來解決這個問題。
保留一組您visted
的地方。 在故意不是任何特定語言的偽代碼中:
function recursive_call(i, j, visited=none)
if visited is none then
visited = set()
end if
if i = n and j = n then
return 1
else if (i, j) in visited or not in grid then
return 0
else
total = 0
add (i, j) to visited
for direction in directions:
(new_i, new_j) = move(i, j, direction)
total += recursive_call(new_i, new_j, visited)
remove (i, j) from visited
return total
end if
end function
您可以通過遞歸回溯來解決這個問題,但我認為還有另一種方法更有趣。
如果我們手動計算前幾個案例,我們會發現:
如果我們然后 go 到OEIS(Integer 序列的在線百科全書)並輸入搜索短語“1,2,12 路徑”,第一個結果是A007764 ,其標題為“非交叉路徑的數量(或自回避路徑)連接 n X n 網格的對角”。
了解您正在尋找的 integer 序列可以解鎖重要的數學資源,包括生成序列的源代碼、相關序列和最知名的值。
該序列的已知值為:
1 1
2 2
3 12
4 184
5 8512
6 1262816
7 575780564
8 789360053252
9 3266598486981642
10 41044208702632496804
11 1568758030464750013214100
12 182413291514248049241470885236
13 64528039343270018963357185158482118
14 69450664761521361664274701548907358996488
15 227449714676812739631826459327989863387613323440
16 2266745568862672746374567396713098934866324885408319028
17 68745445609149931587631563132489232824587945968099457285419306
18 6344814611237963971310297540795524400449443986866480693646369387855336
19 1782112840842065129893384946652325275167838065704767655931452474605826692782532
20 1523344971704879993080742810319229690899454255323294555776029866737355060592877569255844
21 3962892199823037560207299517133362502106339705739463771515237113377010682364035706704472064940398
22 31374751050137102720420538137382214513103312193698723653061351991346433379389385793965576992246021316463868
23 755970286667345339661519123315222619353103732072409481167391410479517925792743631234987038883317634987271171404439792
24 55435429355237477009914318489061437930690379970964331332556958646484008407334885544566386924020875711242060085408513482933945720
25 12371712231207064758338744862673570832373041989012943539678727080484951695515930485641394550792153037191858028212512280926600304581386791094
26 8402974857881133471007083745436809127296054293775383549824742623937028497898215256929178577083970960121625602506027316549718402106494049978375604247408
27 17369931586279272931175440421236498900372229588288140604663703720910342413276134762789218193498006107082296223143380491348290026721931129627708738890853908108906396
您可以使用遞歸回溯自己生成前幾個術語:
from typing import Final, List, Set, Tuple
def walk(x: int, y: int, destx: int, desty: int, used: Set[Tuple[int, int]]) -> int:
"""
Recursive function to calculate the number of self-avoiding walks
Our strategy here is to build a function that generates self-avoiding walks in
a depth-first manner using backtracking to avoid duplication and a hash-set to
avoid overlaps.
Args:
n - How far we are into the walk
x - Current x location
y - Current y location
Returns:
The number of self-avoiding walks of length `n_max`
"""
# Possible displacement values on a square lattice
dr_vals: Final[List[Tuple[int, int]]] = [(-1, 0), (1, 0), (0, 1), (0, -1)]
# Don't walk off the grid
if x<0 or x == destx:
return 0
if y<0 or y == desty:
return 0
if x == destx-1 and y==desty-1:
return 1
# Make a note that we're now at location (x,y) so it is unavailable
used.add((x,y))
# Body of recursion: we will count the walks leading away from (x,y)
walks = 0
# Look at all the possible directions we can go from here
for dr in dr_vals:
# Determine next coordinates given the displacement
nx = x + dr[0]
ny = y + dr[1]
# Don't visit the neighbouring square twice!
if (nx, ny) in used:
continue
# Visit the neighbouring square and count how many walks it has
walks += walk(x=nx, y=ny, destx=destx, desty=desty, used=used)
# We've finished the body of the recursion, we now go back up the stack
# Since we're going back up the stack we no longer occupy (x,y)
used.remove((x,y))
return walks
def main():
# Make a table of how many self-avoiding walks there are in an n x n square
# Given the exponential increase the cost of computation and simplicity of this
# algorithm, this will probably run forever
for n in range(30):
used: Set[Tuple[int, int]] = set([(1000, 1000)])
print(n, walk(x=0, y=0, destx=n, desty=n, used=used))
main()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.