• Nenhum resultado encontrado

aula 03 - Busca informada

N/A
N/A
Protected

Academic year: 2021

Share "aula 03 - Busca informada"

Copied!
11
0
0

Texto

(1)

Estratégias de Busca Informadas

Em determinados casos, possui-se mais informações além da definição do problema, e essa informação pode ser usada para otimizar a busca por uma solução. Esse tipo de busca é chamada de busca informada, ou busca heurística.

A abordagem geral que consideramos é chamada best-first search. Best-first search é uma instância do algoritmo geral em árvore ou grafo, no qual um nó é selecionado para expansão com base em uma função de avaliação, f(n). A função de avaliação é interpretada como uma estimativa de custo, portanto, o nó com a avaliação mais baixa é expandido primeiro. A implementação em grafo da best-first search é idêntica à da busca de custo uniforme abordada anteriormente, exceto pelo uso de f em vez de g para ordenar a fila de prioridade. A escolha de f determina a estratégia de busca. A maioria desses algoritmos inclui como componente de f uma função heurística, denotada h(n): h(n) = custo estimado do caminho do estado no nó n para um estado de meta.

Note que h(n) toma um nó como entrada, mas, ao contrário de g(n), depende apenas do estado naquele nó. Por exemplo, na Romênia, pode-se estimar o custo do trajeto mais barato de Arad para Bucareste por distâncias em linha reta entre Arad e Bucareste.

Funções heurísticas são a forma mais comum em que o conhecimento adicional do problema é transmitido ao algoritmo de busca. As funções heurísticas serão tratadas com detalhe posteriormente, por enquanto, consideramos como funções arbitrárias, não-negativas, específicas do problema, com uma restrição: se n é um nó de meta, então h(n) = 0.

Busca Gananciosa

A busca gananciosa tenta expandir o nó que está mais próximo da meta, com base no fato de que isso provavelmente levará a uma solução rapidamente. Assim, avalia os nós usando apenas a função heurística; isto é, f(n) = h(n). Vamos ver como isso funciona para problemas de localização de rotas na Romênia; usamos a heurística de distância em linha reta, a qual chamaremos hLR. Se o objetivo é

Bucareste, precisamos conhecer as distâncias em linha reta para Bucareste, que são mostradas na tabela abaixo. Por exemplo, hLR(In(Arad)) = 366.

(2)

Observe que os valores de hLR não podem ser calculados a partir da própria descrição do problema.

Além disso, é preciso uma certa experiência para saber que hLR está correlacionado com as

distâncias reais das rodovias e é, portanto, uma heurística útil.

A figura abaixo mostra o progresso de uma busca gananciosa, na melhor das hipóteses, usando hLR

para encontrar um caminho de Arad a Bucareste. O primeiro nó a ser expandido de Arad será Sibiu porque está mais perto de Bucareste do que de Zerind ou Timisoara. O próximo nó a ser expandido será Fagaras porque está mais próximo. Fagaras, por sua vez, gera Bucareste, que é o objetivo.

(3)

Para este problema em particular, a pesquisa gananciosa usando hLR encontra uma solução sem

nunca expandir um nó que não esteja no caminho da solução; Portanto, seu custo de pesquisa é mínimo. Não é o ideal, no entanto: o caminho de Sibiu e Fagaras para Bucareste é 32 quilômetros mais longo do que o caminho através de Rimnicu Vilcea e Pitesti. Isso mostra por que o algoritmo é chamado de "ganancioso": em cada passo ele tenta chegar o mais perto possível do objetivo.

Condições para Condições Ótimas: Admissibilidade e Consistência

A primeira condição necessária para otimização do algoritmo é que h(n) seja uma heurística admissível. Uma heurística admissível é aquela que nunca superestima o custo para alcançar o objetivo. Como g(n) é o custo real para alcançar n ao longo do caminho atual, e f(n) = g(n) + h(n), temos como consequência imediata que f(n) nunca superestima o verdadeiro custo de uma solução ao longo do caminho atual através de n.

As heurísticas admissíveis são, por natureza, otimistas porque acham que o custo de resolver o problema é menor do que realmente é. Um exemplo óbvio de uma heurística admissível é a distância em linha reta hLR que usamos para chegar a Bucareste. A distância em linha reta é

admissível porque o caminho mais curto entre dois pontos é uma linha reta, então o caminho em linha reta não pode ser superestimada.

Na figura abaixo, tem-se o progresso de uma busca da árvore A* em Bucareste. Os valores de g são calculados a partir dos custos da etapa na figura do mapa, ilustrado na aula anterior, e os valores de hLR são dados na figura anterior. Observe, em particular, que Bucareste aparece pela primeira vez na

fronteira na etapa (e), mas não é selecionada para expansão porque seu custo f = 450 é maior que o de Pitesti 417.

Outra maneira de dizer isso é que pode haver uma solução através do Pitesti cujo custo é tão baixo quanto 417, então o algoritmo não irá se contentar com uma solução que custa 450. Uma segunda condição um pouco mais forte chamada consistência (ou às vezes monotonicidade) é necessária apenas para aplicações de A* para pesquisa por grafo. Uma heurística h(n) é consistente se, para cada nó n e todo sucessor n’ de n gerado por qualquer ação a, o custo estimado de atingir a meta a partir de n não é maior que o custo da etapa de chegar a n’ mais o estimado custo de atingir o objetivo de n’:

(4)

Esta é uma forma da desigualdade do triângulo, que estipula que cada lado de um triângulo não pode ser maior que a soma dos outros dois lados. Aqui, o triângulo é formado por n, n’, e o objetivo Gn mais próximo de n. Para uma heurística admissível, a desigualdade faz perfeito sentido: se

houvesse uma rota de n para Gn via n’ que fosse mais barata que h(n), isso violaria a propriedade

que h(n) é um limite inferior do custo para alcance Gn. É bastante fácil mostrar que toda heurística

consistente é também admissível. A consistência é, portanto, um requisito mais rígido do que a admissibilidade, mas é preciso trabalhar muito duro para inventar heurísticas que sejam admissíveis,

(5)

mas não consistentes. Todas as heurísticas admissíveis que discutimos neste capítulo também são consistentes. Considere, por exemplo, hLR. Sabemos que a desigualdade geral do triângulo é

satisfeita quando cada lado é medido pela distância em linha reta e que a distância em linha reta entre n e n’ não é maior que c(n, a, n’). Portanto, hLR é uma heurística consistente.

A condição ótima de A*

Como mencionada anteriormente, A* tem as seguintes propriedades: a versão de busca em árvore de A* é ótima se h(n) for admissível, enquanto a versão de busca por grafo é ótima se h(n) for consistente. Mostramos a segunda dessas duas afirmações, pois é mais útil. O argumento essencialmente espelha o argumento para a otimização da busca de custo uniforme, com g substituído por f - assim como no próprio algoritmo A*.

O primeiro passo é estabelecer o seguinte: se h(n) é consistente, então os valores de f(n) ao longo de qualquer caminho são não-decrescentes. A prova segue diretamente da definição de consistência. Suponha que n’ seja um sucessor de n; então g(n’) = g(n) + c (n,a, n) para alguma ação a, e temos:

f(n’) = g(n’) + h(n’) = g(n) + c(n, a, n’) + h(n’) ≥ g(n) + h(n) = f(n)

O próximo passo é provar que sempre que A* seleciona um nó n para expansão, o caminho ótimo para esse nó foi encontrado. Se este não fosse o caso, teria que haver outra fronteira nó n’ no caminho ótimo do nó inicial para n, pela propriedade de separação do grafo, porque f não está diminuindo ao longo de qualquer caminho, n’ teria menor custo f que n e teria sido selecionado primeiro.

Das duas observações precedentes, segue-se que a sequência de nós expandidos por A* usando a pesquisa por grafo está em ordem decrescente de f(n). Portanto, o primeiro nó de meta selecionado para expansão deve ser uma solução ótima, porque f é o custo real para os nós de meta (que possuem h = 0) e todos os nós de meta posteriores serão pelo menos tão caros quanto.

O fato de os custos f não estarem diminuindo ao longo de qualquer caminho também significa que podemos desenhar contornos no espaço de estados, assim como os contornos de um mapa topográfico. A figura abaixo mostra um exemplo.

(6)

Dentro do contorno rotulado com o valor 400, todos os nós têm f(n) menor ou igual a 400 e assim por diante. Então, como A* expande o nó de fronteira de menor custo f, podemos ver que uma busca A* se espalha a partir do nó inicial, adicionando nós em faixas concêntricas de aumento de custo f.

Com busca de custo uniforme (busca A* usando h(n) = 0), as bandas serão “circulares” ao redor do estado inicial. Com heurísticas mais precisas, as bandas se estenderão para o estado objetivo e se tornarão mais estreitamente focadas em torno do caminho ideal. Se C* é o custo do caminho da solução ótima, então podemos dizer o seguinte:

• A* expande todos os nós com f(n) < C*.

• A* pode, então, expandir alguns dos nós diretamente no “contorno de meta” (onde f(n) = C*) antes de selecionar um nó de meta.

A completude requer que haja apenas alguns nós finitos com custo menor ou igual a C*, uma condição que é verdadeira se todos os custos da etapa excederem um número finito ε se b é finito. Observe que A* não expande nenhum nó com f(n) > C*, por exemplo, Timisoara não é expandido, embora seja um filho da raiz. Nós dizemos, então, que a subárvore abaixo de Timisoara é podada. Como hLR é admissível, o algoritmo pode ignorar esta subárvore com segurança, garantindo a

otimização. O conceito de poda (eliminar possibilidades sem ter que examiná-las) é importante para muitas áreas da IA. Uma observação final é que, entre os algoritmos otimizados desse tipo (algoritmos que estendem os caminhos de busca da raiz e usam a mesma informação heurística), A* é otimamente eficiente para qualquer heurística consistente. Ou seja, não é garantido que nenhum

(7)

outro algoritmo ótimo expanda menos nós do que A* (exceto, possivelmente, através de desempate entre nós com f(n) = C*). Isso ocorre porque qualquer algoritmo que não expanda todos os nós com f(n) < C* corre o risco de perder a solução ideal.

A pesquisa A* ser completa, ótima e otimamente eficiente entre todos algoritmos do tipo, é bastante satisfatória. Infelizmente, isso não significa que A* seja a resposta para todas as nossas necessidades de pesquisa. O problema é que, para a maioria dos problemas, o número de estados dentro do espaço de pesquisa de contornos do objetivo ainda é exponencial no comprimento da solução.

Os detalhes da análise estão além do escopo dessa disciplina, mas os resultados básicos são os seguintes. Para problemas com custos de passo constantes, o crescimento no tempo de execução como uma função da profundidade da solução ótima d é analisado em termos do erro absoluto ou do erro relativo da heurística. O erro absoluto é definido como Δ ≡ h* - h, onde h* é o custo real da obtenção da raiz até a meta e o erro relativo é definido como ε ≡ (h* - h)/h*.h*.

Os resultados da complexidade dependem muito fortemente das suposições feitas sobre o espaço de estados. O modelo mais simples estudado é um espaço de estados que tem um único objetivo e é essencialmente uma árvore com ações reversíveis. O quebra-cabeças de 8-peças deslizáveis satisfaz o primeiro e terceiro destes pressupostos. Neste caso, a complexidade de tempo de A* é exponencial no erro máximo absoluto, isto é, O(bΔ). Para custos constantes, podemos escrever isso

como O(bεd), onde d é a profundidade da solução.

Para quase todas as heurísticas em uso prático, o erro absoluto é pelo menos proporcional ao custo do caminho h*, então ε é constante ou crescente e a complexidade do tempo é exponencial em d. Também podemos ver o efeito de uma heurística mais precisa: O(bεd) = O((bε)d), então o fator

efetivo de ramificação (definido mais formalmente na próxima seção) é bε.

Quando o espaço de estados tem muitos estados de meta, particularmente estados de objetivo quase ótimos, o processo de busca pode ser desviado do caminho ideal e existe um custo extra proporcional ao número de objetivos cujo custo está dentro de um fator ε do custo ótimo. Finalmente, no caso geral de um grafo, a situação é ainda pior. Pode haver exponencialmente muitos estados com f(n) < C* mesmo se o erro absoluto for limitado por uma constante.

(8)

A complexidade de A* muitas vezes torna impraticável insistir em encontrar uma solução ideal. Pode-se usar variantes de A* que localizam soluções sub-ótimas rapidamente, ou às vezes é possível projetar heurísticas mais precisas, mas não estritamente admissíveis. Em qualquer caso, o uso de uma boa heurística ainda oferece enormes economias em comparação com o uso de uma pesquisa desinformada.

O tempo de computação não é, no entanto, o principal inconveniente de A*. Como ele mantém todos os nós gerados na memória (assim como todos os algoritmos de busca por grafo), A* geralmente fica sem espaço muito antes fica sem tempo. Por esse motivo, A* não é prático para muitos problemas de grande escala. Existem, no entanto, algoritmos que superam o problema do espaço sem sacrificar a otimização ou integridade, a um custo pequeno em tempo de execução. Pesquisa heurística limitada pela memória

A maneira mais simples de reduzir os requisitos de memória para A* é adaptar a idéia de aprofundamento iterativo ao contexto de busca heurística, resultando no algoritmo A* de aprofundamento iterativo (IDA*). A principal diferença entre o IDA* e o aprofundamento iterativo padrão é que o ponto de corte usado é o custo f (g + h) em vez da profundidade. A cada iteração, o valor de corte é o menor custo f de qualquer nó que excedeu o ponto de corte na iteração anterior.

O IDA* é prático para muitos problemas com custos unitários e evita a sobrecarga substancial associada à manutenção de uma fila ordenada de nós. Infelizmente, ela sofre das mesmas dificuldades com custos de valor real que a versão iterativa da pesquisa de custo uniforme.

A pesquisa recursiva melhor-primeiro (RBFS) é um algoritmo recursivo simples que tenta imitar a operação da pesquisa padrão melhor-primeiro, mas usando apenas o espaço linear. Sua estrutura é semelhante à de uma pesquisa recursiva em profundidade, mas em vez de continuar indefinidamente no caminho atual, ela usa uma variável f-limite para acompanhar o valor f do melhor caminho alternativo disponível a partir de qualquer ancestral do nó corrente. Se o nó atual exceder esse limite, a recursão se desenrola de volta para o caminho alternativo. À medida que a recursão se desenrola, o RBFS substitui o valor f de cada nó ao longo do caminho por um valor de backup (o melhor valor f de seus filhos). Desta forma, a RBFS lembra o valor f da melhor folha na subárvore esquecida e pode, portanto, decidir se vale a pena reexpandir a subárvore em algum momento posterior. A figura abaixo mostra como a RBFS chega a Bucareste.

(9)

O RBFS é um pouco mais eficiente que o IDA*, mas ainda sofre com a excessiva regeneração de nós. No exemplo da figura acima, a RBFS segue o caminho via Rimnicu Vilcea, então “muda de idéia” e tenta Fagaras, e depois muda de idéia novamente. Essas mudanças mentais ocorrem porque, toda vez que o melhor caminho atual é estendido, é provável que seu valor f aumente (h é geralmente menos otimista para nós mais próximos da meta). Quando isso acontece, o segundo melhor caminho pode se tornar o melhor caminho, portanto, a pesquisa precisa recuar para segui-lo. Cada mudança corresponde a uma iteração do IDA* e pode exigir muitas reexpansões de nós esquecidos para recriar o melhor caminho e estendê-lo mais um nó. Como na busca em árvore, o RBFS é um algoritmo ótimo se a função heurística h(n) for admissível. Sua complexidade de espaço é linear na profundidade da solução ideal mais profunda, mas sua complexidade de tempo é bastante

(10)

difícil de caracterizar: depende tanto da precisão da função heurística quanto da frequência com que o melhor caminho muda à medida que os nós são expandidos.

O IDA* e o RBFS sofrem com o uso de pouca memória. Entre as iterações, o IDA* retém apenas um único número: o limite atual do custo f. O RBFS retém mais informações na memória, mas usa apenas espaço linear: mesmo se mais memória estivesse disponível, o RBFS não tem como utilizá-lo. Como eles esquecem a maior parte do que fizeram, os dois algoritmos podem acabar reexpandindo os mesmos estados várias vezes. Além disso, eles sofrem o aumento potencialmente exponencial na complexidade associada a caminhos redundantes em gráficos. Parece sensato, portanto, usar toda a memória disponível. Dois algoritmos que fazem isso são MA* (A* limitado pela memória) e SMA* (MA* simplificado).

SMA* atua como A*, expandindo a melhor folha até que a memória esteja cheia. Neste ponto, não é possível adicionar um novo nó à árvore de pesquisa sem eliminar um antigo. O SMA* sempre derruba o pior nó da folha: aquele com o maior valor f. Assim como o RBFS, o SMA* faz backup do valor do nó esquecido para seu pai. Dessa forma, o ancestral de uma subárvore esquecida conhece a qualidade do melhor caminho nessa subárvore. Com essa informação, o SMA* regenera a subárvore somente quando todos os outros caminhos forem exibidos com aparência pior do que o caminho esquecido.

Outra maneira de dizer isso é que, se todos os descendentes de um nó n são esquecidos, então não saberemos para onde ir de n, mas ainda teremos uma idéia de como valer a pena ir a qualquer lugar de n. O algoritmo completo é muito complicado para reproduzir aqui, mas há uma sutileza que vale a pena mencionar. Dizemos que a SMA* expande a melhor folha e apaga a pior folha. E se todos os nós da folha tiverem o mesmo valor f?

Para evitar a seleção do mesmo nó para exclusão e expansão, o SMA* expande a folha mais recente e exclui a pior folha mais antiga. Elas coincidem quando há apenas uma folha, mas, nesse caso, a árvore de pesquisa atual deve ser um caminho único, de raiz a folha, que preenche toda a memória. Se a folha não for um nó de meta, mesmo se estiver em um caminho de solução ideal, essa solução não poderá ser acessada com a memória disponível. Portanto, o nó pode ser descartado exatamente como se não tivesse sucessores. O SMA* é completo se houver alguma solução acessível, isto é, se d, a profundidade do nó de objetivo mais raso, for menor que o tamanho da memória (expresso em nós).

(11)

É ideal se qualquer solução ótima for alcançável, caso contrário, retorna a melhor solução alcançável. Em termos práticos, o SMA* é uma escolha bastante robusta para encontrar soluções ótimas, particularmente quando o espaço de estados é um grafo, os custos de etapa não são uniformes e a geração de nós é cara em comparação com a sobrecarga de manutenção da fronteira e do conjunto explorado.

Em problemas muito difíceis, no entanto, muitas vezes será o caso que o SMA* será forçado a alternar continuamente entre muitos caminhos de solução, apenas um pequeno subconjunto dos quais pode caber na memória (isso se assemelha ao problema de debulhar em sistemas de paginação em disco). Então, o tempo extra necessário para a regeneração repetida dos mesmos nós significa que problemas que seriam praticamente solucionáveis por A*, com memória ilimitada, tornam-se intratáveis para o SMA*. Ou seja, as limitações de memória podem tornar um problema intratável do ponto de vista do tempo de computação. Embora nenhuma teoria atual explique a troca entre tempo e memória, parece que esse é um problema inevitável. A única saída é eliminar o requisito de “solução ótima”.

Referências

Documentos relacionados

Todavia, segundo Ajeje (2015), existem dificuldades para determinar com precisão a ocorrência de falhas, tais como: os fatores de ocorrência, severidade e

As concentrações de azoto e de fósforo no solo mineral foram analisadas um ano após incêndio e as perdas por escorrência durante o segundo ano, em três zonas de pinhal com

As investigações sobre a distribuição dos knickpoints e/ou knickzones, na bacia de drenagem, sobretudo abrangendo grandes áreas, são limitadas (Hayakawa &amp; Oguchi, 2006), em

O conjunto de high-availability Synology integra dois RackStation RC18015xs+ como nós de computação duplos e várias unidades de expansão RXD1215sas como unidades de

O Synology high-availability cluster integra dois RackStation RC18015xs+ como nódulos de computação duplos, e múltiplas Unidades de Expansão como unidades de

Nota: Para obter mais informações sobre a edição dos privilégios de acesso de um grupo às pastas compartilhadas ou aplicativos, consulte &#34;Permitir o acesso dos usuários ou

replicação/dispositivo para dispositivo: Copie facilmente os arquivos de e para as unidades USB conectadas ou qualquer compartilhamento de rede – incluindo os locais do

desempenho, ideal para pequenas e médias empresas e empresas distribuídas para proteção de dados avançada e compartilhamento de conteúdo remoto e