2

期待される結果はこのようなものです。

0 0 0 1 0 * * * 0 0 0 0
0 0 0 0 1 * 1 * * 0 0 0
0 0 1 1 1 * 1 0 * 0 0 0
0 * * 0 1 * 1 0 * 0 0 0
0 * 1 1 1 * 1 0 * * 0 0
0 * 0 1 1 * 1 0 0 * 0 0
0 * 0 0 1 * 1 0 0 * 0 0
0 * * * * * 1 0 0 * * 0
0 0 0 0 0 0 1 0 0 0 * 0
0 0 0 0 0 0 1 0 0 0 * 0
0 0 0 0 0 0 1 0 0 0 * 0
0 0 0 0 0 0 1 0 0 0 * *

あなたは4方向にしか歩くことができず、45度の方向はありません。私はA *を使用しています。私の場合、元のアルゴリズムの一部をより適したものに変更しました。

ここに私のpythonコードがあります:

私はそれを1000回実行します。

コストは1.4秒~1.5秒

def astar(m,startp,endp):
    w,h = 12,12
    sx,sy = startp
    ex,ey = endp
    #[parent node, x, y,g,f]
    node = [None,sx,sy,0,abs(ex-sx)+abs(ey-sy)] 
    closeList = [node]
    createdList = {}
    createdList[sy*w+sx] = node
    k=0
    while(closeList):
        node = closeList.pop(0)
        x = node[1]
        y = node[2]
        l = node[3]+1
        k+=1
        #find neighbours 
        #make the path not too strange
        if k&1:
            neighbours = ((x,y+1),(x,y-1),(x+1,y),(x-1,y))
        else:
            neighbours = ((x+1,y),(x-1,y),(x,y+1),(x,y-1))
        for nx,ny in neighbours:
            if nx==ex and ny==ey:
                path = [(ex,ey)]
                while node:
                    path.append((node[1],node[2]))
                    node = node[0]
                return list(reversed(path))            
            if 0<=nx<w and 0<=ny<h and m[ny][nx]==0:
                if ny*w+nx not in createdList:
                    nn = (node,nx,ny,l,l+abs(nx-ex)+abs(ny-ey))
                    createdList[ny*w+nx] = nn
                    #adding to closelist ,using binary heap
                    nni = len(closeList)
                    closeList.append(nn)
                    while nni:
                        i = (nni-1)>>1
                        if closeList[i][4]>nn[4]:
                            closeList[i],closeList[nni] = nn,closeList[i]
                            nni = i
                        else:
                            break


    return 'not found'

m = ((0,0,0,1,0,0,0,0,0,0,0,0),
     (0,0,0,0,1,0,1,0,0,0,0,0),
     (0,0,1,1,1,0,1,0,0,0,0,0),
     (0,0,0,0,1,0,1,0,0,0,0,0),
     (0,0,1,1,1,0,1,0,0,0,0,0),
     (0,0,0,1,1,0,1,0,0,0,0,0),
     (0,0,0,0,1,0,1,0,0,0,0,0),
     (0,0,0,0,0,0,1,0,0,0,0,0),
     (0,0,0,0,0,0,1,0,0,0,0,0),
     (0,0,0,0,0,0,1,0,0,0,0,0),
     (0,0,0,0,0,0,1,0,0,0,0,0),
     (0,0,0,0,0,0,1,0,0,0,0,0)
     )

t1 = time.time()
for i in range(1000):
    result = astar(m,(2,3),(11,11))
print(time.time()-t1) 
cm = [list(x[:]) for x in m]


if isinstance(result, list):
    for y in range(len(m)):
        my = m[y]
        for x in range(len(my)):
            for px,py in result:
                if px==x and py ==y:
                    cm[y][x] = '*'

for my in cm:
    print(' '.join([str(x) for x in my]))

exit(0)

今までにもっと速いまたは最速の方法を知っているかどうか教えてください。

4

1 に答える 1

1

* アルゴリズムは、既知のグラフに対して非常に高速です (すべてのエッジが既知であり、許容可能なヒューリスティックを使用してターゲットまでの距離を推定できます)。

A* アルゴリズムにはいくつかの改良が加えられており、最適化されていない代わりに高速化されています。最も一般的なのはA*-Epsilon (AKA bounded A*)です。アイデアは、アルゴリズムがノードを開発できるようにすることです(1+epsilon)*MIN(通常の A* は MIN のみを開発します)。結果は (もちろんイプシロン値に応じて) 通常はより高速なソリューションになりますが、見つかったパスはせいぜい(1+epsilon) * OPTIMAL.


別の可能な最適化は、一方の端から A* を実行し、もう一方 (「出口」) から同時に BFS を実行することです。この手法は双方向検索と呼ばれ、通常、問題の最終状態が 1 つの場合、重み付けされていないグラフのパフォーマンスを向上させる優れた方法です。このスレッドで一度、双方向検索の原理を説明しようとしました

于 2012-11-29T05:53:39.243 に答える