• Nenhum resultado encontrado

PCC173 - Otimização em Redes

N/A
N/A
Protected

Academic year: 2021

Share "PCC173 - Otimização em Redes"

Copied!
38
0
0

Texto

(1)

PCC173 - Otimização em Redes

Marco Antonio M. Carvalho

Departamento de Computação Instituto de Ciências Exatas e Biológicas

Universidade Federal de Ouro Preto

(2)

Avisos

Site da disciplina:

I http://www.decom.ufop.br/marco/ Lista de e-mails:

I pcc173@googlegroups.com Para solicitar acesso:

I http://groups.google.com/group/pcc173

(3)

Conteúdo

(4)

Avisos

I Próxima aula: plantão de dúvidas;

I Próxima aula + 1: Prova 1.

(5)

Algoritmo A

Histórico

O algoritmo A∗ foi proposto por Peter Hart, Nils Nilsson e Bertram Raphael do Stanford Research Institute em 1968, para determinar o caminho a ser navegado pelo robô Shakey, em uma sala com obstáculos. O mesmo algoritmo pode ser utilizado para determinar o caminho mais curto entre um par específico de vértices.

Oriundo da inteligência artificial, este algoritmo é considerado uma extensão do algoritmo de Dijkstra e também é relacionado ao Best-First Search.

Este algoritmo de assemelha ao algoritmo de Dijkstra na medida em que favorece vértices mais próximos ao vértice inicial e também se assemelha ao Best-First Search na medida em que usa informações sobre os vértices mais próximos do destino.

(6)

Algoritmos

#

#

vice versa. A* runs fastest with the fewest graph nodes; grids are often easier to work with but result in lots of nodes. This page covers the A* algorithm but not graph design; see my other page for more about graphs. For the explanations on the rest of the page, I’m going to use grids

because it’s easier to visualize the concepts. Algorithms

There are lots of algorithms that run on graphs. I’m going to cover these:

Breadth First Search explores equally in all directions. This

is an incredibly useful algorithm, not only for regular path finding, but also for procedural map generation, flow field pathfinding, distance maps, and other types of map analysis.

Dijkstra’s Algorithm (also called Uniform Cost Search) lets

us prioritize which paths to explore. Instead of exploring all possible paths equally, it favors lower cost paths. We can assign lower costs to encourage moving on roads, higher costs to avoid forests, higher costs to discourage going near enemies, and more. When movement costs vary, we use this instead of Breadth First Search.

A* is a modification of Dijkstra’s Algorithm that is

optimized for a single destination. Dijkstra’s Algorithm can find paths to all locations; A* finds paths to one location. It prioritizes paths that seem to be leading closer to the goal. I’ll start with the simplest, Breadth First Search, and add one feature at a time to turn it into A*.

Breadth First Search

The key idea for all of these algorithms is that we keep track of an ex-panding ring called the frontier. On a grid, this process is sometimes called “flood fill”, but the same technique works for non-grids. Start the

animation to see how the frontier expands:

Algoritmos

I BFS: Explora igualmente todas as direções.

I Dijkstra: Prioriza caminhos de menor custo durante a exploração.

I A∗: Prioriza caminhos que parecem levar mais rapidamente ao destino.

(7)

O Robô Shakey

(8)

O Robô Shakey

O robô Shakey.

(9)

Algoritmo de Dijkstra

Princípio

Utiliza uma função g(n) que representa o custo exato do caminho entre o vértice de origem e qualquer vértice n.

O algoritmo explora o grafo considerando sempre o vértice de menor g(n). A partir do vértice inicial, expande os caminhos até encontrar o destino desejado e sempreencontra o menor caminho entre os vértices de origem e destino.

(10)

Algoritmo de Dijkstra

O vértice rosa é a origem e o vértice roxo o destino.

A área azul mostra caminhos explorados pelo algoritmo, quanto mais claros os vértices, mais longe do vértice de origem.

(11)

Algoritmo de Dijkstra

O vértice rosa é a origem e o vértice roxo o destino.

No caso com obstáculos, o algoritmo de Dijkstra é lento, mas encontra o caminho mais curto.

(12)

Algoritmo de Dijkstra

Animação

Ver animação Frontier Expansion.

cost_so_far[start] = 0 while not frontier.empty(): current = frontier.get() if current == goal: break

for next in graph.neighbors(current):

new_cost = cost_so_far[current] + graph.cost(current, next) if next not in cost_so_far or new_cost < cost_so_far[next]: cost_so_far[next] = new_cost

priority = new_cost

frontier.put(next, priority) came_from[next] = current

Using a priority queue instead of a regular queue changes the way the fron-tier expands. Contour lines are one way to see this. Start the animation to see how the frontier expands more slowly through the forests, finding the shortest path around the central forest instead of through it:

Breadth First Search Dijkstra’s Algorithm

< Start animation >

Movement costs other than 1 allow us to explore more interesting graphs, not only grids. In the map at the top of the page, movement costs were based on the distance from room to room. Movement costs can also be used to avoid or prefer areas based on proximity to enemies or allies. Implementation notes: We want this priority queue to return the lowest value first. On the implementation page I show PriorityQueuein Python using heapq to return the lowest value first and also in C++ using std::priority_queue configured to return the lowest value first. Also, the version of Dijkstra’s Algorithm and A* I present on this page differs from what’s in algorithms textbooks. It’s much closer to what’s called Uniform Cost Search. I describe the differences on the implementation page.

(13)

Best-First Search

Princípio

Utiliza uma função h(n) que representa uma estimativa do custo do caminho entre o vértice dedestino e qualquer vértice n.

O algoritmo explora o grafo considerando sempre o vértice de menor h(n). A partir do vértice inicial, expande um único caminho até encontrar o destino desejado e não necessariamenteencontra o menor caminho entre os vértices de origem e destino.

Embora seja muito mais rápido do que o algoritmo de Dijkstra, o Best-First Search ignora o comprimento do caminho enquanto o expande e, portanto, pode expandir um caminho mais longo.

(14)

Best-First Search

O vértice rosa é a origem e o vértice roxo o destino. Vértices amarelos possuem alto valor de estimativa e vértices cinza possuem baixo valor de estimativa de custo para chegar ao destino. Marco Antonio M. Carvalho (UFOP) PCC173 23 de abril de 2018 14 / 38

(15)

Best-First Search

O vértice rosa é a origem e o vértice roxo o destino.

No caso com obstáculo, o Best-First Search é mais rápido, mas não possui corretude.

(16)

Best-First Search

Animação

Ver animações Greedy Best-First Search.

#

Heuristic search

With Breadth First Search and Dijkstra’s Algorithm, the frontier expands in all directions. This is a reasonable choice if you’re trying to find a path to all locations or to many locations. However, a common case is to find a path to only one location. Let’s make the frontier expand towards the goal more than it expands in other directions. First, we’ll define a heuris-tic function that tells us how close we are to the goal:

def heuristic(a, b):

# Manhattan distance on a square grid return abs(a.x - b.x) + abs(a.y - b.y)

In Dijkstra’s Algorithm we used the actual distance from the start for the priority queue ordering. Here instead, in Greedy Best First Search, we’ll use the estimated distance to the goal for the priority queue ordering. The location closest to the goal will be explored first. The code uses the priority queue from Dijkstra’s Algorithm but without cost_so_far: frontier = PriorityQueue()

frontier.put(start, 0)

came_from = {}

came_from[start] = None while not frontier.empty(): current = frontier.get() if current == goal: break

for next in graph.neighbors(current): if next not in came_from:

priority = heuristic(goal, next) frontier.put(next, priority) came_from[next] = current

Let’s see how well it works:

Breadth First Search Greedy Best-First Search

(17)

Algoritmo A

Princípio

O algoritmo A∗ utiliza uma função conhecimento-mais-heurística f (n) para estimar o custo do caminho mais curto entre origem e destino que passa pelo vértice n.

A função possui dois componentes, sendo definida da seguinte maneira: f (n) = g(n) + h(n)

Em que g(n) representa o custo exato do caminho entre o vértice inicial e qualquer vértice n e h(n) representa uma estimativa heurística do custo do caminho entre o vértice n e o vértice de destino.

(18)

Algoritmo A

O vértice rosa é a origem e o vértice roxo o destino. No caso simples, o A∗ é tão rápido quanto o Best-First Search. Marco Antonio M. Carvalho (UFOP) PCC173 23 de abril de 2018 18 / 38

(19)

Algoritmo A

O vértice rosa é a origem e o vértice roxo o destino.

No caso com obstáculos, o A∗ determina um caminho tão bom quanto o algoritmo de Dijkstra.

(20)

Algoritmo A

Animação

Ver animações A∗ Search.

# cost_so_far[next] = new_cost

priority = new_cost + heuristic(goal, next) frontier.put(next, priority)

came_from[next] = current

Compare the algorithms: Dijkstra’s Algorithm calculates the distance from the start point. Greedy Best-First Search estimates the distance to the goal point. A* is using the sum of those two distances.

Dijkstra’s 12 13 14 1516 17 18 1920 21 22 2324 25 26 11 12 13 1415 16 17 1819 20 21 2223 24 25 10 11 12 1314 25 26 9 10 11 1213 14 15 1617 18 19 20 24 25 8 9 10 11 12 13 14 1516 17 18 19 23 24 7 8 9 10 11 12 13 1415 16 17 18 22 23 6 7 8 9 10 11 12 1314 15 16 17 21 22 5 6 7 8 9 10 11 1213 14 15 16 20 21 4 5 6 7 8 9 10 11 12 13 14 15 19 20 3 4 5 6 7 8 9 10 11 12 13 14 18 19 2 3 4 5 6 7 8 9 10 11 12 13 17 18 1 2 3 4 5 6 7 8 9 10 11 12 16 17 0 1 15 16 1 2 3 4 5 6 7 8 9 10 11 1213 14 15 2 3 4 5 6 7 8 9 10 11 12 1314 15 16 Greedy Best-First 11 10 9 8 7 6 5 4 3 2 11 10 9 8 7 6 5 4 3 2 1 0 12 11 2 13 12 11 10 9 8 7 6 5 13 12 11 10 9 8 7 6 13 12 11 10 9 8 7 15 14 1312 11 10 9 8 17 16 15 1413 12 11 10 9 1918 17 16 13 12 11 10 21 2019 18 12 11 23 22 2120 12 24 23 22 25 24 26 A* Search 27 2727 27 27 2727 27 27 27 27 25 2525 25 25 2525 25 25 2525 27 25 27 27 25 2525 25 25 2525 25 27 25 2525 25 25 2525 25 27 25 2525 25 25 2525 25 27 25 2525 25 25 2525 25 25 25 2525 25 25 2525 25 25 25 25 2527 27 27 2727 27 2525 25 25 25 2525 25 25 2525 25 25 27

Try opening a hole in the wall in various places. You’ll find that when Greedy Best-First Search finds the right answer, A* finds it too, exploring the same area. When Greedy Best-First Search finds the wrong answer (longer path), A* finds the right answer, like Dijkstra’s Algorithm does, but still explores less than Dijkstra’s Algorithm does.

A* is the best of both worlds. As long as the heuristic does not overesti-mate distances, A* finds an optimal path, like Dijkstra’s Algorithm does. A* uses the heuristic to reorder the nodes so that it’s more likely that the goal node will be encountered sooner.

And … that’s it! That’s the A* algorithm.

More

Are you ready to implement this? Consider using an existing li-brary. If you’re implementing it yourself, I have companion guide that shows step by step how to implement graphs, queues, and pathfinding algorithms in Python, C++, and C#.

Which algorithm should you use for finding paths on a game map? If you want to find paths from or to all all locations, use Breadth First

(21)

Algoritmo A

Considerações sobre a Estimativa Heurística

Algumas considerações sobre h(n):

I Em um caso extremo, se h(n) = 0, então apenas g(n) guiará o algoritmo, tornando-o equivalente ao algoritmo de Dijkstra;

I Se h(n) é sempre menor ou igual ao custo do caminho mais curto entre n e o destino, então o algoritmo A∗ garantidamente encontrará o caminho mais curto – denominamos h(n) admissível;

I Quanto menor o valor de h(n) (para todo n), mais vértices serão expandidos pelo A∗, tornando-o mais lento.

(22)

Algoritmo A

Considerações sobre a Estimativa Heurística (continuado)

I Se h(n) é exatamente igual ao custo do caminho mais curto entre n e o destino, então o A∗ expandirá somente o caminho mais curto, se tornando muito rápido;

I Se h(n) em algum momento for maior que o custo do caminho mais curto entre n e o destino, então não há garantia de que o caminho mais curto será encontrado. Porém, será rápido;

I Em outro caso extremo, se h(n) é muito maior do que g(n), então apenas h(n) guiará o algoritmo, tornando-o equivalente ao Best-First Search.

(23)

Algoritmo A

Terminologia

I F : conjunto dos vértices fechados (já examinados);

I A: conjunto dos vértices abertos (ainda não examinados);

I f (v): função de custo do vértice v;

I g(v): distância da origem até o vértice v;

I g0(v): distância da origem até o vértice v, usando um vértice intermediário;

I h(v): estimativa heurística do custo do caminho do vértice v até o vértice de destino;

I N (v): conjunto de vértices adjacentes ao vértice v;

I dij: distância entre os vértices i e j, de acordo com a matriz D; I rot: vetor utilizado para reconstrução do caminho determinado pelo

(24)

Algoritmo A

Entrada: Grafo G = (V , E), vértices de origem e destino o, d, matriz de distâncias D 1F ← ∅;

2A ← A ∪ {o};

3Crie um vetor vazio rot; 4g(o) ← 0;

5f (o) ← g(o) + h(o); 6enquanto A 6= ∅ faça

7 atual ← i|f (i) < f (j) ∀j ∈ A; 8 se atual = d então retorna rot; 9 A ← A \ {atual};

10 F ← F ∪ {atual};

11 para cada vértice v ∈ N (atual) faça 12 se v ∈ F então continue; 13 g0(v) ← g(atual) + d atual,v; 14 se v /∈ A ou g0(v) < g(v)então 15 rot[v] ← atual; 16 g(v) ← g0(v); 17 f (v) ← g(v) + h(v); 18 se v /∈ A então A ← A ∪ {v}; 19 fim 20 fim 21fim 22retorna ERRO;

(25)

Algoritmo A

Complexidade

A complexidade de tempo do A∗ depende diretamente da função h(v) usada.

No pior caso, a quantidade de vértices explorados é exponencial no tamanho do menor caminho.

Porém, o algoritmo possui complexidade de tempo polinomial se |h(v) − h∗(v)| ≤ O(log h∗(v)), em que h∗(v) é a heurística perfeita. Em outras palavras, o algoritmo possui complexidade de tempo polinomial se o erro de h(v) não crescer mais rapidamente do que o logaritmo da heurística perfeita.

(26)

Heurísticas

Mapas em Grade

Para mapas em grade, existem estimativas heurísticas adotadas amplamente:

I Em grades quadradas, que permitem movimentos em 4 direções, usamos a distância Manhattan;

I Em grades quadradas, que permitem movimentos em 8 direções, usamos a distância Chebyshev (ou distância Diagonal);

I Em grades quadradas, que permitem movimentos em todas as direções, usamos a distância Euclidiana (que permitem movimentos fora da grade);

I Em grades hexagonais, que permitem movimentos em 6 direções, usamos a distância Manhattan adaptada para grades hexagonais.

(27)

Manhattan vs. Euclidiana

Distância Manhattan (vermelho, azul e amarelo) e distância Euclidiana (verde).

(28)

Exemplo

Mapa das cidades da Romênia, um exemplo clássico para demonstração do algoritmo A∗.

(29)

Exemplo

Vamos executar o algoritmo A∗ para determinar o caminho mais curto entre as

cidades de Arad e Bucharest, utilizando como heurística a distância em linha reta (nunca superestima a distância real).

(30)

Exemplo

(31)
(32)

Exemplo

(33)
(34)

Exemplo

A função f (v) deve ser monotonicamente crescente ao longo do caminho. Vértices internos à área contornada possuem f (v) menor ou igual aos vértices

externos. Nos contornos, f = 380, f = 400 e f = 420.

(35)

Mais Visualizações

Visualização dos algoritmos A∗, BFS, Dijkstra e Best-First Search em um mapa rodoviário

I http://kevanahlquist.com/osm_pathfinding/

Visualização dos algoritmos A∗, BFS, Dijkstra e Best-First Search e outros em um grid

(36)

Algoritmo A

Referências

I Introduction to A∗, from Red Blob Games. Disponível em:

https://www.redblobgames.com/pathfinding/a-star/introduction.html. Acessado em 20 de abril de 2018.

(37)

Exercício

Execute o algoritmo A∗para determinar o caminho mais curto entre as cidades de

(38)

Dúvidas?

Referências

Documentos relacionados

[r]

O embrião das hostilidades veio em forma de um conflito sistematizado na região da Caxemira entre os anos de 1947 e 1948, protagonizados pela Índia e pelo Paquistão logo após

In fact, much of the current usage and rise of coup with adjectives falls outside the classic conceptualization, and changes the concept structure of coups into a family

As associações encontradas entre os polimorfismos do gene HTR2C e sintomas comportamentais, em especial a comportamento agressivo, a problemas sociais e tempo cognitivo

De acordo com o Plano Estratégico Nacional do Turismo (PENT), Portugal dispõe das características – condições climatéricas, recursos naturais e culturais – poten- ciadoras

Esta capacidade pode ter duas vertentes: a fotográfica, que corresponde ao registo do texto exactamente como se fosse uma fotografia (mais rara); e a memória visual

Para não encompridar demais a história de “Influência do jazz”, lembro que, ainda em 1963, o Bossa Três (com Luiz Carlos Vinhas ao piano, Tião Neto ao baixo e

Saraiva e Ponte (2003) mostram como o trabalho cola- borativo envolvendo um investigador e um pequeno grupo de professores de Matemática do ensino secundário, desenvolvido também