Добавлен паттерн Observer. Подготовлены лабиринты и выполнены замеры
This commit is contained in:
parent
e77bf45914
commit
06a8a01c7f
101
YanyaevAA/task2/docs/data/100x100.txt
Normal file
101
YanyaevAA/task2/docs/data/100x100.txt
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
####################################################################################################
|
||||
#S # # # # # # # # #
|
||||
# ####### # ##### # ############# # ####### # ##### # ############# # ####### # ##### # ########## #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # ### # # # # # # # ######### # # # ### # # # # # # # ######### # # # ### # # # # # # # ###### # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # ### # # # # # # # ##### # # # # # ### # # # # # # # ##### # # # # # ### # # # # # # # ## # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # ####### # ############# ##### # # ####### # ############# ##### # # ####### # ############# # ##
|
||||
# # # # # # # # # # #
|
||||
# ################################# # ############################### # ########################## #
|
||||
# # # #
|
||||
# ################################# # ############################### # ########################## #
|
||||
# # # # # # #
|
||||
# # ############################### # # ############################# # # ######################## #
|
||||
# # # # # # # # # # #
|
||||
# # # ########################### # # # # ########################### # # # ###################### #
|
||||
# # # # # # # # # # # # # # # # #
|
||||
# # # # ####################### # # # # # # ####################### # # # # # ################## # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # ################### # # # # # # # # ################### # # # # # # # ############## # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # ############### # # # # # # # # # # ############### # # # # # # # # # ########## # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # ########### # # # # # # # # # # # # ########### # # # # # # # # # # # ###### # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # ####### # # # # # # # # # # # # # # ####### # # # # # # # # # # # # # ## # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # ### # # # # # # # # # # # # # # # ### # # # # # # # # # # # # # # ## # # # # # ##
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # ##
|
||||
# # # # # # # # ### ##### # # # # # # # ### ##### ### ##### # # # # # # # ### ##### ### # # # # # ##
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # ##
|
||||
# # # # # # # ### ######### # # # # # ### ######### ######### # # # # # ### ######### ### # # # # ##
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # ##
|
||||
# # # # # # ### ############# # # # ### ############# ######### # # # ### ############# ### # # # ##
|
||||
# # # # # # # # # # # # # # # # # # # # ##
|
||||
# # # # # ### ############### # # ### ############### ######### # # ### ############### ### # # # ##
|
||||
# # # # # # # # # # # # # # # # # ##
|
||||
# # # # ### ################# # ### ################# ######### # ### ################# ### # # # ##
|
||||
# # # # # # # # # # # # # # ##
|
||||
# # # ### ##################### ### ################# ######### ### ##################### ### # # ##
|
||||
# # # # # # # # # # # ##
|
||||
# # ### ######################### # ################# ######### # # ######################### ### ##
|
||||
# # # # # # # ##
|
||||
# ### ############################# ################# ######### # ############################# ####
|
||||
# # # # ##
|
||||
### ################################################# ######### # ##################################
|
||||
# # # #
|
||||
# ################################################### ######### # ##################################
|
||||
# # # # # #
|
||||
# # ################################################# ######### # # ################################
|
||||
# # # # # # # #
|
||||
# # # ############################################### ######### # # # ##############################
|
||||
# # # # # # # # # #
|
||||
# # # # ############################################# ######### # # # # ############################
|
||||
# # # # # # # # # # # #
|
||||
# # # # # ########################################### ######### # # # # # ##########################
|
||||
# # # # # # # # # # # # # #
|
||||
# # # # # # ######################################### ######### # # # # # # ########################
|
||||
# # # # # # # # # # # # # # # #
|
||||
# # # # # # # ####################################### ######### # # # # # # # ######################
|
||||
# # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # ##################################### ######### # # # # # # # # ####################
|
||||
# # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # ################################### ######### # # # # # # # # # ##################
|
||||
# # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # ################################# ######### # # # # # # # # # # ################
|
||||
# # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # ############################### ######### # # # # # # # # # # # ##############
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # ############################# ######### # # # # # # # # # # # # ############
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # ########################### ######### # # # # # # # # # # # # # ##########
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # ##
|
||||
# # # # # # # # # # # # # # ######################### ######### # # # # # # # # # # # # # # ##### ##
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # ##
|
||||
# # # # # # # # # # # # # # # ####################### ######### # # # # # # # # # # # # # # # # # ##
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # ##
|
||||
# # # # # # # # # # # # # # # # ################### # # # # # # # # # # # # # # # # # # # ##
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # ##
|
||||
# # # # # # # # # # # # # # # # # ############### # # # # # # # # # # # # # # # # # # # # ##
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # ##
|
||||
# # # # # # # # # # # # # # # # # # ########### # # # # # # # # # # # # # # # # # # # # # ##
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # ##
|
||||
# # # # # # # # # # # # # # # # # # # ####### # # # # # # # # # # # # # # # # # # # # # ##
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # ##
|
||||
# # # # # # # # # # # # # # # # # # # # ### # # # # # # # # # # # # # # # # # # # # # ##
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # ##
|
||||
# # # # # # # # # # # # # # # # # # # # ### # # # # # # # # # # # # # # # # # # # # ##
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # ##
|
||||
# # # # # # # # # # # # # # # # # # # ### # # # # # # # # # # # # # # # # # # # ##
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # ##
|
||||
# # # # # # # # # # # # # # # # # # ### # # # # # # # # # # # # # # # # # # ##
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # ##
|
||||
# # # # # # # # # # # # # # # # # ### # # # # # # # # # # # # # # # # # ##
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # ##
|
||||
# # # # # # # # # # # # # # # # ### # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # ####
|
||||
# # # # # # # # # # # # # # # ### # # # # # # # # # # # # # # # # #
|
||||
# E#
|
||||
####################################################################################################
|
||||
10
YanyaevAA/task2/docs/data/10x10.txt
Normal file
10
YanyaevAA/task2/docs/data/10x10.txt
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
##########
|
||||
#S #
|
||||
######## #
|
||||
# #
|
||||
# ########
|
||||
# #
|
||||
######## #
|
||||
# #
|
||||
# E#
|
||||
##########
|
||||
51
YanyaevAA/task2/docs/data/50x50.txt
Normal file
51
YanyaevAA/task2/docs/data/50x50.txt
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
##################################################
|
||||
#S# # # # # #
|
||||
# # ### # ##### # ### ####### ### ### # ### ### #
|
||||
# # # # # # # # # # # # # # # # #
|
||||
##### # ### # # # # ### # # ####### # ####### ###
|
||||
# # # # # # # # # # # #
|
||||
### # ####### # # ####### # ### ### # # ### ### #
|
||||
# # # # # # # # # # # # #
|
||||
# ######### # ######### # ### ### ####### ### # #
|
||||
# # # # # # # # # # # # #
|
||||
# # ### # ### # ####### ### # # # # ### # ##### #
|
||||
# # # # # # # # # # # # #
|
||||
### # ### # ######### ### ########### # # # ### #
|
||||
# # # # # # # # # # # #
|
||||
# ##### # # # ##### ### # # ######### # ####### #
|
||||
# # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # ### # # # # ##### # # # ##### #
|
||||
# # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # ### # # ##### # # # # # # # # # #
|
||||
# # # # # # # # # # # # # #
|
||||
##### ####### ### ####### ########### ####### # #
|
||||
# # # # # # # # #
|
||||
# ####### ####### # ####### ##### # ### ####### #
|
||||
# # # # # # # # # # # #
|
||||
# # ####### ####### ##### # # # # ### # # ########
|
||||
# # # # # # # # # # # # # # #
|
||||
# # # ####### ### ##### # # # # ### # # # # ### #
|
||||
# # # # # # # # # # # # # # # # #
|
||||
# # # # ####### ### # ####### ### # # # ##### # #
|
||||
# # # # # # # # # # # # # #
|
||||
# # # # # ####### ### # ####### ### # ######### #
|
||||
# # # # # # # # # # #
|
||||
####### # # ####### ### # ### ### # ########### #
|
||||
# # # # # # # # # # #
|
||||
# ####### # # ####### ### # # # ############### #
|
||||
# # # # # # # # #
|
||||
# # ####### ########### ####### # ############# #
|
||||
# # # # # # # # #
|
||||
# # # ####### ########### ####### # ######### # #
|
||||
# # # # # # # # # # # #
|
||||
# # # # ####### ########### ### # # # ##### # # #
|
||||
# # # # # # # # # # # # # #
|
||||
# # # # # ####### ########### # # # ####### # # #
|
||||
# # # # # # # # # #
|
||||
# ####### # ####### ############### # ######### #
|
||||
# # # # # # #
|
||||
# ######### # ####### ####################### # #
|
||||
# # # #
|
||||
############# ################################# #
|
||||
# E#
|
||||
##################################################
|
||||
20
YanyaevAA/task2/docs/data/empty.txt
Normal file
20
YanyaevAA/task2/docs/data/empty.txt
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
####################
|
||||
#S #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# E#
|
||||
####################
|
||||
16
YanyaevAA/task2/docs/data/maze_results.csv
Normal file
16
YanyaevAA/task2/docs/data/maze_results.csv
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
лабиринт,стратегия,время_мс,посещено_клеток,длина_пути
|
||||
10x10.txt,BFS,0.02810000005410984,30.0,29.0
|
||||
10x10.txt,DFS,0.038610000046901405,43.0,29.0
|
||||
10x10.txt,AStar,0.03273000111221336,30.0,29.0
|
||||
50x50.txt,BFS,0.7084800003212877,799.0,316.0
|
||||
50x50.txt,DFS,0.48563999953330494,562.0,350.0
|
||||
50x50.txt,AStar,0.6310500000836328,539.0,316.0
|
||||
100x100.txt,BFS,3.024820000428008,3576.0,196.0
|
||||
100x100.txt,DFS,0.44655999954557046,595.0,364.0
|
||||
100x100.txt,AStar,0.5645899997034576,522.0,196.0
|
||||
empty.txt,BFS,0.2849799988325685,324.0,35.0
|
||||
empty.txt,DFS,0.1592799999343697,324.0,171.0
|
||||
empty.txt,AStar,0.4022000000986736,324.0,35.0
|
||||
without_exit.txt,BFS,0.041259999125031754,48.0,0.0
|
||||
without_exit.txt,DFS,0.040809998608892784,48.0,0.0
|
||||
without_exit.txt,AStar,0.052090000826865435,48.0,0.0
|
||||
|
15
YanyaevAA/task2/docs/data/without_exit.txt
Normal file
15
YanyaevAA/task2/docs/data/without_exit.txt
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
###############
|
||||
#S #
|
||||
# ########### #
|
||||
# # # #
|
||||
# # ####### # #
|
||||
# # # # # #
|
||||
# # # ### # # #
|
||||
# # # #E# # # #
|
||||
# # # ### # # #
|
||||
# # # # # #
|
||||
# # ####### # #
|
||||
# # # #
|
||||
# ########### #
|
||||
# #
|
||||
###############
|
||||
|
|
@ -1,17 +1,20 @@
|
|||
from abc import ABC, abstractmethod
|
||||
from collections import deque
|
||||
import heapq
|
||||
import time
|
||||
import os
|
||||
import csv
|
||||
#Этап 1
|
||||
class Cell:
|
||||
def __init__(self, x, y, is_wall=False, is_start=False, is_exit=False):
|
||||
def __init__(self, x, y, isWall=False, isStart=False, isExit=False):
|
||||
self.x = x
|
||||
self.y = y
|
||||
self.is_wall = is_wall
|
||||
self.is_start = is_start
|
||||
self.is_exit = is_exit
|
||||
self.isWall = isWall
|
||||
self.isStart = isStart
|
||||
self.isExit = isExit
|
||||
|
||||
def isPassable(self):
|
||||
return not self.is_wall
|
||||
return not self.isWall
|
||||
|
||||
class Maze:
|
||||
def __init__(self, cells, width, height, start, exit):
|
||||
|
|
@ -59,15 +62,15 @@ class TextFileMazeBuilder(MazeBuilder):
|
|||
for x in range(width):
|
||||
char=lines[y][x]
|
||||
|
||||
is_wall = (char == '#')
|
||||
is_start = (char == 'S')
|
||||
is_exit = (char == 'E')
|
||||
isWall = (char == '#')
|
||||
isStart = (char == 'S')
|
||||
isExit = (char == 'E')
|
||||
|
||||
cell=Cell(x, y, is_wall, is_start, is_exit)
|
||||
cell=Cell(x, y, isWall, isStart, isExit)
|
||||
|
||||
if is_start:
|
||||
if isStart:
|
||||
start_cell =cell
|
||||
if is_exit:
|
||||
if isExit:
|
||||
exit_cell =cell
|
||||
row.append(cell)
|
||||
grid.append(row)
|
||||
|
|
@ -135,22 +138,30 @@ class AStar(PathFindingStrategy):
|
|||
if neighbor not in g_score or g_score_new < g_score[neighbor]:
|
||||
traveled_path[neighbor] = current
|
||||
g_score[neighbor] = g_score_new
|
||||
f_score = tentative_g_score + abs(neighbor.x - exit.x) + abs(neighbor.y - exit.y)
|
||||
f_score = g_score_new + abs(neighbor.x - exit.x) + abs(neighbor.y - exit.y)
|
||||
count += 1
|
||||
heapq.heappush(open_set, (f_score, count, neighbor))
|
||||
return [],len(traveled_path)
|
||||
|
||||
#Этап 4
|
||||
class SearchStats:
|
||||
def __init__(self, time, visited_cells, path_length):
|
||||
self.time = time
|
||||
self.visited_cells = visited_cells
|
||||
self.path_length = path_length
|
||||
|
||||
class MazeSolver:
|
||||
def __init__(self, maze, strategy):
|
||||
self.maze = maze
|
||||
self.strategy = strategy
|
||||
|
||||
self.observers = []
|
||||
def addObserver(self, observer):
|
||||
self.observers.append(observer)
|
||||
def setStrategy(self, strategy):
|
||||
self.strategy = strategy
|
||||
def solve(self):
|
||||
start_cell = self.maze.getStart()
|
||||
exit_cell = self.maze.getExit()
|
||||
start_cell = self.maze.start
|
||||
exit_cell = self.maze.exit
|
||||
|
||||
start_time = time.perf_counter()
|
||||
path, visited_cells = self.strategy.findPath(self.maze, start_cell, exit_cell)
|
||||
|
|
@ -158,7 +169,98 @@ class MazeSolver:
|
|||
|
||||
time_ms = (end_time - start_time) * 1000
|
||||
path_length = len(path)
|
||||
stats=SearchStats(time_ms, visited_cells, path_length)
|
||||
event = Event("path_found", data=stats)
|
||||
for observer in self.observers:
|
||||
observer.update(event)
|
||||
|
||||
return time_ms, visited_cells, path_length
|
||||
return stats
|
||||
|
||||
#Этап 5
|
||||
#5.1
|
||||
class Event:
|
||||
def __init__(self, event_type, data=None):
|
||||
self.event_type = event_type
|
||||
self.data = data
|
||||
|
||||
class Observer(ABC):
|
||||
@abstractmethod
|
||||
def update(self, event):
|
||||
pass
|
||||
|
||||
class ConsoleView(Observer):
|
||||
def update(self, event):
|
||||
if event.event_type == "path_found":
|
||||
stats=event.data
|
||||
print("Путь найден:")
|
||||
print("Время выполнения:", stats.time)
|
||||
print("Количество посещённых клеток:", stats.visited_cells)
|
||||
print("Длина найденного пути:", stats.path_length)
|
||||
if event.event_type == "move":
|
||||
x, y = event.data
|
||||
print(f"Игрок переместился в ячейку: {x}, {y}")
|
||||
if event.event_type == "maze_loaded":
|
||||
print("Загружен новый лабиринт")
|
||||
|
||||
def render(self, maze, path):
|
||||
for y in range(maze.height):
|
||||
row_str=""
|
||||
for x in range(maze.width):
|
||||
cell=maze.getCell(x, y)
|
||||
if cell == maze.start:
|
||||
row_str += "S"
|
||||
elif cell == maze.exit:
|
||||
row_str += "E"
|
||||
elif cell in path:
|
||||
row_str += "·"
|
||||
elif cell.isWall:
|
||||
row_str += "#"
|
||||
else:
|
||||
row_str += " "
|
||||
print(row_str)
|
||||
|
||||
#Этап 6
|
||||
mazes = ["10x10.txt","50x50.txt","100x100.txt","empty.txt","without_exit.txt"]
|
||||
|
||||
results =[["лабиринт",
|
||||
"стратегия",
|
||||
"время_мс",
|
||||
"посещено_клеток",
|
||||
"длина_пути"]]
|
||||
strategies = {
|
||||
"BFS": BFS(),
|
||||
"DFS": DFS(),
|
||||
"AStar": AStar()
|
||||
}
|
||||
builder = TextFileMazeBuilder()
|
||||
n=10
|
||||
directory = os.path.join("docs", "data")
|
||||
for maze_name in mazes:
|
||||
print(maze_name)
|
||||
file_name=os.path.join(directory, maze_name)
|
||||
maze = builder.buildFromFile(file_name)
|
||||
viewer=ConsoleView()
|
||||
for strategy_name, strategy in strategies.items():
|
||||
total_time = 0.0
|
||||
total_visited = 0
|
||||
total_path_length = 0
|
||||
|
||||
solver = MazeSolver(maze, strategy)
|
||||
|
||||
for _ in range(n):
|
||||
stats = solver.solve()
|
||||
total_time += stats.time
|
||||
total_visited += stats.visited_cells
|
||||
total_path_length += stats.path_length
|
||||
avg_time = total_time/n
|
||||
avg_visited = total_visited/n
|
||||
avg_path_length = total_path_length/n
|
||||
print(f"{maze_name} стратегия: {strategy_name} время_мс: {avg_time} посещено_клеток: {avg_visited} длина_пути: {avg_path_length}")
|
||||
results.append([maze_name, strategy_name, avg_time, avg_visited, avg_path_length])
|
||||
path, _ = strategy.findPath(maze, maze.start, maze.exit)
|
||||
path=path[1:-1]
|
||||
viewer.render(maze, path)
|
||||
csv_filename = os.path.join(directory, "maze_results.csv")
|
||||
with open(csv_filename, "w", newline="", encoding="utf-8-sig") as f:
|
||||
writer = csv.writer(f)
|
||||
writer.writerows(results)
|
||||
Loading…
Reference in New Issue
Block a user