#author("2026-07-10T09:10:28+09:00;2023-02-23T23:33:35+09:00","default:vip","vip")
[[問題文>練習問題#d4135691]]
#author("2026-07-11T15:41:32+09:00;2023-02-23T23:33:35+09:00","default:vip","vip")
[[問題文>練習問題#maze]]

[[A*探索>https://ja.wikipedia.org/?curid=157096]]。
 #!/usr/bin/python
 import heapq
 
 R, C, N = 10, 10, 10
 
 class Cell(object):
     def __init__(self, r, c, reachable):
         self.r = r
         self.c = c
         self.is_reachable = reachable
         self.parent = None
         self.moving_cost = 0  # 移動コスト
         self.heuristic_cost = 0  # ヒューリスティックコスト
         self.score = 0  # スコア = 移動コスト + ヒューリスティックコスト
 
     def __lt__(self, other):
         return self.heuristic_cost < other.heuristic_cost
 
 
 class AStar(object):
     def __init__(self, _mp):
         self.op = []
         heapq.heapify(self.op)
         self.cl = set()
         self.cells = []
         self.grid_height = R
         self.grid_width = C
         self.start = None
         self.end = None
         self.mp = _mp
 
     def init_grid(self):
         for r in range(self.grid_height):
             for c in range(self.grid_width):
                 reachable = mp[r][c] != '#'
                 self.cells.append(Cell(r, c, reachable))
         for r in range(self.grid_height):
             for c in range(self.grid_width):
                 if r == 0 and mp[r][c] == ' ':
                     self.start = self.__get_cell(r, c)
                 if r == R - 1 and mp[r][c] == ' ':
                     self.end = self.__get_cell(r, c)
 
     def __get_heuristic(self, cell):
         return N * (abs(cell.r - self.end.r) + abs(cell.c - self.end.c))
 
     def __get_cell(self, r, c):
         return self.cells[r * self.grid_height + c]
 
     def __get_adjacent_cells(self, cell):
         cells = []
         if cell.r < self.grid_height - 1:
             cells.append(self.__get_cell(cell.r + 1, cell.c))
         if cell.c < self.grid_width - 1:
             cells.append(self.__get_cell(cell.r,     cell.c + 1))
         if cell.r > 0:
             cells.append(self.__get_cell(cell.r - 1, cell.c))
         if cell.c > 0:
             cells.append(self.__get_cell(cell.r,     cell.c - 1))
         return cells
 
     def __display_path(self):
         cell = self.end
         mp[self.start.r][self.start.c], mp[self.end.r][self.end.c] = '+', '+'
         while cell.parent is not self.start:
             cell = cell.parent
             mp[cell.r][cell.c] = '+'
         print('\n'.join(''.join(mp[r]) for r in range(R)))
 
     def __update_cell(self, adj, cell):
         adj.moving_cost = cell.moving_cost + N
         adj.heuristic_cost = self.__get_heuristic(adj)
         adj.parent = cell
         adj.score = adj.heuristic_cost + adj.moving_cost
 
     def process(self):
         heapq.heappush(self.op, (self.start.score, self.start))
         while len(self.op):
             _, cell = heapq.heappop(self.op)
             self.cl.add(cell)
             if cell is self.end:
                 self.__display_path()
                 break
             adj_cells = self.__get_adjacent_cells(cell)
             for c in adj_cells:
                 if c.is_reachable and c not in self.cl:
                     if (c.score, c) in self.op:
                         if c.moving_cost > cell.moving_cost + N:
                             self.__update_cell(c, cell)
                     else:
                         self.__update_cell(c, cell)
                         heapq.heappush(self.op, (c.score, c))
 
 mp = []
 print('input: ')
 while True:
     s = input()
     if s == '': break
     mp.append(s)
 mp = list(map(list, mp))
 astar = AStar(mp)
 astar.init_grid()
 astar.process()

----
[[幅優先探索>https://ja.wikipedia.org/?curid=12889]]。空の入力で[[VIP迷路>#vip-maze]]を解かせます。
 import heapq
 
 maze = []
 print('input: ')
 while True:
     s = input()
     if s == '': break
     maze.append(s)
 
 if len(maze) == 0:
     s = """\
 # ##############################
 #   #     # #    #   ###     # #
 ## # ## #   ## #   #  #  # #   #
 #    #  # # #  # # # #  # # ## #
 # ## ## #  # # #  ###  #       #
 #  #  # # ## # # # #  #  # ## ##
 ##  #   #      #     #  #   #  #
 ###################### #########"""
     print(f"{s}\n")
     maze = s.split("\n")
 
 UNVISITED = None
 WALL = (-1, -1)
 PATH = (-2,-2)
 
 ch_2_pt = lambda ch: WALL if ch == '#' else UNVISITED
 grid = [[ch_2_pt(ch) for ch in row_str] for row_str in maze]
 H = len(grid)
 W = len(grid[0])
 
 # detecting the start and goal
 doors = {'west': None, 'east': None, 'north': None, 'south': None} 
 for y in range(H):
     if grid[y][ 0 ] == UNVISITED: doors['west'] = (y, 0)
     if grid[y][W-1] == UNVISITED: doors['east'] = (y, W-1)
 for x in range(W):
     if grid[ 0 ][x] == UNVISITED: doors['north'] = (0, x)
     if grid[H-1][x] == UNVISITED: doors['south'] = (H-1, x)
 start, goal = list(d for d in doors.values() if d)[0:2]
 
 # Breadth First Search (BFS)
 from collections import deque
 queue = deque([start])
 grid[start[0]][start[1]] = WALL
 
 while len(queue) > 0:
     y, x = queue.popleft()
     if (y, x) == goal:
         break
     for (dy, dx) in ((-1,0),(0,1),(1,0),(0,-1)):
             if y+dy < 0 or H <= y+dy or x+dx < 0 or W <= x+dx:
                 continue
             if grid[y+dy][x+dx] == UNVISITED:
                 queue.append((y+dy, x+dx))
                 grid[y+dy][x+dx] = (y, x)
                 
 cur = goal
 while cur != WALL:
     y, x = cur
     cur = grid[y][x]
     grid[y][x] = PATH
 
 def pt_2_ch(pt):
     if pt == WALL: return '.'
     elif pt == PATH: return '*'
     else: return ' '
     
 maze_solved = "\n".join(''.join(pt_2_ch(pt) for pt in row) for row in grid)
 print(maze_solved)

&aname(vip-maze);
>
 # ##############################
 #   #     # #    #   ###     # #
 ## # ## #   ## #   #  #  # #   #
 #    #  # # #  # # # #  # # ## #
 # ## ## #  # # #  ###  #       #
 #  #  # # ## # # # #  #  # ## ##
 ##  #   #      #     #  #   #  #
 ###################### #########
 
 .*..............................
 .** .  ***. . ***.   ...*****. .
 ..*. ..*.*  ..*.*  .  .**. .***.
 . ***. *.*. . *.*. . .**. . ..*.
 . ..*..*.* . .*.* ...**.*******.
 .  .**.*.*.. .*.*. .**.**. .. ..
 ..  .***.******.*****.**.   .  .
 ......................*.........

----
初心者用:スタートからゴールへの経路を全て塗りつぶすアルゴリズムです。

 #例題の迷路をリスト型で入力しておきます。
 maze = """\
 ######## #
 #        #
 # ###### #
 # #    # #
 # #### # #
 #      # #
 ######## #
 ##   #   #
 #  #   # #
 # ########""".split("\n")
 
 print('\nこれは入力された迷路です。')
 for i in range(10):	#入力した迷路を表示します。
 	print(maze[i])
 
 print('\nこれは経路を全て+で塗りつぶしたものです。')
 for i in range(10):	#経路をすべて+で塗りつぶします。
 	maze[i] = maze[i].replace(' ','+')
 	print(maze[i])
 
 def dig(mat,row,col):
 	st = mat[row-1][col] + mat[row][col+1] + mat[row+1][col] + mat[row][col-1]
 	cnt = st.count('#') + st.count(' ')
 	if cnt >= 3:
 		mat[row] = mat[row][:col] + ' ' + mat[row][col+1:]
 	else:
 		pass
 
 def ent_dig():
 	for i in range(1,9):
 		for j in range(1,9):
 			if maze[i][j] == '+':
 				dig(maze,i,j)
 
 cnt = 0
 while True:
 	pre_maze = list(maze)
 	ent_dig()
 	if maze == pre_maze:
 		print('\n経路検出の結果です。')
 		for i in range(10):
 			print(maze[i])
 		break
 	else:
 		cnt += 1
 		print('\n{0}回目の誤経路削除の結果です。'.format(cnt))
 		for i in range(10):
 			print(maze[i])

トップ   編集 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS