-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathbbox.py
91 lines (66 loc) · 2.57 KB
/
bbox.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
from __future__ import annotations
import tqdm
import itertools
import collections
from types import FunctionType
from solver.pruning.base import BasePruning
from solver.base import dijkstraFloodFill
from utils.bbox import BoundingBox
from utils.path import getLastEdge
from graph.grid import GridMap
class BBoxPruning(BasePruning):
def __init__(
self,
) -> BBoxPruning:
super().__init__()
self.bboxes = collections.defaultdict(dict)
def preprocess(
self,
forcedDirections: FunctionType,
grid: GridMap,
verbose: bool = True,
) -> None:
per_x, per_y = range(grid.height), range(grid.width)
#init the data
self.bboxes = {
node: {
edge: BoundingBox()
for edge in grid.getAllowedMovements(node[0], node[1])
}
for node in itertools.product(per_x, per_y)
if not grid.isObstacle(node[0], node[1])
}
if verbose:
iterator = tqdm.tqdm(
iterable = itertools.product(per_x, per_y),
total = grid.height*grid.width,
desc = 'Preprocess the map',
leave = True,
)
else:
iterator = itertools.product(per_x, per_y)
# find unions of bboxes
for node in iterator:
if grid.isObstacle(node[0], node[1]):
continue
forced_directions = collections.defaultdict(set)
for computed_node in dijkstraFloodFill(grid, node):
edge = getLastEdge(computed_node)
self.bboxes[node][edge].add(computed_node.i, computed_node.j)
forced_directions[edge].update(forcedDirections(node[0], node[1], edge[0], edge[1], grid))
for edge in forced_directions:
for forced in forced_directions[edge]:
self.bboxes[node][edge] |= self.bboxes[node][forced]
self.preprocessed = True
def getOptimalDirections(
self,
state: Node,
goal: Node,
) -> set:
current = (state.i, state.j)
optimal = {
direction
for direction in self.bboxes[current]
if self.bboxes[current][direction].isInside(goal.i, goal.j)
}
return optimal