From 90f5efe9169fe3bf25bee843a13c0caf4feff88f Mon Sep 17 00:00:00 2001 From: magdabiadala Date: Sun, 3 May 2020 20:55:54 +0200 Subject: [PATCH] Poprawiony raport --- route_planning.md | 95 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 route_planning.md diff --git a/route_planning.md b/route_planning.md new file mode 100644 index 0000000..ba5cca1 --- /dev/null +++ b/route_planning.md @@ -0,0 +1,95 @@ +#### Definicja pętli głównej przeszukiwania: +W algorytmie znajdowania najlepszej ścieżki wykorzystana została kolejka priorytetowa *PriorityQueue()* służąca do przechowywania wierzchołków do odwiedzenia. Dopóki nie jest ona pusta, działa pętla główna przeszukiwania. W pętli kolejno: + +1. z kolejki wybierany jest wierzchołek o najniższym priorytecie +```python +while self.open: + _, current_node = self.open.get() + ``` + +2. dodawany jest on do listy już przeszukanych wierzchołków +```python +self.closed.append(current_node) +``` + +3. sprawdzane jest czy aktualny wierzchołek jest jednocześnie celem, który miał zostać osiągnięty przez agenta +```python +if current_node.x == self.dest.x and current_node.y == self.dest.y: + while current_node.x != start_node.x or current_node.y != start_node.y: + self.path.append(current_node) + current_node = current_node.parent + return True +``` + +>(jeśli tak, od strony celu odtwarzana jest najkrótsza ścieżka prowadząca z aktualnego punktu do celu) + +4. znajdowani są sąsiedzi danego wierzchołka, a następnie dla każdego z nich: + ++ liczony jest koszt za pomocą funkcji heurystyki +```python +cost = current_node.g_cost + self.heuristic(current_node, neighbour) +``` + ++ sprawdane jest czy nie należy on do listy już przeszukanych wierzchołkow (jeśli tak, zostaje on pominięty) +```python +if self.check_if_closed(neighbour): + continue +``` + ++ jeśli znajduje się on już w kolejce priorytetowej ale z większym kosztem niż ten obecnie wyliczony, uaktualniony zostaje jego koszt oraz rodzic +```python +if self.check_if_open(neighbour): + if neighbour.g_cost > cost: + neighbour.g_cost = cost + neighbour.parent = current_node +``` + ++ w przeciwnym przypadku, zostaje on dodany do kolejki priorytetowej wraz ze swoim rodzicem oraz wyliczonym kosztem. +```python +else: + neighbour.g_cost = cost + neighbour.h_cost = self.heuristic(neighbour, self.dest) + neighbour.parent = current_node + self.open.put((neighbour.g_cost, neighbour)) + ``` + +#### Definicja funkcji następnika: + +```python +def get_neighbours(self, node: Node): + neighbours = [] + if self.check_if_can_move(Coordinates(node.x + 1, node.y)): + neighbours.append(Node(node.x + 1, node.y)) + if self.check_if_can_move(Coordinates(node.x - 1, node.y)): + neighbours.append(Node(node.x - 1, node.y)) + if self.check_if_can_move(Coordinates(node.x, node.y + 1)): + neighbours.append(Node(node.x, node.y + 1)) + if self.check_if_can_move(Coordinates(node.x, node.y - 1)): + neighbours.append(Node(node.x, node.y - 1)) + return neighbours +``` +Funkcja zwracająca następników w naszym projekcie wykorzystuje sąsiedztwo von Neumanna. Sąsiadami danej płytki, są 4 najbliższe płytki znajdujące się od niej powyżej, poniżej, na prawo oraz na lewo. + +Dla każdego z 4 potencjalnych sąsiadów sprawdzane jest najpierw czy takowy istnieje za pomocą funkcji *check_if_can_move*: + +```python +def check_if_can_move(self, next_coords: Coordinates): + tile_on_map = 0 <= next_coords.x < self.warehouse.width and 0 <= next_coords.y < self.warehouse.height + if not tile_on_map: + return False + next_tile = self.warehouse.tiles[next_coords.x][next_coords.y] + tile_passable = isinstance(next_tile, Tile) and next_tile.category.passable + return tile_passable +``` + +Funkcja ta sprawdza czy wybrany sąsiad znajduje się w obrębie magazynu i czy jest on płytką po której może przemieszczać się agent. + +#### Definicja funkcji heurystyki: + +```python +def heuristic(self, start: Node, goal: Node): + diff_x = pow(goal.x - start.x, 2) + diff_y = pow(goal.y - start.y, 2) + return round(sqrt(diff_x + diff_y), 3) + ``` +w naszym projekcie jako heurystyki używamy funkcji liczącej odległość euklidesową pomiędzy dwoma wybranymi punktami, z których drugi jest aktualnym celem który agent ma osiągnąć.