O documento descreve o algoritmo de busca em grafos chamado Breadth First Heuristic Search (BFHS). O BFHS é baseado na busca em largura e usa divisão-e-conquista para reconstruir a solução de forma mais eficiente ao manter listas de nós gerados e visitados de forma mais compacta. O BFHS mantém múltiplas listas abertas e fechadas por camada para evitar repetições e geração de nós que não farão parte da solução, reconstruindo a resposta através de subproblemas.
2. Introdução
Breadth First Heuristic Search é um
algoritmo de busca em grafos nãodirigidos, baseado na busca em largura,
utilizando divisão-e-conquista na
reconstrução da resposta e, listas de nós,
gerados e visitados, mais compactas.
9/26/2007
3. Comparação entre os contornos de buscas
Best-First e Breadth-First
Contorno definido pela heurística
aplicada na expansão dos nós.
i
n
í
c
i
o
Breadth-First
9/26/2007
m
e
t
a
Best-First
5. Revisão: Busca em largura
C
B
OpenList : {A},ClosedList : {}
OpenList : {B,C},ClosedList : {A}
OpenList : {C,E,F},ClosedList : {A,B}
OpenList : {E,F,D},ClosedList : {A,B,C}
OpenList : {F,D,I},ClosedList : {A,B,C,E}
OpenList : {D,I},ClosedList : {A,B,C,E,F}
OpenList
9/26/2007 : {I,G},ClosedList : {A,B,C,E,F,D}
OpenList : {G,J},ClosedList : {A,B,C,E,F,D,I}
G
E
A
D
I
F
J
B
6. Cont...
A busca em largura utiliza duas listas, a fim de
evitar expansões de nós repetidos:
● OpenList : nós gerados e não expandidos
● ClosedList: nós já expandidos.
Cada nó possui um ponteiro para o seu
antecessor, de modo que a resposta possa ser
obtida caminhando-se do nó meta ao nó origem
através destes ponteiros.
9/26/2007
7. Problemas
● Para muitos problemas práticos a lista de
nós expandidos(ClosedList) pode se
tornar muito grande.
● A busca gera muitos nós que não têm a
menor chance de fazer parte da solução.
9/26/2007
8. Questões
● Será que precisamos guardar todos os
nós expandidos a fim de evitar
repetições?
● É possível evitar a geração de nós que
não farão parte da solução?
9/26/2007
9. Questões...
Se quisermos evitar repetições e, ao mesmo
tempo, sermos capazes de construir a resposta,
através dos ponteiros de antecessores, a
resposta é não.
Mas, se quisermos apenas um dos dois, a
resposta é sim.
Para evitar a geração de nós que, com certeza,
não farão parte da solução, podemos podá-los
através do uso de heurísticas.
9/26/2007
10. Solução
Manter uma closedList mais compacta, com o custo de
não ser mais possível a geração da resposta através dos
ponteiros para os nós antecessores.
Na verdade, manteremos diversas closedLists/openLists,
uma para cada nível da expansão da busca.
Lembre-se que a busca em largura funciona expandindose todos os nós de um certo nível, colocando os nós
gerados na openList e os nós expandidos na closedList.
9/26/2007
11. Busca em largura com listas por camada
C
G
E
A
D
I
F
J
B
OpenList[0] :{A},ClosedList[0]={}
OpenList[0] :{},OpenList[1]:{B,C},ClosedList[0] : {A}
OpenList[1]: {C},OpenList[2]:{E,F},ClosedList[1] : {B}
OpenList[1]: {},OpenList[2]:{E,F,D},ClosedList[1] : {B,C}
OpenList[2]: {F,D},OpenList[3]:{I},ClosedList[2] : {E}
OpenList[2]: {D},OpenList[3]:{I},ClosedList[2] : {E,F}
OpenList[2]: {},OpenList[3]:{I,G},ClosedList[2] : {E,F,D}
9/26/2007
OpenList[3]: {G},OpenList[4]:{L,J},ClosedList[3] : {I}
L
12. Quais listas devemos manter?
Localidade de uma busca em largura num grafo:
max {g*(n) – g*(n') , 0}
n,n' : nós do grafo
n' pertence aos predecessores de n.
g*(x) : comprimento do menor caminho até o no x, ou, a primeira
camada em que o nó x aparece durante a busca
Teorema: Número de camadas closedList necessárias a fim de
evitar repetições é igual à localidade do grafo.
Calcular localidade não é simples no caso geral.
Corolário: Grafos não-dirigidos possuem localidade igual a um.
Pelo corolário acima, observamos que armazenar somente a
camada imediatamente anterior é suficiente para evitar repetições.
9/26/2007
13. Listas mantidas
Em cada instante t teremos as seguintes listas :
● closedList[l]
● closedList[l-1]
● closedList[0]
● closedList[relay]
● openList[l]
● openList[l+1]
Onde l é a camada sendo expandida no instante t e relay
é uma camada intermediária.
9/26/2007
14. Como reconstruir a resposta?
Uma vez que não mais armazenamos
todos os nós já expandidos, não podemos
utilizar os ponteiros de nós antecessores
para construir a resposta.
Usaremos uma estratégia de divisão-econquista para gerar respostas aos
subproblemas que, concatenados, formam
a solução.
9/26/2007
15. Simulação(upperBound=4, relay=2)
C
B
G
E
A
D
I
F
J
Open[0] :{A},Closed[0]={}
Open[0] :{},Open[1]:{B,C},Closed[0] : {A}
Open[1]: {C},Open[2]:{E,F},Closed[1] : {B},Closed[0] : {A}
Open[1]: {},Open[2]:{E,F,D},Closed[1] : {B,C},Closed[0] : {A}
Open[2]: {F,D},Open[3]:{I},Closed[2] : {E},Closed[1] : {B,C},Closed[0] : {A}
Open[2]: {D},Open[3]:{I},Closed[2] : {E,F},Closed[1] : {B,C},Closed[0] : {A}
Open[2]: {},Open[3]:{I,G},Closed[2] : {E,F,D},Closed[0] : {A}
9/26/2007
Open[3]: {G},Open[4]:{L,J},Closed[3] : {I}
L
17. Reconstrução da solução através de
divisão-e-conquista
Uma vez que o estado meta é alcançado,
precisamos reconstruir a solução
completa.
Devido aos gaps, isso é não é possível.
Aplicamos então o algoritmo BFHS
recursivamente nos dois gaps,
concatenado as soluções encontradas
para os subproblemas.
9/26/2007
18. Implementação
Implementamos o algoritmo BHFS e o aplicamos ao problema
ReguaPuzzle.
Alguns detalhes:
● custo de cada operação deve ser unitário
● é preciso definir um limite superior*
● camada relay divide o problema em dois subproblemas,
aproximadamente de mesmo custo.
● o grafo de estados do ReguaPuzzle não é dirigido
● desconsideramos heuríticas na expansão dos nós**
● subproblemas têm limites superiores inferiores aos dos
problemas decompostos(limites justos).
(*) utilizamos um limite inferior que é incrementado até que uma solução seja
encontrada.
(**) as heurísticas estavam baseadas no custo para se alcançar algum estado meta
9/26/2007
(no problema ReguaPuzzle as metas são pré-definidas) entretanto, cada
19. Melhorias e comentários
● embora a abordagem de divisão-e-conquista seja
eficaz, é mais eficiente parar a recursão antes
● closedLists poderiam ser removidas apenas quando
um certo quantidade de memória estiver sendo
utilizado, diminuindo assim o comprimento dos gaps
● aumentar o limite superior até que uma solução seja
encontrada é uma estratégia mais conservadora,
preservando memória ao custo de uma busca menos
eficiente.
● o autor sugere ainda a remoção de “alguns” nós das
closedLists*.
● a utilização de diversas listas, ao invés de uma,
9/26/2007
diminue a probabilidade de colisões nos hashs.
20. Resultados e conclusões
Quando um problema de busca em grafos não-digiridos for
limitado pela memória disponível, utilizar BHFS pode ser uma
boa opção.
Nas simulações, BHFS resolveu instâncias maiores que a
busca A*, devido à falta de memória enfrentada pelo mesmo.
Talvez um dos pontos mais interessantes deste algoritmo seja
o de conseguir bons desempenhos, utilizando-se de uma
estratégia de busca trivial como a busca em largura.
9/26/2007
21. Referências
● Rong Zhou and Eric A. Hansen. 2004.
Breadth-First Heuristic Search.
● Rong Zhou and Eric A. Hansen. 2004.
BFHSP: A Breadth-First Heuristic Search
Planner.
9/26/2007