Algoritmo A* » Histórico » Versão 2
Antonio de Souza Gomes Pereira, 08/03/2020 04:29 h
1 | 1 | Antonio de Souza Gomes Pereira | # Algoritmo A* |
---|---|---|---|
2 | |||
3 | 2 | Antonio de Souza Gomes Pereira | ## Introdução |
4 | |||
5 | A* é um algoritmo para planejamento de trajetórias em um grid contendo o destino, caminhos livres e obstáculos. Sendo amplamente utilizado para encontrar o caminho mais curto (aproximação), de uma maneira rápida e inteligente. Antes de descrever o funcionamento do mesmo, começamos com o algoritmo de Dijkstra e depois como ele pode ser derivado no A*. |
||
6 | |||
7 | ## Algoritmo de Dijkstra |
||
8 | |||
9 | Dado um grafo e um vértice de origem, como podemos achar a mínima distância dele para todos os outros vértices? |
||
10 | Começamos a implementação criando uma lista aberta e uma lista fechada: |
||
11 | |||
12 | * A lista fechada terá como objetivo simplesmente armazenar o estado que o vértice possui, se sua miníma distância foi calculada ou não (True/False), podendo ser simplesmente um vetor de booleans ou uma hash table. |
||
13 | |||
14 | * A lista aberta conterá todos os outros vértices que já foram visitados e não estão na lista fechada, sendo composta de um par (distância, índice). Durante a execução do algoritmo, precisaremos várias vezes saber o vértice de menor distância na lista, por isso sendo de grande utilidade utilizar uma priority queue como lista fechada, pois o elemento de menor distância sempre ficará no topo da lista. |
||
15 | |||
16 | Podemos descrever o algoritmo da seguinte forma: |
||
17 | |||
18 | |||
19 | ``` |
||
20 | 1) Initialize distances of all vertices as infinite. |
||
21 | |||
22 | 2) Create an empty set. Every item of set is a pair |
||
23 | (weight, vertex). Weight (or distance) is used used |
||
24 | as first item of pair as first item is by default |
||
25 | used to compare two pairs. |
||
26 | |||
27 | 3) Insert source vertex into the set and make its |
||
28 | distance as 0. |
||
29 | |||
30 | 4) While Set doesn't become empty, do following |
||
31 | a) Extract minimum distance vertex from Set. |
||
32 | Let the extracted vertex be u. |
||
33 | b) Loop through all adjacent of u and do |
||
34 | following for every vertex v. |
||
35 | |||
36 | // If there is a shorter path to v |
||
37 | // through u. |
||
38 | If dist[v] > dist[u] + weight(u, v) |
||
39 | |||
40 | (i) Update distance of v, i.e., do |
||
41 | dist[v] = dist[u] + weight(u, v) |
||
42 | (i) If v is in set, update its distance |
||
43 | in set by removing it first, then |
||
44 | inserting with new distance |
||
45 | (ii) If v is not in set, then insert |
||
46 | it in set with new distance |
||
47 | |||
48 | 5) Print distance array dist[] to print all shortest |
||
49 | paths. |
||
50 | ``` |
||
51 | |||
52 | |||
53 | |||
54 | Vamos usar o grafo abaixo como exemplo do funcionamento: |
||
55 | |||
56 | ![](exgrafo.png) |
||
57 | |||
58 | A primeira coisa a se fazer é setar todas as distâncias para +INFINITO, excetuando a origem (vértice v1), que será inserida na lista aberta e terá sua distância como 0. |
||
59 | |||
60 | | LISTA ABERTA | |
||
61 | |--- | |
||
62 | | (0 , 1) | |
||
63 | |||
64 | |||
65 | | LISTA FECHADA | |
||
66 | |--- | |
||
67 | |||
68 | Após isso, retiraremos o vértice de menor valor da lista aberta e o inserimos na lista fechada, nesse caso o v1, e calculamos a distância de todos os vértices adjacentes ao recém retirado, os vértices v6, v3 e v2, respectivamente com distâncias 14, 9 e 7, inserindo-os na lista aberta. |
||
69 | ![](exgrafoi1.png) |
||
70 | |||
71 | | LISTA ABERTA | |
||
72 | |--- | |
||
73 | | (7 , 2) | |
||
74 | | (9 , 3) | |
||
75 | | (14 , 6) | |
||
76 | |||
77 | |||
78 | |||
79 | | LISTA FECHADA | |
||
80 | |--- | |
||
81 | | 1 | |
||
82 | |||
83 | |||
84 | |||
85 | Agora devemos repetir o processo, retirando o vértice de menor valor da lista aberta e o inserindo na fechada, nesse caso o v2, após isso devemos colocar na aberta o v4, que ainda não foi inicializado, e manter o valor de v3, pois a distância relativa ao v2 é de 17, sendo maior que 9, caso a distância calculada fosse menor que 9, o valor deveria ser substituído por esse. |
||
86 | |||
87 | |||
88 | ![](grafo2.png) |
||
89 | |||
90 | | LISTA ABERTA | |
||
91 | |--- | |
||
92 | | (9 , 3) | |
||
93 | | (14 , 6) | |
||
94 | | (15 , 4) | |
||
95 | |||
96 | |||
97 | |||
98 | |||
99 | | LISTA FECHADA | |
||
100 | |--- | |
||
101 | | 1 | |
||
102 | | 2 | |
||
103 | |||
104 | Repetimos o processo até a lista aberta estar vazia e todos os vértices estejam na lista fechada, assim encontrando as menores distâncias de cada vértice. Veja que não encontramos o caminho específico que leva a menor distância, se quisermos fazer isso, basta criar um vetor com os índices dos vértices que sempre é atualizado quando o valor da distância também é atualizado. |
||
105 | |||
106 | ## Derivando o A* |
||
107 | |||
108 | |||
109 | |||
110 | ## Referências |