Pythonで迷路を幅優先探索で解き、全ての最短をルートを表示したいのですが、
最短距離をリストに格納するところまでは出来たのですがそれを元に
ルートを表示するところ(コード内のsearch_route関数)が上手く動作しません。
参考にしたサイト
具体的には次のようなマップな場合、(S:スタート G:ゴール $:ルート *:壁)
***** * * *S*G* * * *****
以下のように2つのルートを表示させたいのですが、
***** * * *S*G* *$$$* ***** ***** *$$$* *S*G* * * *****
コードを実行すると、次の様に2個目のルートに1つ目のルートが重なって表示されます。
***** * * *S*G* *$$$* ***** ***** *$$$* *S*G* *$$$* *****
以下のコードのsearch_route関数の部分をどのように直せばよいでしょうか?
Python
1map = [ 2 '*****', 3 '* *', 4 '*S*G*', 5 '* *', 6 '*****' 7 ]; 8 9 10def print_route(route): 11 for l in route: 12 print( "".join(l)) 13 14# mapから、'S'または'G'の位置を探して返す.無かったらNoneが返る 15def getLoc(map,SorG): 16 t=0 17 for l in map: 18 s=0 19 for n in l: 20 if n == SorG: 21 return (t,s) 22 s=s+1 23 t=t+1 24 25def search(map): 26 s = getLoc(map,'S') # mapからSの位置を探す 27 print ('スタート地点:'+str(s)) 28 if s == None: 29 print( 'スタート地点Sがないので、道はありません.') 30 else: 31 # s から'G'までの最短距離を返す 32 # search_from_s(map,s) 33 return search_from_s(map,s) 34 35 36# s から'G'までの最短距離を返す 37def search_from_s(map,s): 38 mapi = len(map) 39 mapj = len(map[0]) 40 # distanceは、Sから(t,s)までの仮の最短距離を保存する 41 distance=[[None for j in range(mapj)] for i in range(mapi)] 42 distance[s[0]][s[1]]=0 #スタート地点は距離0 43 next.append((s,0)) #探索位置とその位置までのそのルートでの最短距離を保存するリスト型キュー 44 45 while len(next) != 0: 46 n = next.pop(0) 47 a = n[0] # 探索位置 48 dis_a = n[1] # Sからa までの距離 49 # aの上下左右を見る. 50 if 0<=a[0]-1 : # 上。 回りが*で囲われているのでこの行はいらない 51 next_a(a[0]-1,a[1],dis_a,map,distance,next) 52 if a[0]+1<mapi : #下 53 next_a(a[0]+1,a[1],dis_a,map,distance,next) 54 if 0<=a[1]-1 : #左 55 next_a(a[0],a[1]-1,dis_a,map,distance,next) 56 if a[1]+1<mapj : #右 57 next_a(a[0],a[1]+1,dis_a,map,distance,next) 58 #結果出力。ついでにGの位置も出力 59 g=getLoc(map,'G') 60 print ('ゴール地点:'+str(g)) 61 print ('最短距離:'+str(distance[g[0]][g[1]])) 62 return distance 63 64 65#aの上下左右を見る.壁(*)だったら何もしない. 66#壁でなければdistanceのその位置と同じ位置を見て、 67#保存されている距離がdis_a+1よりも小さければ何もしない. 68#大きいか距離が保存されていなかったら、dis_a+1で置き換える 69#"G"だったら、dis_a+1を返し、探索終了. 70#"G"でなければ、nextにその位置とdis_a+1を保存する. 71def next_a(i,j,dis_a,map,distance,next): 72 if map[i][j] == '*': 73 return 74 if distance[i][j] == None: 75 distance[i][j]=dis_a+1 76 if map[i][j] != 'G': #ゴールでないないなら 77 next.append(((i,j),dis_a+1)) 78 else: 79 del next[:] 80 else: 81 # 元のコード distance[i][j] < dis_a+1 となっていたが、距離が同じなら調べる必要は無い 82 if distance[i][j] <= dis_a+1: 83 return 84 else: 85 distance[i][j] = dis_a+1 86 if map[i][j] != 'G': 87 next.append(((i,j),dis_a+1)) 88 else: del next [:] 89 90# nextをグローバル変数にしないと、next [:] と while len(next) != 0: 91# が意味をなさず、ゴールに来ても他の探索ルートが探索を止めない。 92 93""" 94map:マップ 95distance:スタートからの距離を記したリスト 96route:ゴールからの探索ルートに$を記したもの 97dis:スタート、ゴール間の最短距離から1ずつ引いた値 98s:スタートの座標 99g:ゴールの座標 100a:探索している座標 101""" 102def search_route(map, distance, route, dis, s, g, a): 103 route = route.copy() 104 a = a.copy() 105 106 if a == s: 107 # スタートとゴールも$になっているので、SとGで上書き 108 route[s[0]][s[1]]='S' 109 route[g[0]][g[1]]="G" 110 111 print_route(route) 112 print() 113 114 # 枠外に行くと終了 115 if a[0]>=mapi or a[0]<0 or a[1]<0 or a[1]>=mapj: 116 return 117 118 # 最短ルートでないと終了 119 if distance[a[0]][a[1]]!=dis: 120 return 121 122 if distance[a[0]][a[1]]==dis: 123 route[a[0]][a[1]]='$' 124 125 dis=dis-1 126 127 search_route(map,distance, route, dis,s, g, [a[0]+1,a[1]]) 128 search_route(map,distance, route, dis,s, g, [a[0]-1,a[1]]) 129 search_route(map,distance, route, dis,s, g, [a[0],a[1]-1]) 130 search_route(map,distance, route, dis,s, g, [a[0],a[1]+1]) 131 132 133next = [] 134# 迷路を示す配列を渡すとSからGまでの最短距離を返す 135distance = search(map) 136 137mapi = len(map) 138mapj = len(map[0]) 139 140route = [] 141 142for i in range(mapi): 143 lst=[] 144 for j in range(mapj): 145 lst.append(map[i][j]) 146 # print(lst) 147 route.append(lst) 148 149s=getLoc(map,'S') 150s = list(s) 151g=getLoc(map,'G') 152g = list(g) 153a=g 154 155dis=distance[g[0]][g[1]] 156 157search_route(map,distance, route, dis, s, g, a)
「最短距離をリストに格納するところまでは出来た」とのことですが、コードのどの部分で確認できましたか?
回答1件
あなたの回答
tips
プレビュー