@@ -42,38 +42,40 @@ The BFS frontier expands as:
4242
4343.. math ::
4444
45- Q = [(s, [s])]
45+ Q = [(s, [s])], \qquad s \in M
4646
47- where *s * is the start position, and the second term is the path history.
47+ where each element of \( Q\) is a pair \( (v, P)\) with a current node \( v\) and
48+ its path history \( P\) .
4849
49- At each iteration :
50+ The BFS expansion step (pseudocode) :
5051
5152.. math ::
5253
53- (r, c), path = Q.pop(0 )
54+ \begin {aligned}
55+ (r,c),\; P &= Q.pop(0 ), \\
56+ ext{for each } (r',c') \in N(r,c):\quad &\text {if } 0 \le r'<R,\ 0 \le c'<C,\ M_{r',c'}=0 ,\ (r',c')\notin\text {visited},\\
57+ &\quad \text {then } \text {visited} \leftarrow \text {visited} \cup \{(r',c')\},\\
58+ &\quad Q.append\big ((r',c'),\; P + [(r',c')]\big ).
59+ \end {aligned}
5460
55- \text {for each neighbor } (r', c') \text { in } N(r, c):
56- \text {if } (r', c') \text { is free and unvisited:}
57- Q.append((r', c'), path + [(r', c')])
58-
59- The algorithm halts when the target node *t * is reached.
60-
61- Because BFS explores all nodes in increasing distance order, the path returned
62- is the shortest (in terms of number of moves).
61+ The algorithm halts when the target node \( t\) is reached. Because BFS explores
62+ nodes in order of increasing distance, it returns a shortest path (by move count)
63+ for static grids.
6364
6465
6566Dynamic Components
6667------------------
6768
69+
6870### Moving Target
6971
7072Every few frames, the target moves randomly to an adjacent open cell:
7173
7274.. math ::
7375
74- T_{new } = T_{old} + \Delta
76+ T_{t+ 1 } = T_t + \Delta _t, \qquad \Delta _t \in \{(- 1 , 0 ),( 1 , 0 ),( 0 ,- 1 ),( 0 , 1 )\}
7577
76- where :math: ` \Delta \in \{ (- 1 , 0 ), ( 1 , 0 ), ( 0 ,- 1 ), ( 0 , 1 ) \}` .
78+ with the constraint that the new position must be inside the grid and on a free cell .
7779
7880This simulates dynamic goals or moving entities in robotic navigation.
7981
@@ -83,10 +85,9 @@ With a small probability :math:`p`, each cell toggles between *free* and *blocke
8385
8486.. math ::
8587
86- M_{i,j}^{t+1 } =
87- \begin {cases}
88- 1 - M_{i,j}^{t} & \text {with probability } p \\
89- M_{i,j}^{t} & \text {otherwise}
88+ M_{i,j}^{t+1 } = \begin {cases}
89+ 1 - M_{i,j}^{t}, & \text {with probability } p,\\
90+ M_{i,j}^{t}, & \text {with probability } 1 -p.
9091 \end {cases}
9192
9293 This reflects real-world conditions like temporary obstructions or environment changes.
@@ -125,45 +126,21 @@ If :math:`E_t` is the set of explored nodes at frame :math:`t`, then:
125126
126127.. math ::
127128
128- L_t = |P_t|, \quad E_t = |V_t|
129+ L_t = |P_t|, \qquad E_t = |V_t|
130+
131+ where \( P_t\) is the discovered path at frame \( t\) and \( V_t\) is the set of visited nodes.
129132
130- where :math: `P_t` is the discovered path and :math: `V_t` is the visited node set.
133+ Remarks:
131134
132- The solver continually re-estimates the path to accommodate new maze configurations.
135+ - BFS returns a shortest-path in terms of number of grid moves when the grid is static.
136+ - When the environment changes over time, the solver must recompute; this makes optimality
137+ relative to the latest observed configuration rather than the original static grid.
133138
134139
135140Code Link
136141++++++++
137142
138143.. automodule :: PathPlanning.BreadthFirstSearch.dynamic_maze_solver
139- :members:
140- :undoc-members:
141- :show-inheritance:
142-
143- Usage Example
144- ++++++++++++
145-
146- .. code-block :: python
147- import matplotlib.pyplot as plt
148- from PathPlanning.BreadthFirstSearch.dynamic_maze_solver import MazeVisualizer
149-
150- initial_maze = [
151- [0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 ],
152- [0 , 1 , 0 , 1 , 1 , 0 , 1 , 0 , 1 , 0 ],
153- [0 , 0 , 0 , 1 , 0 , 0 , 1 , 0 , 0 , 0 ],
154- [0 , 1 , 0 , 1 , 0 , 1 , 1 , 1 , 1 , 0 ],
155- [0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 ],
156- [0 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 1 , 0 ],
157- [0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 ],
158- [1 , 1 , 1 , 1 , 0 , 1 , 1 , 1 , 1 , 0 ],
159- [0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ],
160- ]
161-
162- start_point = (0 , 0 )
163- end_point = (8 , 9 )
164-
165- visualizer = MazeVisualizer(initial_maze, start_point, end_point)
166- visualizer.run()
167144
168145
169146References
0 commit comments