[2] Лабораторная работа №2 - Лабиринт #280
11255
stepushovgs/labyrinth/benchmark.ipynb
Normal file
11255
stepushovgs/labyrinth/benchmark.ipynb
Normal file
File diff suppressed because it is too large
Load Diff
221
stepushovgs/labyrinth/docs/data/csv/banchmark.csv
Normal file
221
stepushovgs/labyrinth/docs/data/csv/banchmark.csv
Normal file
|
|
@ -0,0 +1,221 @@
|
|||
Лабиринт,Алгоритм,Время,Посещено клеток,Длина пути
|
||||
maze10x10,BFS,0.0744000026315916,25.0,16.0
|
||||
maze10x10,BFS,0.0757000016164965,25.0,16.0
|
||||
maze10x10,BFS,0.0727000006008893,25.0,16.0
|
||||
maze10x10,BFS,0.0742999982321634,25.0,16.0
|
||||
maze10x10,BFS,0.0537000014446675,25.0,16.0
|
||||
maze10x10,BFS,0.0547000017832033,25.0,16.0
|
||||
maze10x10,BFS,0.0569000003451947,25.0,16.0
|
||||
maze10x10,BFS,0.0665000006847549,25.0,16.0
|
||||
maze10x10,BFS,0.0543999994988553,25.0,16.0
|
||||
maze10x10,BFS,0.0548999996681232,25.0,16.0
|
||||
maze10x10(среднее),BFS,0.063820000650594,25.0,16.0
|
||||
maze50x50,BFS,1.4375999999174385,972.0,176.0
|
||||
maze50x50,BFS,1.698000000033062,972.0,176.0
|
||||
maze50x50,BFS,1.5351000001828652,972.0,176.0
|
||||
maze50x50,BFS,1.5220999994198792,972.0,176.0
|
||||
maze50x50,BFS,1.574800000526011,972.0,176.0
|
||||
maze50x50,BFS,1.4951999983168207,972.0,176.0
|
||||
maze50x50,BFS,1.511999998911051,972.0,176.0
|
||||
maze50x50,BFS,1.5139999995881226,972.0,176.0
|
||||
maze50x50,BFS,1.4908999983163085,972.0,176.0
|
||||
maze50x50,BFS,1.487499997892883,972.0,176.0
|
||||
maze50x50(среднее),BFS,1.526719999310444,972.0,176.0
|
||||
maze100x100,BFS,3.02670000019134,2345.0,197.0
|
||||
maze100x100,BFS,3.52529999872786,2345.0,197.0
|
||||
maze100x100,BFS,3.663800001959317,2345.0,197.0
|
||||
maze100x100,BFS,3.517799999826821,2345.0,197.0
|
||||
maze100x100,BFS,3.506500001094537,2345.0,197.0
|
||||
maze100x100,BFS,3.690400000778027,2345.0,197.0
|
||||
maze100x100,BFS,3.396100000827573,2345.0,197.0
|
||||
maze100x100,BFS,3.629499999078689,2345.0,197.0
|
||||
maze100x100,BFS,3.8606999987678137,2345.0,197.0
|
||||
maze100x100,BFS,3.4976999995706137,2345.0,197.0
|
||||
maze100x100(среднее),BFS,3.531450000082259,2345.0,197.0
|
||||
maze_empty,BFS,8.452400001260685,5328.0,158.0
|
||||
maze_empty,BFS,8.42489999922691,5328.0,158.0
|
||||
maze_empty,BFS,8.638600000267616,5328.0,158.0
|
||||
maze_empty,BFS,8.208700000977842,5328.0,158.0
|
||||
maze_empty,BFS,8.816000001388602,5328.0,158.0
|
||||
maze_empty,BFS,8.447899999737274,5328.0,158.0
|
||||
maze_empty,BFS,8.679799997480586,5328.0,158.0
|
||||
maze_empty,BFS,8.399000002100365,5328.0,158.0
|
||||
maze_empty,BFS,8.234299999458017,5328.0,158.0
|
||||
maze_empty,BFS,8.313599999382859,5328.0,158.0
|
||||
maze_empty(среднее),BFS,8.461520000128075,5328.0,158.0
|
||||
maze_no_path,BFS,1.6376999992644414,1245.0,0.0
|
||||
maze_no_path,BFS,1.7487000004621225,1245.0,0.0
|
||||
maze_no_path,BFS,1.933600000484148,1245.0,0.0
|
||||
maze_no_path,BFS,1.8192999996244907,1245.0,0.0
|
||||
maze_no_path,BFS,1.8314999979338609,1245.0,0.0
|
||||
maze_no_path,BFS,1.9929000009142328,1245.0,0.0
|
||||
maze_no_path,BFS,1.7305000001215376,1245.0,0.0
|
||||
maze_no_path,BFS,1.6904000003705733,1245.0,0.0
|
||||
maze_no_path,BFS,1.6647000011289492,1245.0,0.0
|
||||
maze_no_path,BFS,1.733000000967877,1245.0,0.0
|
||||
maze_no_path(среднее),BFS,1.778230000127223,1245.0,0.0
|
||||
maze10x10,DFS,0.0433999994129408,24.0,16.0
|
||||
maze10x10,DFS,0.0624999993306119,24.0,16.0
|
||||
maze10x10,DFS,0.0682999998389277,24.0,16.0
|
||||
maze10x10,DFS,0.0490999991598073,24.0,16.0
|
||||
maze10x10,DFS,0.0468999969598371,24.0,16.0
|
||||
maze10x10,DFS,0.0467999998363666,24.0,16.0
|
||||
maze10x10,DFS,0.0689000007696449,24.0,16.0
|
||||
maze10x10,DFS,0.0502000002597924,24.0,16.0
|
||||
maze10x10,DFS,0.0493999978061765,24.0,16.0
|
||||
maze10x10,DFS,0.0475000015285331,24.0,16.0
|
||||
maze10x10(среднее),DFS,0.0532999994902638,24.0,16.0
|
||||
maze50x50,DFS,1.184500000817934,920.0,176.0
|
||||
maze50x50,DFS,1.274300000659423,920.0,176.0
|
||||
maze50x50,DFS,1.3567999994847924,920.0,176.0
|
||||
maze50x50,DFS,1.27749999955995,920.0,176.0
|
||||
maze50x50,DFS,1.4292000014393125,920.0,176.0
|
||||
maze50x50,DFS,1.2790999971912242,920.0,176.0
|
||||
maze50x50,DFS,1.329700000496814,920.0,176.0
|
||||
maze50x50,DFS,1.257100000657374,920.0,176.0
|
||||
maze50x50,DFS,1.4220000011846423,920.0,176.0
|
||||
maze50x50,DFS,1.372599999740487,920.0,176.0
|
||||
maze50x50(среднее),DFS,1.3182800001231954,920.0,176.0
|
||||
maze100x100,DFS,3.26380000115023,2609.0,197.0
|
||||
maze100x100,DFS,3.768599999602884,2609.0,197.0
|
||||
maze100x100,DFS,3.677199998492142,2609.0,197.0
|
||||
maze100x100,DFS,3.6672999995062128,2609.0,197.0
|
||||
maze100x100,DFS,3.9711999997962266,2609.0,197.0
|
||||
maze100x100,DFS,3.7203000028966926,2609.0,197.0
|
||||
maze100x100,DFS,3.739499999937834,2609.0,197.0
|
||||
maze100x100,DFS,3.717999999935273,2609.0,197.0
|
||||
maze100x100,DFS,3.63140000263229,2609.0,197.0
|
||||
maze100x100,DFS,3.789499998674728,2609.0,197.0
|
||||
maze100x100(среднее),DFS,3.6946800002624514,2609.0,197.0
|
||||
maze_empty,DFS,5.714499999157852,5328.0,2578.0
|
||||
maze_empty,DFS,5.989400000544265,5328.0,2578.0
|
||||
maze_empty,DFS,5.901900000026217,5328.0,2578.0
|
||||
maze_empty,DFS,5.935400000453228,5328.0,2578.0
|
||||
maze_empty,DFS,5.898100000194972,5328.0,2578.0
|
||||
maze_empty,DFS,6.119699999544537,5328.0,2578.0
|
||||
maze_empty,DFS,5.7996000032289885,5328.0,2578.0
|
||||
maze_empty,DFS,6.074900000385242,5328.0,2578.0
|
||||
maze_empty,DFS,5.99549999969895,5328.0,2578.0
|
||||
maze_empty,DFS,5.661700000928249,5328.0,2578.0
|
||||
maze_empty(среднее),DFS,5.90907000041625,5328.0,2578.0
|
||||
maze_no_path,DFS,2.58909999683965,1245.0,0.0
|
||||
maze_no_path,DFS,1.87980000191601,1245.0,0.0
|
||||
maze_no_path,DFS,1.6818000003695488,1245.0,0.0
|
||||
maze_no_path,DFS,1.8071000013151208,1245.0,0.0
|
||||
maze_no_path,DFS,1.6453999996883797,1245.0,0.0
|
||||
maze_no_path,DFS,1.7989999978453852,1245.0,0.0
|
||||
maze_no_path,DFS,1.778600002580788,1245.0,0.0
|
||||
maze_no_path,DFS,1.668100001552375,1245.0,0.0
|
||||
maze_no_path,DFS,1.6705999987607356,1245.0,0.0
|
||||
maze_no_path,DFS,1.7055999996955509,1245.0,0.0
|
||||
maze_no_path(среднее),DFS,1.8225100000563543,1245.0,0.0
|
||||
maze10x10,A*,0.0639999998384155,24.0,16.0
|
||||
maze10x10,A*,0.0728000013623386,24.0,16.0
|
||||
maze10x10,A*,0.0684000006003771,24.0,16.0
|
||||
maze10x10,A*,0.0645000000076834,24.0,16.0
|
||||
maze10x10,A*,0.0641000005998648,24.0,16.0
|
||||
maze10x10,A*,0.0661000012769363,24.0,16.0
|
||||
maze10x10,A*,0.0680000011925585,24.0,16.0
|
||||
maze10x10,A*,0.0658999997540377,24.0,16.0
|
||||
maze10x10,A*,0.0686999992467463,24.0,16.0
|
||||
maze10x10,A*,0.0715000023774337,24.0,16.0
|
||||
maze10x10(среднее),A*,0.0674000006256392,24.0,16.0
|
||||
maze50x50,A*,1.6070000019681174,763.0,176.0
|
||||
maze50x50,A*,1.840099997934885,763.0,176.0
|
||||
maze50x50,A*,1.7380999997840263,763.0,176.0
|
||||
maze50x50,A*,1.808999997592764,763.0,176.0
|
||||
maze50x50,A*,1.6594000007899012,763.0,176.0
|
||||
maze50x50,A*,1.821499998186482,763.0,176.0
|
||||
maze50x50,A*,1.6746000001148786,763.0,176.0
|
||||
maze50x50,A*,2.4415000007138588,763.0,176.0
|
||||
maze50x50,A*,2.8442000002542045,763.0,176.0
|
||||
maze50x50,A*,1.8294000001333188,763.0,176.0
|
||||
maze50x50(среднее),A*,1.926479999747244,763.0,176.0
|
||||
maze100x100,A*,2.5787000013224315,1194.0,197.0
|
||||
maze100x100,A*,2.7651999989757314,1194.0,197.0
|
||||
maze100x100,A*,2.860200002032798,1194.0,197.0
|
||||
maze100x100,A*,2.8369999999995343,1194.0,197.0
|
||||
maze100x100,A*,2.906600002461346,1194.0,197.0
|
||||
maze100x100,A*,2.7929999996558763,1194.0,197.0
|
||||
maze100x100,A*,3.06319999799598,1194.0,197.0
|
||||
maze100x100,A*,2.834499999153195,1194.0,197.0
|
||||
maze100x100,A*,2.7511999978742097,1194.0,197.0
|
||||
maze100x100,A*,2.793700001348043,1194.0,197.0
|
||||
maze100x100(среднее),A*,2.8183300000819145,1194.0,197.0
|
||||
maze_empty,A*,13.580099999671802,5328.0,158.0
|
||||
maze_empty,A*,13.65030000306433,5328.0,158.0
|
||||
maze_empty,A*,13.666799997736234,5328.0,158.0
|
||||
maze_empty,A*,14.009900001838105,5328.0,158.0
|
||||
maze_empty,A*,13.549700001021847,5328.0,158.0
|
||||
maze_empty,A*,13.690499999938766,5328.0,158.0
|
||||
maze_empty,A*,13.920800000050804,5328.0,158.0
|
||||
maze_empty,A*,13.680399999429936,5328.0,158.0
|
||||
maze_empty,A*,13.70409999799449,5328.0,158.0
|
||||
maze_empty,A*,13.471199999912642,5328.0,158.0
|
||||
maze_empty(среднее),A*,13.692380000065896,5328.0,158.0
|
||||
maze_no_path,A*,2.5481999982730485,1245.0,0.0
|
||||
maze_no_path,A*,2.8395000008458737,1245.0,0.0
|
||||
maze_no_path,A*,2.7317999993101694,1245.0,0.0
|
||||
maze_no_path,A*,2.7791000029537827,1245.0,0.0
|
||||
maze_no_path,A*,2.718199997616466,1245.0,0.0
|
||||
maze_no_path,A*,2.6510000025155023,1245.0,0.0
|
||||
maze_no_path,A*,2.674000003025867,1245.0,0.0
|
||||
maze_no_path,A*,2.6954999993904494,1245.0,0.0
|
||||
maze_no_path,A*,2.705599999899277,1245.0,0.0
|
||||
maze_no_path,A*,2.7092999989690725,1245.0,0.0
|
||||
maze_no_path(среднее),A*,2.705220000279951,1245.0,0.0
|
||||
maze10x10,Dijkstra,0.0546999981452245,25.0,16.0
|
||||
maze10x10,Dijkstra,0.0766999983170535,25.0,16.0
|
||||
maze10x10,Dijkstra,0.0564999972993973,25.0,16.0
|
||||
maze10x10,Dijkstra,0.055399999837391,25.0,16.0
|
||||
maze10x10,Dijkstra,0.0901999992493074,25.0,16.0
|
||||
maze10x10,Dijkstra,0.0636000004305969,25.0,16.0
|
||||
maze10x10,Dijkstra,0.0642000013613142,25.0,16.0
|
||||
maze10x10,Dijkstra,0.0633000017842277,25.0,16.0
|
||||
maze10x10,Dijkstra,0.1010999985737726,25.0,16.0
|
||||
maze10x10,Dijkstra,0.0564000001759268,25.0,16.0
|
||||
maze10x10(среднее),Dijkstra,0.0682099995174212,25.0,16.0
|
||||
maze50x50,Dijkstra,1.7924999992828816,972.0,176.0
|
||||
maze50x50,Dijkstra,1.7590999996173196,972.0,176.0
|
||||
maze50x50,Dijkstra,1.8786000000545755,972.0,176.0
|
||||
maze50x50,Dijkstra,1.80720000207657,972.0,176.0
|
||||
maze50x50,Dijkstra,1.840500000980683,972.0,176.0
|
||||
maze50x50,Dijkstra,1.7653000031714328,972.0,176.0
|
||||
maze50x50,Dijkstra,1.9654999996419065,972.0,176.0
|
||||
maze50x50,Dijkstra,1.79049999860581,972.0,176.0
|
||||
maze50x50,Dijkstra,1.797400000214111,972.0,176.0
|
||||
maze50x50,Dijkstra,1.7621000006329268,972.0,176.0
|
||||
maze50x50(среднее),Dijkstra,1.8158700004278217,972.0,176.0
|
||||
maze100x100,Dijkstra,3.954100000555627,2345.0,197.0
|
||||
maze100x100,Dijkstra,4.249900001013884,2345.0,197.0
|
||||
maze100x100,Dijkstra,4.330399999162182,2345.0,197.0
|
||||
maze100x100,Dijkstra,4.545499999949243,2345.0,197.0
|
||||
maze100x100,Dijkstra,4.328899998654379,2345.0,197.0
|
||||
maze100x100,Dijkstra,4.53189999825554,2345.0,197.0
|
||||
maze100x100,Dijkstra,4.320200001529884,2345.0,197.0
|
||||
maze100x100,Dijkstra,4.45179999951506,2345.0,197.0
|
||||
maze100x100,Dijkstra,4.341399999248097,2345.0,197.0
|
||||
maze100x100,Dijkstra,4.510700000537327,2345.0,197.0
|
||||
maze100x100(среднее),Dijkstra,4.356479999842122,2345.0,197.0
|
||||
maze_empty,Dijkstra,11.241200001677498,5328.0,158.0
|
||||
maze_empty,Dijkstra,11.333599999488795,5328.0,158.0
|
||||
maze_empty,Dijkstra,11.416299999837063,5328.0,158.0
|
||||
maze_empty,Dijkstra,11.310300000332065,5328.0,158.0
|
||||
maze_empty,Dijkstra,11.522700002387865,5328.0,158.0
|
||||
maze_empty,Dijkstra,11.251799998717615,5328.0,158.0
|
||||
maze_empty,Dijkstra,11.823299999377925,5328.0,158.0
|
||||
maze_empty,Dijkstra,11.53350000095088,5328.0,158.0
|
||||
maze_empty,Dijkstra,11.488299998745788,5328.0,158.0
|
||||
maze_empty,Dijkstra,11.370600001100684,5328.0,158.0
|
||||
maze_empty(среднее),Dijkstra,11.429160000261618,5328.0,158.0
|
||||
maze_no_path,Dijkstra,2.119600001606159,1245.0,0.0
|
||||
maze_no_path,Dijkstra,2.07120000050054,1245.0,0.0
|
||||
maze_no_path,Dijkstra,2.1706000006815884,1245.0,0.0
|
||||
maze_no_path,Dijkstra,2.152000000933185,1245.0,0.0
|
||||
maze_no_path,Dijkstra,2.309299998159986,1245.0,0.0
|
||||
maze_no_path,Dijkstra,2.229900001111673,1245.0,0.0
|
||||
maze_no_path,Dijkstra,2.0933000014338177,1245.0,0.0
|
||||
maze_no_path,Dijkstra,2.175500001612818,1245.0,0.0
|
||||
maze_no_path,Dijkstra,2.386500000284286,1245.0,0.0
|
||||
maze_no_path,Dijkstra,2.2796000012021977,1245.0,0.0
|
||||
maze_no_path(среднее),Dijkstra,2.198750000752625,1245.0,0.0
|
||||
|
BIN
stepushovgs/labyrinth/docs/data/img/100x100.pdf
Normal file
BIN
stepushovgs/labyrinth/docs/data/img/100x100.pdf
Normal file
Binary file not shown.
BIN
stepushovgs/labyrinth/docs/data/img/10x10.pdf
Normal file
BIN
stepushovgs/labyrinth/docs/data/img/10x10.pdf
Normal file
Binary file not shown.
BIN
stepushovgs/labyrinth/docs/data/img/50x50.pdf
Normal file
BIN
stepushovgs/labyrinth/docs/data/img/50x50.pdf
Normal file
Binary file not shown.
BIN
stepushovgs/labyrinth/docs/data/img/empty.pdf
Normal file
BIN
stepushovgs/labyrinth/docs/data/img/empty.pdf
Normal file
Binary file not shown.
BIN
stepushovgs/labyrinth/docs/data/img/no_path.pdf
Normal file
BIN
stepushovgs/labyrinth/docs/data/img/no_path.pdf
Normal file
Binary file not shown.
745
stepushovgs/labyrinth/docs/data/main.ipynb
Normal file
745
stepushovgs/labyrinth/docs/data/main.ipynb
Normal file
File diff suppressed because one or more lines are too long
183
stepushovgs/labyrinth/docs/Отчёт.md
Normal file
183
stepushovgs/labyrinth/docs/Отчёт.md
Normal file
|
|
@ -0,0 +1,183 @@
|
|||
## Описание работы
|
||||
Схема реализованных классов:
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class TextFileMazeBuilder {
|
||||
+buildFromFile(filename): Maze
|
||||
}
|
||||
class Maze {
|
||||
-cells: Cell[]
|
||||
-width: int
|
||||
-height: int
|
||||
-start: Cell
|
||||
-exit: Cell
|
||||
+getCell(x,y): Cell
|
||||
+getNeighbors(cell): List~Cell~
|
||||
}
|
||||
|
||||
class Cell {
|
||||
-x: int
|
||||
-y: int
|
||||
-isWall: bool
|
||||
-isStart: bool
|
||||
-isExit: bool
|
||||
-value: int
|
||||
+isPassable(): bool
|
||||
+getXY(): tuple[int, int]
|
||||
+toStr(): str
|
||||
}
|
||||
|
||||
class MazeBuilder {
|
||||
<<interface>>
|
||||
+buildFromFile(filename): Maze
|
||||
}
|
||||
|
||||
class PathFindingStrategy {
|
||||
<<interface>>
|
||||
+name(): str
|
||||
+findPath(maze, start, exit): tuple[list[tuple[int, int]], int]
|
||||
}
|
||||
|
||||
class BFS {
|
||||
+findPath(maze, start, exit): tuple[list[tuple[int, int]], int]
|
||||
}
|
||||
class DFS {
|
||||
+findPath(maze, start, exit): tuple[list[tuple[int, int]], int]
|
||||
}
|
||||
class AStar {
|
||||
+findPath(maze, start, exit): tuple[list[tuple[int, int]], int]
|
||||
+heuristic(a, b): int
|
||||
}
|
||||
class Dijkstra {
|
||||
+findPath(maze, start, exit): tuple[list[tuple[int, int]], int]
|
||||
}
|
||||
|
||||
class SearchStats {
|
||||
-timeMs: float
|
||||
-visitedCells: int
|
||||
-pathLength: int
|
||||
-path: list~Cell~
|
||||
}
|
||||
|
||||
class MazeSolver {
|
||||
-Maze maze
|
||||
-PathFindingStrategy strategy
|
||||
-Observer observer
|
||||
+strategyName: str
|
||||
+setStrategy(strategy)
|
||||
+solve(): SearchStats
|
||||
}
|
||||
|
||||
class Observer {
|
||||
<<interface>>
|
||||
+update(event)
|
||||
}
|
||||
|
||||
class ConsoleView {
|
||||
+update(event)
|
||||
+render(maze, player_position, path)
|
||||
}
|
||||
|
||||
class Event {
|
||||
-event: str
|
||||
-maze: Maze
|
||||
-player_position: tuple[int,int]
|
||||
-path: list~Cell~
|
||||
}
|
||||
|
||||
MazeBuilder <|.. TextFileMazeBuilder
|
||||
MazeBuilder --> Maze : creates
|
||||
PathFindingStrategy <|.. BFS
|
||||
PathFindingStrategy <|.. DFS
|
||||
PathFindingStrategy <|.. AStar
|
||||
PathFindingStrategy <|.. Dijkstra
|
||||
MazeSolver --> PathFindingStrategy : uses
|
||||
MazeSolver --> Maze : uses
|
||||
Maze --> Cell : uses
|
||||
MazeSolver --> SearchStats : return
|
||||
Observer <|.. ConsoleView
|
||||
ConsoleView --> Event : get
|
||||
MazeSolver --> Observer : notifies
|
||||
```
|
||||
1. Листинги ключевых классов (можно выборочно) или ссылка на репозиторий.
|
||||
- Классы `Cell` и `Maze` представлены в папке `source/classes/`
|
||||
- Реализации интерфейса `Builder` и класса `TextFileMazeBuilder` находятся в `source/builder/`
|
||||
- Реализации интерфейса `Observer` и класса `ConsoleView` находятся в `source/observer/`
|
||||
- Интерфейс `strategy`, класс `MazeSolver` и реализации алгоритмов BFS, DFS, A*, Дейкстра находятся в папке `source/strategy/`
|
||||
## Результаты экспериментов
|
||||
Все результаты находятся в `/data/cvs/banchmark.csv`, тесты запускаются через файл `benchmark.ipynb`. Лабиринты, на которых проходили тесты, находятся в директори `mazes/benchmarks/`
|
||||
Проведём 10 замеров и отобразим результаты на графиках (пунктиром отмечены среднее значение)
|
||||
![[10x10.pdf]]
|
||||
![[50x50.pdf]]
|
||||
![[100x100.pdf]]
|
||||
![[empty.pdf]]
|
||||
![[no_path.pdf]]
|
||||
|
||||
Заполним таблицу для количества посещённых клеток для каждого алгоритма:
|
||||
|
||||
| Лабиринт | BFS | DFS | A* | Дейкстра |
|
||||
| :------------: | :--: | :--: | :--: | :------: |
|
||||
| $10\times10$ | 25 | 24 | 24 | 25 |
|
||||
| $50\times50$ | 972 | 920 | 763 | 972 |
|
||||
| $100\times100$ | 2345 | 2609 | 1194 | 2345 |
|
||||
| Пустой | 5328 | 5328 | 5328 | 5328 |
|
||||
| Без выхода | 1245 | 1245 | 1245 | 1245
|
||||
|
||||
## Анализ результатов
|
||||
- **DFS** быстрее на большинстве лабиринтов, но путь может быть неоптимальным
|
||||
В качестве демонстрации, сравним работу DFS и BFS на небольшом пустом лабиринте:
|
||||
```
|
||||
BFS
|
||||
Путь найден:
|
||||
#####################################
|
||||
#S #
|
||||
#. #
|
||||
#. #
|
||||
#. #
|
||||
#. #
|
||||
#. #
|
||||
#. #
|
||||
#. #
|
||||
#..................................E#
|
||||
#####################################
|
||||
time: 0.8261000002676155 ms
|
||||
visited cells: 315
|
||||
path length: 43
|
||||
```
|
||||
```
|
||||
DFS
|
||||
Путь найден:
|
||||
#####################################
|
||||
#S..................................#
|
||||
# .#
|
||||
#...................................#
|
||||
#. #
|
||||
#...................................#
|
||||
# .#
|
||||
#...................................#
|
||||
#. #
|
||||
#..................................E#
|
||||
#####################################
|
||||
time: 0.6825999989814591 ms
|
||||
visited cells: 315
|
||||
path length: 179
|
||||
```
|
||||
Как видно по примеру DFS нашёл путь быстрее (0.68 против 0.82 мс), но длина найденного маршрута 179 клеток, в то время как путь, найденный BFS состоит из 43 клеток.
|
||||
#### A*:
|
||||
- По таблице видно, что A* проходит меньше всего клеток. Это происходит, так как идея алгоритма в том что он отдаёт приоритет клеткам, которые ближе к цели.
|
||||
- На практике медленнее DFS из-за операций с кучей (O(log n) на каждый шаг)
|
||||
|
||||
#### Dijkstra:
|
||||
- По сложности аналогичен BFS для лабиринтов без весов, но медленнее BFS из-за приоритетной очереди.
|
||||
- Имеет смысл на взвешенных графах
|
||||
|
||||
## Выводы
|
||||
Использование ООП и паттернов дало:
|
||||
- расширяемость - лёгкость добавления нового алгоритма поиска без изменения текущей структуры и существующих классов
|
||||
- гибкость - можно менять алгоритмы поиска, конструкторы лабиринтов и способы отображения так же без изменения уже существующих
|
||||
- Лёгкость тестирования - можно тестировать каждый элемент независимо
|
||||
Без этого было бы сложно внедрять новые реализации классов, способы отображения или создания лабиринта или изменять существующие алгоритмы.
|
||||
Но реализация интерфейсов и унификация классов увеличили объём кода и так же наложили ограничения на обрабатываемые данные.
|
||||
|
||||
По скорости лучшим по большинству тестов стал DFS. Второй по скорости BFS, так же он находит самый короткий путь, но при усложнении лабиринта(увеличении развилок и размера) начинает проигрывать A*.
|
||||
103
stepushovgs/labyrinth/mazes/benchmarks/maze100x100.txt
Normal file
103
stepushovgs/labyrinth/mazes/benchmarks/maze100x100.txt
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
#######################################################################################################
|
||||
# # # # # # # # # # # #
|
||||
### # ##### # # # ############# ######### ### ### # # # ### # # # # # # ####### ##### ##### # ### ### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # ##### # ##### ### ### ### # ##### # ####### ##### ### ##### ### ####### # # ####### ### ### ##### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ##### ### ### ##### # ####### ### ### # ##### ##### # ########### ### ### ##### ### # ### # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
### # ### # ### # ######### ##### ### # ### # ### ##### ### ### # ### # # # ### # # ##### # ### ##### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # ### ### # # ### # # ####### # # # ### # ### # # # ####### # # ##### ### ### ### # ##### ### # ###
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
##### # # # # ### ### # ##### # # ##### ### # ##### # ##### ##### ### # # ####### ##### # # # # # # ###
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # ##### ### # ### # ### # # ### ##### ####### ### ##### ### ### # # # # # # # ######### # # ### # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
### # ### ### ### # ############# ### # # ### ############### # ##### # ##### ### # # ########### ### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
### # ##### # ####### ##### ##### ### ### # ### ### ### ####### ##### # # ##### ##### # # # # ##### # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
### # # ### ##### # # # # ##### ##### ##### ##### # ##### # ### ##### ### ### ### ### ### ########### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ####### # ### # # ##### # # ### # ########### ##### # # ### # ### # # # # ##### # ### # ####### # ###
|
||||
# # # # # # # S # # # # # # # # # # # # # # #
|
||||
### # ####### # ##### ##### ### # ### ### ####### # # # # ### ### # ######### # ### ### ### # # ### # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ########### # ### # # # # # ### ########### # # # ####### ### # ##### ### ### ### # ### ####### # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # ##### # # ####### ### ##### # # ######### # ##### ### # ##### ########### # # # # # ### # # ### ###
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ### ### # ### # # # # # ### ##### ### ### ##### ##### ### # ### # ### ####### # # ### ####### # #####
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # ### ### ### ##### # # ##### ### # ### # # ### ### ##### ####### ####### # ##### ### # # ### ### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # ##### # # # # # # # ### # ### ##### ### ### ######### # # # ##### # # ### ##### ### # # ##### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
##### # # # # ####### ### ##### # ##### ####### # # ### ######### ### # # # ########### ####### ### ###
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # ### ### # ### # # # ##### ### # ### # # ####### ### # ##### # ##### ##### ### # # ####### ### ### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
### # ############### # # ### # ##### ### ### ### # # # ### ### # # ### # # ### ##### ### ### ####### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # #
|
||||
##### # ####### # ##### ### ### ##### # ####### ######### # ### # ####### # ######### # # ######### # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ### ### # ### # ### ##### # ##### # ### # ### # # # # ##### # # # ############# ####### ### # ### ###
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ### ##### ### # ### ##### ### # ### # # # # ##### # ### # # # # # # ### # # # ### ######### ##### # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # ### ##### ### ##### ##### ####### ### ########### # # # ### # # ### ####### # # # # ######### ### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
### ### ### ### ### # ##### # # ####### # # # # ####### ####### ##### ##### ####### # ##### ### ##### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ####### # ##### # # ### ##### ### # ####### ### ### # ##### # ### # ### ##### # ### # # # # ### #####
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # ### # # # ##### ##### # # ####### # # ### ####### ### # ##### ### # # # ####### # # ### ### # # ###
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ##### # ### # # ############### # ##### ############# # ##### # ### # ### # # ### # # # # ######### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ######### # ### # ####### # ####### # # # ### # ### ### # ##### ### # ##### ############### ### # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
### ### ### # ####### # ### # ### # ### # ### ##### ##### ##### ### ### # # # # # # ##### ##### ### # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ### # ### ####### ### ####### # ### ##### # # ####### ##### ### ### # ##### # ####### # # # ### # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ### ### ##### # # ##### # # ### # ##### # ### # # ### ### # ### ########### ### # # ### ### ##### # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # ### ### ### ##### ### # ####### ### ##### ### # ######### ##### ### ### ##### ####### ##### ### ###
|
||||
# # # # # # # # # # # # # # # # # # # # # # # #
|
||||
########### ##### ##### # ### ### ### # ####### # # ### ### ### # # # # # ### # ##### # # # ### # # ###
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ### ##### # ### # # # # # ### # # # ##### # ### ### # # ### ##### ####### ### # # ### ######### # ###
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
### ####### # ### ### ##### ##### # ### ### ### ### # ##### # ### # # # ##### # ### ### # ######### # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # ### # ##### ####### # ##### ##### ##### # # # # # ### # # ######### # ### # ####### # ### #####
|
||||
# # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ### ### ############# ### ### ##### ######### # ### ####### # ### # # ####### # ### ##### ### #######
|
||||
# # # # # # # # # # # # # # # # # # # # #
|
||||
# # ### # # # ### ##### # # ### ############### ### # # # ##### # # ##### ##### # ### ##### ##### # ###
|
||||
# # # # # # # # # # # # # # # E # # # # # # # # #
|
||||
# # ### ##### # ##### ### # # # ### # ### # ######### # # ##### ####### ####### ##### ####### # #######
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
### ####### ### # # # ##### ######### ### ##### ####### # # # # # # # # # # ### # ### # ### # ### # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ### ### ####### # # ### # ### ####### # ### # # ### ####### ####### ### ### # ########### # ### #####
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # ### ####### ######### ##### # # ### ### ### # ### # # # ##### ### # ##### ### # # # ### ###########
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
##### # # # # # # # # # ##### ##### ##### # ##### # ##### # # ### # # # # ######### ########### # ### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # ### ### ####### ### ### # ### ######### ##### ##### ####### # # ##### # # # ### # ######### ### # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ### ### ####### # ### # ### ######### # ### # # ### # # # # ##### ### # # ##### ### ######### # # ###
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ##### ### # ######### ### # ### ### # ### # ########### ### ### # ### # # ### ### ######### # ##### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # ### # # # ##### ### # ### ### # ##### ### # ### ##### ##### ####### ##### # ### ### ### # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # #
|
||||
### # ##### # # ##### ### # # ##### ##### # # ######### ### ### ##### ### ### # ### ##### # # ### ### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
### # ### # ### # ##### # # ####### # ### ### # ### # ### # # ### ### # # ##### # # ### ### # # # ### #
|
||||
# # # # # # # # # # # # # # # # # # # # # #
|
||||
#######################################################################################################
|
||||
6
stepushovgs/labyrinth/mazes/benchmarks/maze10x10.txt
Normal file
6
stepushovgs/labyrinth/mazes/benchmarks/maze10x10.txt
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
S # #####
|
||||
## # # E#
|
||||
# # ###
|
||||
### ## # #
|
||||
# #
|
||||
##########
|
||||
53
stepushovgs/labyrinth/mazes/benchmarks/maze50x50.txt
Normal file
53
stepushovgs/labyrinth/mazes/benchmarks/maze50x50.txt
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
#####################################################
|
||||
# S # # # # # # # # #
|
||||
####### ##### # ##### # # ### ### ### ### ##### # ###
|
||||
# # # # # # # # # # # #
|
||||
# ##### # ####### ##### ### ####### ### ### # # # # #
|
||||
# # # # # # # # # # # # # # # #
|
||||
# ### # ##### # # # # ##### # # # ##### # ### ### ###
|
||||
# # # # # # # # # # # # # # #
|
||||
# ### # # ### # ### # ### # # ######### ##### # ### #
|
||||
# # # # # # # # # # # # # # #
|
||||
### # ### ####### ### # ### ### ####### # ### ### # #
|
||||
# # # # # # # # # # # # # # #
|
||||
# ### # # # # # ##### ### # ### ### # ######### #####
|
||||
# # # # # # # # # # # # # #
|
||||
# ############# # # ### ##### ##### ### ##### ### # #
|
||||
# # # # # # # # # # # #
|
||||
### # # # ########### ##### # ### ### ######### ### #
|
||||
# # # # # # # # # # # # # #
|
||||
# ### # ####### # ##### # ### ### ####### # # # ### #
|
||||
# # # # # # # # # # # # # # # #
|
||||
# # # ### # # ####### # ### ### ### ##### ### #######
|
||||
# # # # # # # # # # # # # #
|
||||
### ### ##### # # ### ### ### # ### # ######### ### #
|
||||
# # # # # # # # # # # #
|
||||
# # # ### ##### # # # # ########### # ### # # # # ###
|
||||
# # # # # # # # # # # # # # #
|
||||
# # # ############# ##### ##### ##### ### # ##### # #
|
||||
# # # # # # # # # # # # # #
|
||||
# ##### ### ##### # # # ### # ### ####### ### ##### #
|
||||
# # # # # # # # # # # # # # # # # #
|
||||
### ### # ######### # ### # ### # # # # ### ##### # #
|
||||
# # # # # # # # # # #
|
||||
### # # ####### # ### ############# # # # ### ### # #
|
||||
# # # # # # # # # # # # # #
|
||||
### # ######### ####### # ### # # # ### ##### ##### #
|
||||
# # # # # E # # # # # #
|
||||
# ### ##### ### # ### ### # ####### # ##### # #######
|
||||
# # # # # # # # # # # # # # # # # #
|
||||
##### # # # ##### # ####### ### # ### ##### # # # ###
|
||||
# # # # # # # # # # # # #
|
||||
####### ##### # ### ### # ##### ##### ### ##### ### #
|
||||
# # # # # # # # # # # # # # #
|
||||
# # # # # # # # ##### ### # # # ### ### # # ### ### #
|
||||
# # # # # # # # # # # # # # # # # #
|
||||
# ############# ### ### # ### # # ### ### ### ##### #
|
||||
# # # # # # # # # # # # # #
|
||||
# # # # # # ### ### # ##### ### ### ### # ### ### # #
|
||||
# # # # # # # # # # # # #
|
||||
# ##### ##### ### ########### ####### ##### ### #####
|
||||
# # # # # # # # # # # # #
|
||||
# # # ##### # # ### # ### # # # # ### ### # ##### ###
|
||||
# # # # # # # # # #
|
||||
#####################################################
|
||||
50
stepushovgs/labyrinth/mazes/benchmarks/maze_empty.txt
Normal file
50
stepushovgs/labyrinth/mazes/benchmarks/maze_empty.txt
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
#################################################################################################################
|
||||
#S #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# E#
|
||||
#################################################################################################################
|
||||
53
stepushovgs/labyrinth/mazes/benchmarks/maze_no_path.txt
Normal file
53
stepushovgs/labyrinth/mazes/benchmarks/maze_no_path.txt
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
#####################################################
|
||||
# S # # # # # # # # #
|
||||
####### ##### # ##### # # ### ### ### ### ##### # ###
|
||||
# # # # # # # # # # # #
|
||||
# ##### # ####### ##### ### ####### ### ### # # # # #
|
||||
# # # # # # # # # # # # # # # #
|
||||
# ### # ##### # # # # ##### # # # ##### # ### ### ###
|
||||
# # # # # # # # # # # # # # #
|
||||
# ### # # ### # ### # ### # # ######### ##### # ### #
|
||||
# # # # # # # # # # # # # # #
|
||||
### # ### ####### ### # ### ### ####### # ### ### # #
|
||||
# # # # # # # # # # # # # # #
|
||||
# ### # # # # # ##### ### # ### ### # ######### #####
|
||||
# # # # # # # # # # # # # #
|
||||
# ############# # # ### ##### ##### ### ##### ### # #
|
||||
# # # # # # # # # # # #
|
||||
### # # # ########### ##### # ### ### ######### ### #
|
||||
# # # # # # # # # # # # # #
|
||||
# ### # ####### # ##### # ### ### ####### # # # ### #
|
||||
# # # # # # # # # # # # # # # #
|
||||
# # # ### # # ####### # ### ### ### ##### ### #######
|
||||
# # # # # # # # # # # # # #
|
||||
### ### ##### # # ### ### ### # ### # ######### ### #
|
||||
# # # # # # # # # # # #
|
||||
# # # ### ##### # # # # ########### # ### # # # # ###
|
||||
# # # # # # # # # # # # # # #
|
||||
# # # ############# ##### ##### ##### ### # ##### # #
|
||||
# # # # # # # # # # # # # #
|
||||
# ##### ### ##### # # # ### # ### ####### ### ##### #
|
||||
# # # # # # # # # # # # # # # # # #
|
||||
### ### # ######### # ### # ### # # # # ### ##### # #
|
||||
# # # # # # # # # # #
|
||||
### # # ####### # ### ############# # # # ### ### # #
|
||||
# # # # # # # # # # # # # #
|
||||
### # ######### ####### # ######### ### ##### ##### #
|
||||
# # # # # E # # # # # #
|
||||
# ### ##### ### # ### ### # ####### # ##### # #######
|
||||
# # # # # # # # # # # # # # # # # #
|
||||
##### # # # ##### # ####### ### # ### ##### # # # ###
|
||||
# # # # # # # # # # # # #
|
||||
####### ##### # ### ### # ##### ##### ### ##### ### #
|
||||
# # # # # # # # # # # # # # #
|
||||
# # # # # # # # ##### ### # # # ### ### # # ### ### #
|
||||
# # # # # # # # # # # # # # # # # #
|
||||
# ############# ### ### # ### # # ### ### ### ##### #
|
||||
# # # # # # # # # # # # # #
|
||||
# # # # # # ### ### # ##### ### ### ### # ### ### # #
|
||||
# # # # # # # # # # # # #
|
||||
# ##### ##### ### ########### ####### ##### ### #####
|
||||
# # # # # # # # # # # # #
|
||||
# # # ##### # # ### # ### # # # # ### ### # #########
|
||||
# # # # # # # # # #
|
||||
#####################################################
|
||||
6
stepushovgs/labyrinth/mazes/tests/test_lab.txt
Normal file
6
stepushovgs/labyrinth/mazes/tests/test_lab.txt
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
S # #####
|
||||
## # # E#
|
||||
# # ###
|
||||
### ## # #
|
||||
# #
|
||||
##########
|
||||
103
stepushovgs/labyrinth/mazes/tests/test_lab100.txt
Normal file
103
stepushovgs/labyrinth/mazes/tests/test_lab100.txt
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
#######################################################################################################
|
||||
# # # # # # # # # # # #
|
||||
### # ##### # # # ############# ######### ### ### # # # ### # # # # # # ####### ##### ##### # ### ### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # ##### # ##### ### ### ### # ##### # ####### ##### ### ##### ### ####### # # ####### ### ### ##### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ##### ### ### ##### # ####### ### ### # ##### ##### # ########### ### ### ##### ### # ### # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
### # ### # ### # ######### ##### ### # ### # ### ##### ### ### # ### # # # ### # # ##### # ### ##### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # ### ### # # ### # # ####### # # # ### # ### # # # ####### # # ##### ### ### ### # ##### ### # ###
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
##### # # # # ### ### # ##### # # ##### ### # ##### # ##### ##### ### # # ####### ##### # # # # # # ###
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # ##### ### # ### # ### # # ### ##### ####### ### ##### ### ### # # # # # # # ######### # # ### # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
### # ### ### ### # ############# ### # # ### ############### # ##### # ##### ### # # ########### ### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
### # ##### # ####### ##### ##### ### ### # ### ### ### ####### ##### # # ##### ##### # # # # ##### # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
### # # ### ##### # # # # ##### ##### ##### ##### # ##### # ### ##### ### ### ### ### ### ########### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ####### # ### # # ##### # # ### # ########### ##### # # ### # ### # # # # ##### # ### # ####### # ###
|
||||
# # # # # # # S # # # # # # # # # # # # # # #
|
||||
### # ####### # ##### ##### ### # ### ### ####### # # # # ### ### # ######### # ### ### ### # # ### # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ########### # ### # # # # # ### ########### # # # ####### ### # ##### ### ### ### # ### ####### # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # ##### # # ####### ### ##### # # ######### # ##### ### # ##### ########### # # # # # ### # # ### ###
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ### ### # ### # # # # # ### ##### ### ### ##### ##### ### # ### # ### ####### # # ### ####### # #####
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # ### ### ### ##### # # ##### ### # ### # # ### ### ##### ####### ####### # ##### ### # # ### ### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # ##### # # # # # # # ### # ### ##### ### ### ######### # # # ##### # # ### ##### ### # # ##### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
##### # # # # ####### ### ##### # ##### ####### # # ### ######### ### # # # ########### ####### ### ###
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # ### ### # ### # # # ##### ### # ### # # ####### ### # ##### # ##### ##### ### # # ####### ### ### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
### # ############### # # ### # ##### ### ### ### # # # ### ### # # ### # # ### ##### ### ### ####### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # #
|
||||
##### # ####### # ##### ### ### ##### # ####### ######### # ### # ####### # ######### # # ######### # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ### ### # ### # ### ##### # ##### # ### # ### # # # # ##### # # # ############# ####### ### # ### ###
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ### ##### ### # ### ##### ### # ### # # # # ##### # ### # # # # # # ### # # # ### ######### ##### # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # ### ##### ### ##### ##### ####### ### ########### # # # ### # # ### ####### # # # # ######### ### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
### ### ### ### ### # ##### # # ####### # # # # ####### ####### ##### ##### ####### # ##### ### ##### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ####### # ##### # # ### ##### ### # ####### ### ### # ##### # ### # ### ##### # ### # # # # ### #####
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # ### # # # ##### ##### # # ####### # # ### ####### ### # ##### ### # # # ####### # # ### ### # # ###
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ##### # ### # # ############### # ##### ############# # ##### # ### # ### # # ### # # # # ######### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ######### # ### # ####### # ####### # # # ### # ### ### # ##### ### # ##### ############### ### # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
### ### ### # ####### # ### # ### # ### # ### ##### ##### ##### ### ### # # # # # # ##### ##### ### # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ### # ### ####### ### ####### # ### ##### # # ####### ##### ### ### # ##### # ####### # # # ### # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ### ### ##### # # ##### # # ### # ##### # ### # # ### ### # ### ########### ### # # ### ### ##### # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # ### ### ### ##### ### # ####### ### ##### ### # ######### ##### ### ### ##### ####### ##### ### ###
|
||||
# # # # # # # # # # # # # # # # # # # # # # # #
|
||||
########### ##### ##### # ### ### ### # ####### # # ### ### ### # # # # # ### # ##### # # # ### # # ###
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ### ##### # ### # # # # # ### # # # ##### # ### ### # # ### ##### ####### ### # # ### ######### # ###
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
### ####### # ### ### ##### ##### # ### ### ### ### # ##### # ### # # # ##### # ### ### # ######### # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # ### # ##### ####### # ##### ##### ##### # # # # # ### # # ######### # ### # ####### # ### #####
|
||||
# # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ### ### ############# ### ### ##### ######### # ### ####### # ### # # ####### # ### ##### ### #######
|
||||
# # # # # # # # # # # # # # # # # # # # #
|
||||
# # ### # # # ### ##### # # ### ############### ### # # # ##### # # ##### ##### # ### ##### ##### # ###
|
||||
# # # # # # # # # # # # # # # E # # # # # # # # #
|
||||
# # ### ##### # ##### ### # # # ### # ### # ######### # # ##### ####### ####### ##### ####### # #######
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
### ####### ### # # # ##### ######### ### ##### ####### # # # # # # # # # # ### # ### # ### # ### # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ### ### ####### # # ### # ### ####### # ### # # ### ####### ####### ### ### # ########### # ### #####
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # ### ####### ######### ##### # # ### ### ### # ### # # # ##### ### # ##### ### # # # ### ###########
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
##### # # # # # # # # # ##### ##### ##### # ##### # ##### # # ### # # # # ######### ########### # ### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # ### ### ####### ### ### # ### ######### ##### ##### ####### # # ##### # # # ### # ######### ### # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ### ### ####### # ### # ### ######### # ### # # ### # # # # ##### ### # # ##### ### ######### # # ###
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ##### ### # ######### ### # ### ### # ### # ########### ### ### # ### # # ### ### ######### # ##### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # ### # # # ##### ### # ### ### # ##### ### # ### ##### ##### ####### ##### # ### ### ### # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # #
|
||||
### # ##### # # ##### ### # # ##### ##### # # ######### ### ### ##### ### ### # ### ##### # # ### ### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
### # ### # ### # ##### # # ####### # ### ### # ### # ### # # ### ### # # ##### # # ### ### # # # ### #
|
||||
# # # # # # # # # # # # # # # # # # # # # #
|
||||
#######################################################################################################
|
||||
11
stepushovgs/labyrinth/mazes/tests/test_lab2.txt
Normal file
11
stepushovgs/labyrinth/mazes/tests/test_lab2.txt
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
#####################################
|
||||
#S #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# E#
|
||||
#####################################
|
||||
23
stepushovgs/labyrinth/mazes/tests/test_lab20x20.txt
Normal file
23
stepushovgs/labyrinth/mazes/tests/test_lab20x20.txt
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
#######################
|
||||
# # # # # # #
|
||||
### ### ##### # # # ###
|
||||
# # # # # #
|
||||
# # # ##### ### ##### #
|
||||
# # # # # #
|
||||
##### ### # ######### #
|
||||
# #
|
||||
##### # # ### ####### #
|
||||
# # # # # # #
|
||||
########### # ### ### #
|
||||
# # # # # # # #
|
||||
# ### # # ### # ### ###
|
||||
# # # # # # #
|
||||
# ### ####### # # ### #
|
||||
# # # # #
|
||||
### ####### ### #######
|
||||
# # # #
|
||||
########### # ##### # #
|
||||
# # # # #
|
||||
##### ####### ##### # #
|
||||
# # # #
|
||||
#######################
|
||||
9
stepushovgs/labyrinth/mazes/tests/test_lab3.txt
Normal file
9
stepushovgs/labyrinth/mazes/tests/test_lab3.txt
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
####################
|
||||
#S #
|
||||
# ########## #
|
||||
# #### #
|
||||
# ######## #
|
||||
# #
|
||||
# ####### #### #
|
||||
# E #
|
||||
####################
|
||||
9
stepushovgs/labyrinth/mazes/tests/test_labNoPath.txt
Normal file
9
stepushovgs/labyrinth/mazes/tests/test_labNoPath.txt
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
####################
|
||||
#S #
|
||||
# ########## #
|
||||
# #### #
|
||||
# ######## #
|
||||
# #
|
||||
# ####### #######
|
||||
# #E #
|
||||
####################
|
||||
4
stepushovgs/labyrinth/source/__init__.py
Normal file
4
stepushovgs/labyrinth/source/__init__.py
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
from .builder import *
|
||||
from .classes import *
|
||||
from .observer import *
|
||||
from .strategy import *
|
||||
4
stepushovgs/labyrinth/source/builder/__init__.py
Normal file
4
stepushovgs/labyrinth/source/builder/__init__.py
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
from .builder import MazeBuilder
|
||||
from .text_file_maze_builder import TextFileMazeBuilder
|
||||
|
||||
__all__ = ['MazeBuilder', 'TextFileMazeBuilder']
|
||||
9
stepushovgs/labyrinth/source/builder/builder.py
Normal file
9
stepushovgs/labyrinth/source/builder/builder.py
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
from abc import ABC, abstractmethod
|
||||
|
||||
|
||||
from source.classes.maze import Maze
|
||||
|
||||
class MazeBuilder(ABC):
|
||||
@abstractmethod
|
||||
def buildFromFile(self, filename: str) -> Maze:
|
||||
pass
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
from source.classes.maze import Maze, Cell
|
||||
from .builder import MazeBuilder
|
||||
|
||||
|
||||
class TextFileMazeBuilder(MazeBuilder):
|
||||
def buildFromFile(self, filename: str) -> Maze:
|
||||
"""Получает лабиринт из текстового файла"""
|
||||
with open(filename) as f:
|
||||
data = f.read().splitlines()
|
||||
x, y = 0, 0
|
||||
width = len(data[0])
|
||||
height = len(data)
|
||||
|
||||
cells = [[None] * width for _ in range(height)]
|
||||
|
||||
start, c_exit = None, None
|
||||
|
||||
for line in data:
|
||||
x = 0
|
||||
for c in line.strip():
|
||||
if c == 'S':
|
||||
cells[y][x] = Cell(x, y, isStart=True)
|
||||
start = cells[y][x]
|
||||
x += 1
|
||||
elif c == 'E':
|
||||
cells[y][x] = Cell(x, y, isExit=True)
|
||||
c_exit = cells[y][x]
|
||||
x += 1
|
||||
elif c == '#':
|
||||
cells[y][x] = Cell(x, y, isWall=True)
|
||||
x += 1
|
||||
elif c == ' ':
|
||||
cells[y][x] = Cell(x, y)
|
||||
x += 1
|
||||
else:
|
||||
print(f'Обнаружен неизвестный символ({c}) в файле лабиринта\nfilename: {filename}\nОн заменён на стену')
|
||||
cells[y][x] = Cell(x, y, isWall=True)
|
||||
x += 1
|
||||
|
||||
y += 1
|
||||
|
||||
if start == None:
|
||||
raise ValueError(f'В файле лабиринта не обнаружен вход!\nfilename: {filename}')
|
||||
|
||||
if c_exit == None:
|
||||
raise ValueError(f'В файле лабиринта не обнаружен выход!\nfilename: {filename}')
|
||||
|
||||
return Maze(
|
||||
cells=cells,
|
||||
width=width,
|
||||
height=height,
|
||||
start=start,
|
||||
exit_cell=c_exit
|
||||
)
|
||||
4
stepushovgs/labyrinth/source/classes/__init__.py
Normal file
4
stepushovgs/labyrinth/source/classes/__init__.py
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
from .cell import Cell
|
||||
from .maze import Maze
|
||||
|
||||
__all__ = ['Cell', 'Maze']
|
||||
86
stepushovgs/labyrinth/source/classes/cell.py
Normal file
86
stepushovgs/labyrinth/source/classes/cell.py
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
class Cell:
|
||||
"""
|
||||
Клетка лабиринта
|
||||
|
||||
`x, y` - координаты клетки в лабиринте
|
||||
|
||||
`isWall` - Является ли клетка стеной
|
||||
|
||||
`isStart` - Является ли клетка стартом
|
||||
|
||||
`isExit` - Является ли клетка выходом лабиринта
|
||||
|
||||
`value` - Вес клетки
|
||||
"""
|
||||
|
||||
def __init__(self, x: int, y: int, isWall=False, isStart=False, isExit=False, value=1):
|
||||
"""
|
||||
Создание клетки лабиринта
|
||||
|
||||
`x` - столбец клетки в лабиринте
|
||||
`y` - строка клетки в лабиринте
|
||||
|
||||
`isWall` - Является ли клетка стеной
|
||||
|
||||
`isStart` - Является ли клетка стартом
|
||||
|
||||
`isExit` - Является ли клетка выходом лабиринта
|
||||
|
||||
`value` - Вес клетки
|
||||
"""
|
||||
self.__x = x
|
||||
self.__y = y
|
||||
self.isWall = isWall
|
||||
self.isStart = isStart
|
||||
self.isExit = isExit
|
||||
self.__value = value
|
||||
pass
|
||||
|
||||
@property
|
||||
def isPassable(self) -> bool:
|
||||
"""возвращает `True` для прохода, если клетка не стена"""
|
||||
return not self.isWall
|
||||
|
||||
@property
|
||||
def x(self) -> int:
|
||||
"""Возвращает координату клетки по оси X"""
|
||||
return self.__x
|
||||
|
||||
@property
|
||||
def y(self) -> int:
|
||||
"""Возвращает координату клетки по оси Y"""
|
||||
return self.__y
|
||||
|
||||
def getXY(self) -> tuple[int, int]:
|
||||
"""Возвращает кортеж координат в формате `(x, y)`"""
|
||||
return self.__x, self.__y
|
||||
|
||||
@property
|
||||
def value(self) -> int:
|
||||
"""Возвращает вес клетки"""
|
||||
return self.__value
|
||||
|
||||
def toStr(self) -> str:
|
||||
"""
|
||||
Возвращает строчкое представление клетки
|
||||
|
||||
`#` - Стена
|
||||
|
||||
`S` - Начало лабиринта
|
||||
|
||||
`E` - Конец лабиринта
|
||||
|
||||
` `(пробел) - свободный проход
|
||||
|
||||
`<int>` - Вес клетки
|
||||
"""
|
||||
if self.isWall:
|
||||
return '#'
|
||||
elif self.isStart:
|
||||
return 'S'
|
||||
elif self.isExit:
|
||||
return 'E'
|
||||
else:
|
||||
return ' '
|
||||
|
||||
|
||||
46
stepushovgs/labyrinth/source/classes/maze.py
Normal file
46
stepushovgs/labyrinth/source/classes/maze.py
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
from .cell import Cell
|
||||
|
||||
class Maze:
|
||||
"""Лабиринт"""
|
||||
def __init__(self, cells, width: int, height: int, start: Cell, exit_cell: Cell):
|
||||
self.cells = cells
|
||||
self.width = width
|
||||
self.height = height
|
||||
self.start = start
|
||||
self.exit = exit_cell
|
||||
pass
|
||||
|
||||
def getCell(self, x: int, y: int) -> Cell:
|
||||
return self.cells[y][x] # строка стобец
|
||||
|
||||
def getNeighbors(self, cell) -> list[Cell]:
|
||||
"""Возвращает список соседних проходимых клеток (вверх, вниз, влево, вправо, если в пределах границ и не стена)."""
|
||||
neighbors = []
|
||||
|
||||
c_x, c_y = cell.getXY()
|
||||
|
||||
if c_y - 1 >= 0 and not self.cells[c_y - 1][c_x].isWall:
|
||||
neighbors.append(self.cells[c_y - 1][c_x])
|
||||
|
||||
if c_y + 1 < self.height and not self.cells[c_y + 1][c_x].isWall:
|
||||
neighbors.append(self.cells[c_y + 1][c_x])
|
||||
|
||||
if c_x - 1 >= 0 and not self.cells[c_y][c_x - 1].isWall:
|
||||
neighbors.append(self.cells[c_y][c_x - 1])
|
||||
|
||||
if c_x + 1 < self.width and not self.cells[c_y][c_x + 1].isWall:
|
||||
neighbors.append(self.cells[c_y][c_x + 1])
|
||||
|
||||
return neighbors
|
||||
|
||||
def printer(self):
|
||||
"""Выводит в консоль лабиринт (отладочное)"""
|
||||
for line in self.cells:
|
||||
for c in line:
|
||||
print(c.toStr(), end='')
|
||||
|
||||
print()
|
||||
|
||||
def info(self):
|
||||
"""Основная информация о лабиринте"""
|
||||
print(f'height: {self.height}\nwidth: {self.width}\nstart: {self.start.getXY()}\nexit: {self.exit.getXY()}\ncount cells: {self.height * self.width}')
|
||||
0
stepushovgs/labyrinth/source/command/command.py
Normal file
0
stepushovgs/labyrinth/source/command/command.py
Normal file
4
stepushovgs/labyrinth/source/observer/__init__.py
Normal file
4
stepushovgs/labyrinth/source/observer/__init__.py
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
from .console_view import ConsoleView
|
||||
from .observer import Observer, Event
|
||||
|
||||
__all__ = ['ConsoleView', 'Observer', 'Event']
|
||||
79
stepushovgs/labyrinth/source/observer/console_view.py
Normal file
79
stepushovgs/labyrinth/source/observer/console_view.py
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
import os
|
||||
|
||||
|
||||
from .observer import Observer, Event
|
||||
from source.classes import Cell, Maze
|
||||
|
||||
class ConsoleView(Observer):
|
||||
|
||||
def update(self, event: Event):
|
||||
"""Вывод состояния лабиринта на экран
|
||||
|
||||
`maze_loaded` - Лабиринт загружен
|
||||
|
||||
`path_found` - Отображает лабиринт и маршрут в нём (символом `*`)
|
||||
|
||||
`move` - Выводит лабиринт и позицию игрока в нём (символом `P`)
|
||||
|
||||
"""
|
||||
if event.event == "path_found":
|
||||
print("Путь найден:")
|
||||
self.render(
|
||||
event.maze,
|
||||
event.player_position,
|
||||
event.path
|
||||
)
|
||||
elif event.event == "move":
|
||||
self.render(
|
||||
event.maze,
|
||||
event.player_position,
|
||||
event.path
|
||||
)
|
||||
elif event.event == "maze_loaded":
|
||||
print("Загружен лабиринт:")
|
||||
self.render(
|
||||
event.maze,
|
||||
event.player_position,
|
||||
event.path
|
||||
)
|
||||
else:
|
||||
pass
|
||||
|
||||
|
||||
def render(self, maze:Maze, player_position: tuple[int, int], path: list):
|
||||
os.system('cls' if os.name == 'nt' else 'clear')
|
||||
|
||||
# Если path содержит объекты Cell, преобразуем в координаты
|
||||
if path and isinstance(path[0], Cell):
|
||||
path_xy = [cell.getXY() for cell in path]
|
||||
else:
|
||||
path_xy = path
|
||||
|
||||
# path_xy = [cell.getXY() for cell in path]
|
||||
|
||||
for line in maze.cells:
|
||||
for c in line:
|
||||
if c.getXY() == player_position:
|
||||
print('P', end='')
|
||||
elif c.toStr() in ["S", "E"]:
|
||||
print(c.toStr(), end='')
|
||||
elif c.getXY() in path_xy:
|
||||
print('.', end='')
|
||||
else:
|
||||
print(c.toStr(), end='')
|
||||
|
||||
print()
|
||||
|
||||
# def render_xy(self, maze: Maze, player_position: tuple[int, int], path: list[tuple[int, int]]):
|
||||
# os.system('cls' if os.name == 'nt' else 'clear')
|
||||
# # path_xy = [cell.getXY() for cell in path]
|
||||
|
||||
# for line in maze.cells:
|
||||
# for c in line:
|
||||
# if c.getXY() == player_position:
|
||||
# print('P', end='')
|
||||
# elif c.getXY() in path:
|
||||
# print('*', end='')
|
||||
# else:
|
||||
# print(c.toStr(), end='')
|
||||
# print()
|
||||
21
stepushovgs/labyrinth/source/observer/observer.py
Normal file
21
stepushovgs/labyrinth/source/observer/observer.py
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
from abc import ABC, abstractmethod
|
||||
# import os
|
||||
|
||||
from source.classes import Maze
|
||||
|
||||
|
||||
class Event:
|
||||
def __init__(self, event: str, maze: Maze, player_position: tuple[int, int], path):
|
||||
self.event = event
|
||||
self.maze = maze
|
||||
self.player_position = player_position
|
||||
self.path = path
|
||||
|
||||
|
||||
class Observer(ABC):
|
||||
|
||||
@abstractmethod
|
||||
def update(self, event: Event):
|
||||
pass
|
||||
|
||||
|
||||
49
stepushovgs/labyrinth/source/strategy/BFS.py
Normal file
49
stepushovgs/labyrinth/source/strategy/BFS.py
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
from collections import deque
|
||||
|
||||
|
||||
from source.strategy import PathFindingStrategy, reconstruct_path
|
||||
from source.classes import Maze, Cell
|
||||
|
||||
class BFS(PathFindingStrategy):
|
||||
@property
|
||||
def name(self):
|
||||
"""Возвращает название метода"""
|
||||
return "BFS"
|
||||
|
||||
def findPath(self, maze: Maze) -> tuple[list[Cell], int]:
|
||||
start_cell = maze.start
|
||||
exit_cell = maze.exit
|
||||
|
||||
# print(f"Старт: {start_cell.getXY()}")
|
||||
# print(f"Выход: {exit_cell.getXY()}")
|
||||
# print(f"Соседи старта: {[n.getXY() for n in maze.getNeighbors(start_cell)]}")
|
||||
|
||||
queue = deque([start_cell])
|
||||
|
||||
parents = {start_cell.getXY(): Cell(-1, -1)}
|
||||
visited = {start_cell.getXY()}
|
||||
count_visited = 1
|
||||
|
||||
while queue:
|
||||
current = queue.popleft()
|
||||
|
||||
if current.getXY() == exit_cell.getXY():
|
||||
return reconstruct_path(
|
||||
came_from=parents,
|
||||
start=start_cell,
|
||||
end=current
|
||||
), count_visited
|
||||
|
||||
# neigbours = maze.getNeighbors(current)
|
||||
# print(f"для клекти {current.getXY()} соседи: {[neigbour.getXY() for neigbour in neigbours]}")
|
||||
|
||||
for neighbor in maze.getNeighbors(current):
|
||||
neig_xy = neighbor.getXY()
|
||||
|
||||
if neig_xy not in visited:
|
||||
visited.add(neig_xy)
|
||||
parents[neig_xy] = current
|
||||
count_visited += 1
|
||||
queue.append(neighbor)
|
||||
|
||||
return [], count_visited
|
||||
47
stepushovgs/labyrinth/source/strategy/DFS.py
Normal file
47
stepushovgs/labyrinth/source/strategy/DFS.py
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
from source.strategy import PathFindingStrategy, reconstruct_path
|
||||
from source.classes import Maze, Cell
|
||||
|
||||
class DFS(PathFindingStrategy):
|
||||
@property
|
||||
def name(self) -> str:
|
||||
"""Возвращает название метода"""
|
||||
return "DFS"
|
||||
|
||||
def findPath(self, maze: Maze) -> tuple[list[Cell], int]:
|
||||
start_cell = maze.start
|
||||
exit_cell = maze.exit
|
||||
|
||||
# print(f"Старт: {start_cell.getXY()}")
|
||||
# print(f"Выход: {exit_cell.getXY()}")
|
||||
# print(f"Соседи старта: {[n.getXY() for n in maze.getNeighbors(start_cell)]}")
|
||||
|
||||
stack = [start_cell]
|
||||
|
||||
parents = {start_cell.getXY(): Cell(-1, -1)}
|
||||
visited = {start_cell.getXY()}
|
||||
count_visited = 1
|
||||
|
||||
while stack:
|
||||
current = stack.pop()
|
||||
|
||||
if current.getXY() == exit_cell.getXY():
|
||||
return reconstruct_path(
|
||||
came_from=parents,
|
||||
start=start_cell,
|
||||
end=current
|
||||
), count_visited
|
||||
|
||||
# neigbours = maze.getNeighbors(current)
|
||||
# print(f"для клекти {current.getXY()} соседи: {[neigbour.getXY() for neigbour in neigbours]}")
|
||||
|
||||
for neighbor in maze.getNeighbors(current):
|
||||
neig_xy = neighbor.getXY()
|
||||
|
||||
if neig_xy not in visited:
|
||||
visited.add(neig_xy)
|
||||
parents[neig_xy] = current
|
||||
count_visited += 1
|
||||
# new_path = current_path + [neigbour]
|
||||
stack.append(neighbor)
|
||||
|
||||
return [], count_visited
|
||||
56
stepushovgs/labyrinth/source/strategy/Dijkstra.py
Normal file
56
stepushovgs/labyrinth/source/strategy/Dijkstra.py
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
from heapq import *
|
||||
|
||||
|
||||
from source.strategy import PathFindingStrategy, reconstruct_path
|
||||
from source.classes import Maze, Cell
|
||||
|
||||
|
||||
class Dijkstra(PathFindingStrategy):
|
||||
@property
|
||||
def name(self) -> str:
|
||||
"""Возвращает название метода"""
|
||||
return "Dijkstra"
|
||||
|
||||
|
||||
def findPath(self, maze: Maze):
|
||||
start_cell = maze.start
|
||||
exit_cell = maze.exit
|
||||
|
||||
queue = []
|
||||
counter = 0 # счётчик для уникальности, чтобы не сравнивать клетки
|
||||
|
||||
heappush(queue, (0, counter, start_cell))
|
||||
counter += 1
|
||||
|
||||
cost_visited = {start_cell.getXY(): 0}
|
||||
came_from = {start_cell.getXY(): None}
|
||||
visited_count = 1
|
||||
|
||||
while queue:
|
||||
current_cost, _, current_cell = heappop(queue)
|
||||
|
||||
if current_cell.getXY() == exit_cell.getXY():
|
||||
return reconstruct_path(
|
||||
came_from=came_from,
|
||||
start=start_cell,
|
||||
end=current_cell
|
||||
), visited_count
|
||||
|
||||
next_cells = maze.getNeighbors(current_cell)
|
||||
|
||||
for next_cell in next_cells:
|
||||
neighbor_cost = next_cell.value
|
||||
neighbor_cell_xy = next_cell.getXY()
|
||||
|
||||
new_cost = current_cost + neighbor_cost
|
||||
|
||||
if neighbor_cell_xy not in cost_visited or new_cost < cost_visited[neighbor_cell_xy]:
|
||||
heappush(queue, (new_cost, counter, next_cell))
|
||||
counter += 1
|
||||
|
||||
cost_visited[neighbor_cell_xy] = new_cost
|
||||
came_from[neighbor_cell_xy] = current_cell
|
||||
visited_count += 1
|
||||
|
||||
return [], visited_count
|
||||
|
||||
12
stepushovgs/labyrinth/source/strategy/__init__.py
Normal file
12
stepushovgs/labyrinth/source/strategy/__init__.py
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
from .strategy import PathFindingStrategy, reconstruct_path
|
||||
from .maze_solver import MazeSolver
|
||||
|
||||
|
||||
from .bfs import BFS
|
||||
from .dfs import DFS
|
||||
from .astar import AStar
|
||||
from .dijkstra import Dijkstra
|
||||
# from .maze_solver import MazeSolver
|
||||
# from .strategy import PathFindingStrategy, reconstruct_path
|
||||
|
||||
__all__ = ['BFS', 'DFS', 'AStar', 'Dijkstra', 'MazeSolver', 'PathFindingStrategy', 'reconstruct_path']
|
||||
64
stepushovgs/labyrinth/source/strategy/astar.py
Normal file
64
stepushovgs/labyrinth/source/strategy/astar.py
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
from heapq import *
|
||||
|
||||
|
||||
from source.strategy import PathFindingStrategy, reconstruct_path
|
||||
from source.classes import Maze, Cell
|
||||
|
||||
|
||||
class AStar(PathFindingStrategy):
|
||||
@property
|
||||
def name(self) -> str:
|
||||
return "A*"
|
||||
|
||||
def heuristic(self, a: Cell, b: Cell) -> int:
|
||||
x1, y1 = a.getXY()
|
||||
x2, y2 = b.getXY()
|
||||
|
||||
return abs(x1 - x2) + abs(y1 - y2)
|
||||
|
||||
def findPath(self, maze: Maze) -> tuple[list[Cell], int]:
|
||||
start_cell = maze.start
|
||||
exit_cell = maze.exit
|
||||
|
||||
queue = []
|
||||
counter = 0 # счётчик для уникальности, чтобы не сравнивать клетки
|
||||
|
||||
start_h = self.heuristic(start_cell, exit_cell)
|
||||
|
||||
heappush(queue, (start_h, counter, start_cell))
|
||||
counter += 1
|
||||
|
||||
cost_visited = {start_cell.getXY(): 0}
|
||||
came_from = {start_cell.getXY(): None}
|
||||
visited_count = 1
|
||||
|
||||
while queue:
|
||||
current_cost, _, current_cell = heappop(queue)
|
||||
current_g = cost_visited[current_cell.getXY()]
|
||||
|
||||
if current_cell.getXY() == exit_cell.getXY():
|
||||
return reconstruct_path(
|
||||
came_from=came_from,
|
||||
start=start_cell,
|
||||
end=current_cell
|
||||
), visited_count
|
||||
|
||||
next_cells = maze.getNeighbors(current_cell)
|
||||
|
||||
for next_cell in next_cells:
|
||||
neighbor_cost = next_cell.value
|
||||
neighbor_cell_xy = next_cell.getXY()
|
||||
|
||||
new_cost = current_g + neighbor_cost
|
||||
|
||||
if neighbor_cell_xy not in cost_visited or new_cost < cost_visited[neighbor_cell_xy]:
|
||||
priority = new_cost + self.heuristic(next_cell, exit_cell)
|
||||
|
||||
heappush(queue, (priority, counter, next_cell))
|
||||
counter += 1
|
||||
|
||||
cost_visited[neighbor_cell_xy] = new_cost
|
||||
came_from[neighbor_cell_xy] = current_cell
|
||||
visited_count += 1
|
||||
|
||||
return [], visited_count
|
||||
55
stepushovgs/labyrinth/source/strategy/maze_solver.py
Normal file
55
stepushovgs/labyrinth/source/strategy/maze_solver.py
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
import time
|
||||
|
||||
|
||||
from .strategy import PathFindingStrategy
|
||||
from source.observer import Observer, Event
|
||||
from source.classes import Cell, Maze
|
||||
|
||||
|
||||
class MazeSolver:
|
||||
def __init__(self, maze: Maze, strategy: PathFindingStrategy, observer: Observer):
|
||||
self.maze = maze
|
||||
self.strategy = strategy
|
||||
self.observer = observer
|
||||
|
||||
def strategyName(self) -> str:
|
||||
return self.strategy.name
|
||||
|
||||
def setStrategy(self, strategy: PathFindingStrategy):
|
||||
self.strategy = strategy
|
||||
|
||||
def solve(self):
|
||||
start_time = time.perf_counter()
|
||||
path, visited_cells = self.strategy.findPath(self.maze)
|
||||
finish_time = time.perf_counter()
|
||||
|
||||
self.observer.update(Event(
|
||||
event="path_found",
|
||||
maze=self.maze,
|
||||
player_position=self.maze.exit,
|
||||
path=path
|
||||
))
|
||||
|
||||
return SearchStats(
|
||||
timeMs=(finish_time - start_time) * 1000,
|
||||
visitedCells=visited_cells,
|
||||
pathLength=len(path),
|
||||
path=path
|
||||
)
|
||||
|
||||
|
||||
|
||||
class SearchStats:
|
||||
"""Общая информация о тесте алгоритма"""
|
||||
def __init__(self, timeMs: float, visitedCells: int, pathLength: int, path: list[Cell]):
|
||||
self.timeMs = timeMs
|
||||
self.visitedCells = visitedCells
|
||||
self.pathLength = pathLength
|
||||
self.path = path
|
||||
|
||||
def show(self):
|
||||
"""Вывод информации о тесте в консоль"""
|
||||
print(f'time: {self.timeMs} ms\nvisited cells: {self.visitedCells}\npath length: {self.pathLength}')
|
||||
|
||||
# def toStr(self) -> str:
|
||||
# return f'{self.timeMs} {self.visitedCells} {self.pathLength}'
|
||||
39
stepushovgs/labyrinth/source/strategy/strategy.py
Normal file
39
stepushovgs/labyrinth/source/strategy/strategy.py
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
from abc import ABC, abstractmethod
|
||||
|
||||
|
||||
from source.classes import Cell, Maze
|
||||
|
||||
|
||||
class PathFindingStrategy(ABC):
|
||||
"""Интерфейс для семейства алгоритмов поиска пути от старта до выхода."""
|
||||
|
||||
@abstractmethod
|
||||
def findPath(self, maze: Maze) -> tuple[list[tuple[int, int]], int]:
|
||||
"""Возвращающим список координат клеток пути (от старта до выхода включительно) или пустой список, если пути нет и количество посещённых клеток."""
|
||||
pass
|
||||
@property
|
||||
@abstractmethod
|
||||
def name(self) -> str:
|
||||
"""Возвращает название алгоритма"""
|
||||
pass
|
||||
|
||||
# class CellAlgorithm(Cell):
|
||||
# def __init__(self, x: int, y: int, parent: Cell, exitDist: float, isWall=False, isStart=False, isExit=False, value=1):
|
||||
# super().__init__(x, y, isWall, isStart, isExit, value)
|
||||
# self.parent = parent
|
||||
# self.ExitDist = exitDist
|
||||
# self.weight = self.value + exitDist
|
||||
|
||||
|
||||
def reconstruct_path(came_from: dict, start: Cell, end: Cell) -> list[Cell]:
|
||||
"""Восстановление пути по словарю предшественников"""
|
||||
path = []
|
||||
current = end
|
||||
|
||||
# Идём от конца к началу по цепочке came_from
|
||||
while current.getXY() != start.getXY():
|
||||
path.append(current)
|
||||
current = came_from[current.getXY()]
|
||||
|
||||
path.append(start)
|
||||
return path[::-1]
|
||||
1078
stepushovgs/labyrinth/test.ipynb
Normal file
1078
stepushovgs/labyrinth/test.ipynb
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user