Você está na página 1de 5

ECOI22 - Inteligência Artificial - Métodos de Busca

e Programação Dinâmica (PD)


P. H. A. Prado1 , R. J. R. Macieira2
1,3 Institute of Technological Sciences, Universidade Federal de Itajubá, Itabira, Minas Gerais, Brazil
phaprado@unifei.edu.br, rafaelreis14@hotmail.com

Abstract—Este trabalho tem como objetivo apresentar, explicar a) Busca em largura: A pesquisa em largura consiste na
e comparar a programação dinâmica (PD) e também os principais construção de uma árvore de estados partindo do estado inicial
métodos de busca existentes, além de apresentar implementações - onde se aplica, a todo momento, todas as regras possı́veis
de dois destes - implementação esta que servirá para comparar os
métodos aplicados de acordo com as propriedades Completude, aos estados de maior profundidade. Sempre encontra a solução
Otimalidade, Complexidade de Tempo e Complexidade de Espaço. (quando esta existe), mas com um alto custo considerando
que demora muito tempo e ocupa muito espaço. Porém, sua
Palavras-chave—Métodos de Busca, Implementações, Pro- principal vantagem é que sempre encontra o MENOR caminho
priedades, Programação Dinâmica. entre o nodo inicial e o final mais próximo.
b) Busca em profundidade: Já a pesquisa em profun-
I. I NTRODUÇ ÃO didade consiste na exploração completa de cada ramo da
Os métodos de busca não foram ”inventados” para solu- árvore antes mesmo de conhecer o ramo vizinho. Ela tem um
cionar os problemas mais complexos da humanidade - muito custo bom considerando que usa pouca memória, é boa para
pelo contrário, tiveram suas primeiras aplicações em desafios problemas com várias soluções. Porém, não pode ser usada em
lógicos simples e bem conhecidos. Historicamente, as primeiras árvores com profundidade infinita, correndo o risco de ficar
situações a serem estudadas foram os quebra-cabeças, os jogos presa em ramos errados. A busca em profundidade não encontra
e a prova automática de teoremas. Ou seja, os métodos de busca necessariamente a solução mais rápida, mas acaba sendo mais
são pensados para resolver problemas solucionáveis por seres eficiente se tratando de situações com várias soluções ou vários
humanos - soluções essas que estão associadas à inteligência. caminhos para a solução.
Esses são problemas de conhecimento total, ou seja, tudo o que 2) Busca Heurı́stica: A busca heurı́stica leva em conta o ob-
precisa para solucioná-los é conhecido. Como por exemplo, se jetivo para decidir qual caminho escolher - ou seja, ela utiliza de
um método de busca fosse construir um carro, seria necessário conhecimento extra sobre o problema para guiar o seu processo
que todas as peças, sem exceção, estivessem dispostas assim de busca. Um bom exemplo de comparação é a procura de um
como suas funções individuais e em conjunto. Dessa forma, é barco perdido no oceano. A busca às cegas procura o barco no
possı́vel traçar um caminho até a resolução do problema. oceano inteiro. A busca heurı́stica utiliza informações relativas
Um problema de busca é definido por alguns elementos, e o a esse problema (vento, correntes marı́timas, clima etc.). Em
primeiro a ser citado é o espaço de estados, onde cada módulo muitos casos, a utilização dos métodos de busca às cegas pode
dele descreve uma possı́vel situação do problema. Outro é um se tornar inviável devido o alto número de nós explorados
estado inicial, que descreve a situação inicial do problema. para chegar até a solução. No método heurı́stico, na maioria
Há também os estados finais, que representam as situações das vezes é possı́vel estabelecer regras que ajudem a reduzir
finais/desejáveis. Por fim, há um conjunto de procedimentos a busca - essas técnicas dependem de informações especı́ficas
que, de acordo com o estado dado, determinam todos os outros sobre o problema abordado. Esse tipo de informação é chamado
estados que podem ser alcançados a partir dele. de informação heurı́stica, enquanto os procedimentos de busca
são chamados de métodos de busca heuristica. As principais
II. M ATERIAIS E M ÉTODOS estratégias de busca heurı́stica são a ”subida da encosta”, ”o
melhor primeiro”, e a ”têmpera simulada”.
A. Métodos de Busca
a) Busca ”Subida da Encosta”: O método ”subida da
Existem múltiplas estratégias de busca para a resolução de encosta” é o mais popular e também o mais simples. Ele é
problemas - cada uma com suas particularidades e resultados. baseado na busca em profundidade, que tem a meta de alcançar
Essas estratégias de busca são divididas em dois grandes o objetivo com o menor número de passos possı́vel. A sua
cenários: a busca às cegas e a busca heurı́stica. intuição heurı́stica é de que o número de passos para atingir
1) Busca às Cegas: A busca às cegas tem esse nome pois um objetivo é inversamente proporcional ao tamanho desses
ela não leva em consideração informações especı́ficas sobre o passos. Ele SEMPRE encontra uma solução, com custo baixo
problema que está resolvendo. Ela tem dois tipos principais, e tentando percorrer o menor número de nodos possı́vel. Ele
que são a pesquisa em largura e a pesquisa em profundidade. é dividido em duas variações: a subida de encosta simples e
a subida de encosta pela trilha mais ı́ngreme. A primeira vai a) Implementação da Busca em Largura: Para a resolução
examinando os sucessores do atual estado e prossegue para o do problema foram utilizadas 3 bibliotecas: a stl list, para
primeiro estado maior que o atual. A subida de encosta pela implementação das funções de listas - que será a estrutura
trilha mais ı́ngreme examina todos os sucessores do atual estado principal do programa. Outra é uma lista de adjacência que
e escolhe para onde prosseguir com base em qual é o mais representará o grafo, além da queue que será utilizada para
próximo da solução. implementar a fila que dará a ordem de leitura, e por fim a
b) Busca ”O melhor primeiro” (BestFirst): O método ”o iostream, que é a biblioteca com funções padrões do C++.
melhor primeiro” combina os melhores pontos da busca em
largura com os melhores pontos da busca em profundidade. Ele
procura otimizar a solução considerando todas as informações
disponı́veis naquele instante, não somente da última expansão.
Todos os estados abertos até esse instante são candidatos a
serem expandidos. Apesar de sempre encontrar uma solução,
pode não ser o método mais rápido de utilização. Seu custo é
relativamente baixo, porém seu número de nodos explorados é
imprevisı́vel - podendo ser muito alto ou muito baixo.
c) Busca ”Têmpera Simulada”: A estratégia ”têmpera
simulada*” é adequada em problemas em que a subida de
encosta encontra demasiados paltôs e locais máximos. Por não
utilizar backtracking, não garante que a solução encontrada
seja a mais assertiva possı́vel. Tem esse nome pois se inspira
no processo de têmpera do aço - no qual as temperaturas são
gradativamente abaixadas até que a estrutura molecular se torne
uniforme o suficiente. O que esse método faz é atribuir uma
”energia” inicial ao processo de busca, o que permite que além Fig. 2. Grafo criado para a Busca em Largura.
de subir encostas, ele também seja capaz de descer encostas e
percorrer platôs se houver energia suficiente. Essa energia decai
ao longo do tempo, fazendo com que o processo se estabilize
em algum máximo que tem maior chance de ser solução do
problema.

B. Aplicação dos métodos de busca


Definidos os métodos de busca, serão apresentadas duas
implementações em C++ - uma sendo com o método da busca
em largura e outra no método de busca ”best-first”. O problema
que será utilizado de exemplo é o das peças pretas e brancas
- que possui o objetivo de ordenar essas peças a partir de um
estado inicial. Para a solução do problema, é necessário que as
duas fichas pretas estejam entre as duas fichas brancas.
Fig. 3. Saı́da do código fonte apresentado.

Foi criada uma classe Graph, instanciada uma variável do


tipo inteiro, que representa a quantidade de vértices e uma
lista de ponteiros de inteiros ”adj”. Dentro da classe Graph,
foram instanciadas algumas funções. A função ”Graph(int V)”
(construtor) tem a finalidade de criar uma lista de adjacentes; a
função ”void addEdge(int v1, int v2)” tem a função de adicionar
um valor v2 na aresta de posição v1 - ou seja, ligar v1 a v2;
e a função string State(int c), que retorna a posição das fichas
pretas e brancas na posição de análise, relacionando os grafos
II-B0a, II-B.
A busca de fato é executa na função ”void widthSearch(int
v)”. Essa função recebe a quantidade de vértices do grafo, e ,
Fig. 1. Espaço de Estados do Problema das Fichas Pretas e Brancas [1]. nela, será criada uma fila de inteiros - então ela começará uma
busca em largura e irá verificar se o elemento em análise já
foi visitado. Se sim, ela sairá do laço while. Caso o vértice em serão visitados primeiro, até chegar na meta e encerrar o
análise seja igual a meta, o programa sairá do laço e com isso programa.
finalizará a busca.
A saı́da do código está representada na Figura II-B0a, e,
como previsto, ela percorre todo o grafo de forma longitudinal,
assim até que chegue na meta e encerre o programa.
b) Implementação da Busca ”Best-First”: Nesta
implementação, não é permitido que seja feita da mesma
forma da busca em largura, pois este método conta com
análise de custos - ou seja, é necessário montar uma estrutura
que nos possibilite inserir pesos nas arestas. Sob esse prisma,
o algoritmo construı́do conta com um vector de um ’container Fig. 5. Saı́da do código fonte apresentado.
pair’, que agrupa dois inteiros - sendo um a posição do estado
no grafo e o outro o custo da aresta que liga esta posição a c) Comparação entre o item ’a’ e ’b’: Analisando os dois
outra. métodos paralelamente, é possı́vel concluir que o desempenho
Similar à implementação da busca em largura, temos uma individual pode ser avaliado a partir de diferentes propriedades,
função void ”addEdge(int x, int y, int custo)”, que liga x como otimalidade e completude.
a y, efetuando assim a ligação entre estes e armazenando o Se tratando de otimalidade, a busca em largura é consid-
custo nesta ligação. A função ”string State(int c)” também está erada ótima, pois encontra uma solução de menor custo. A
presente, efetuando a mesma função descrita anteriormente. busca ”Best First” empata, pois apresenta apenas uma solução
possı́vel, e ainda é a primeira a ser encontrada.
Por fim, a busca é feita na função ”void searchBF(int
Se tratando de completude, ambos são completos. A busca
reference, string goal, int n)”, onde é passada a posição de
em largura pois o nó meta mais raso está na profundidade d,
referência, a solução do problema (meta) e o número de vértices
enquanto a busca BF sempre encontra a meta a partir dos pesos
do grafo. De maneira análoga ao método anterior, criamos um
individuais dos ramos.
vector<bool> visited, que armazena se uma posição foi ou
Dessa forma, considerando os dois métodos, para o problema
não visitada. Porém, criamos uma lista de prioridade ”prior-
das fichas pretas e brancas, conclui-se que utilizar o método
ity queue<pi, vector<pi>, greater<pi> > pq” que ordena de
heurı́stico best-first é melhor, por apresentar as mesmas car-
forma crescente os custos das arestas (”second” do pair). Dessa
acterı́sticas do método de busca em largura, porem com uma
forma, a ordem de busca será sempre do menor para o maior
complexidade de tempo e espaço mais efetivo.
custo. A criação da fila fica no laço for da função, que rotaciona
Por fim, colocando os dois métodos lado a lado, podemos
todo o grafo, verificando se uma posição já foi visitada, e a
concluir que, para o problema das fichas brancas e pretas, o
inclui na fila de prioridade.
método de busca heurı́stica ”Best First” é melhor. Isso pois
apresenta caracterı́sticas muito semelhantes à busca em largura,
porém com uma complexidade mais efetiva (tempo e custo).
C. Programação Dinâmica
O método de programação dinâmica (PD) consiste em uma
forma de resolver problemas recursivos de uma maneira mais
inteligente. Assim como na recursividade, o PD instancia o
problema final em inúmeras subinstâncias, que serão resolvidas
de forma simplificada, a fim de solucionar o problema final.
Contudo, o algoritimo recursivo acaba sendo redundante e
ineficiente, visto que em várias situações a recursividade acaba
refazendo um mesmo cálculo inúmeras vezes.
Já através da utilização da programação dinâmica, o resultado
de cada subinstância já solucionada é armazenado na memória,
de forma que a cada nova subinstância gerada, seja possı́vel
recuperar os valores anteriormente calculados, a fim de reduzir
o tempo de processamento para a solução final do problema.
Fig. 4. Grafo utilizado na Busca Best-First Usando como exemplo clássico para a utilização de recur-
sividade, temos a sequência de Fibonacci: 0, 1, 1, 2, 3, 5,
Para efetuarmos a implementação, criamos o grafo ponder- 8, 13, 21, 34, 55... Onde o próximo número da sequência
ado de forma arbitrária, apresentado na figura II-B0b.A saı́da é escrito pelos dois anteriores, ou, matematicamente falando,
da aplicação em questão está representada na Figura II-B0b, e F [n] = F [n − 1] + F [n − 2], sendo F [0] = 0 e F [1] = 1, com
como previsto, ela percorre de forma que os menores custos n a partir de 2.
Sendo resolvido de forma recursiva, terı́amos um programa com precisão que exista um metodo infalı́vel para qualquer
rodando ”de cima para baixo” da seguinte forma: tipo de situação, visto que, assim como foi mostrado, dois
metodos distintos podem percorrer um grafo e encontrar a
mesma solução com mais ou menos passos em um determinado
problema, mas em outro caso, este mesmo resultado pode se
inverter. Assim sendo, conclui-se que é necessário analizar a
utilização de cada metodo de busca separadamente em cada
caso distinto, utilizando o custo operacional, custo de memoria
e a complexidade da estrutura em questão como parâmetros
Fig. 6. Programação recursiva da sequência fibonacci
para determinar o melhor método de busca para aquela sitação
expecı́fica.
Este problema, porém, se torna demasiadamente demorado [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [5]
e ineficiente, visto que a cada instância recursiva de um F [n],
todos os valores anteriores são novamente recalculados, como
é possivel ver na figura abaixo:

Fig. 7. Representação de resultados para sequência fibonnaci de n = 5

O uso da PD consiste em, através deste mesmo exemplo,


armazenar cada valor de F[n] já calculado em uma tabela de
busca F [0...n], de forma que no fim tem-se uma estrutura de
programação efetuada da sequinte forma:

Fig. 8. Programação dinâmica da sequência Fibonacci

Enquanto o algoritmo recursivo resolveria a sequência Fi-


bonacci em um custo operacional O(1.5n ), a PD resolveria o
mesmo problema em apénas O(n). A desvantagem, porém, é
que quanto maior for a complexidade da solução necessária
para o problema, maior também será a quantidade de memória
requerida pelo sistema.
III. C ONCLUS ÃO
Conforme é possivel analizar através deste trabalho, existem
vários metodos de buscas que podem ser utilizados em diversos
tipos de problemas distintos. Contudo, não é possivel afirmar
R EFERENCES http://jeiks.net/wp-content/uploads/2013/05/Metodosd eB usca.pdf, 2016.
Data de acesso : 09 de maio, 2022.
[1] Sandro Carvalho Isidoro. Prolog, 2021.
Data de acesso: 04 de maio, 2022. [7] Sandra Maria Aluı́sio. Problema do jogo das oito fichas fazendo uso da busca
[2] Eduardo Hruschka. Aula 2: Resolução de Problemas Via Busca. bidirecional. https://sites.icmc.usp.br/sandra/G5t 2/8P uzzle.htm, 1999.
http://wiki.icmc.usp.br/images/1/11/Aula2 Busca.pdf, 2014. Data de acesso : 09 de maio, 2022.
Data de acesso: 03 de maio, 2022. [8] Jose Augusto Baranauskas. Estratégia de busca.
[3] Derpartment of Electrical Engineering and Computer Science. Artificial https://dcm.ffclrp.usp.br/ augusto/teaching/ia/IA-Estrategias-Busca.pdf, 2006.
intelligence. http://www.ai.mit.edu/courses/6.034b/searchcomplex.pdf, Data de acesso: 05 de maio, 2022.
2003. [9] Victor Matheus R. de Carvalho. Programação dinâmica. https://lamfo-
Data de acesso: 03 de maio, 2022. unb.github.io/2019/05/30/Programacao-Dinamica/, 2019.
[4] Fernando Gomide. Estruturas e estratégias Data de acesso: 06 de maio, 2022.
de busca. https://www.dca.fee.unicamp.br/ go-
mide/courses/EA072/transp/EA072EstruturasEstrategiasBusca4.pdf, [10] Paulo Feofiloff. Programação dinâmica.
2018. https://www.ime.usp.br/ pf/analised ea lgoritmos/aulas/dynamic −
Data de acesso: 08 de maio, 2022. programming.html, 2020.
[5] Eduardo Hruschka. Busca informada. Data de acesso : 07 de maio, 2022.
http://wiki.icmc.usp.br/images/3/32/Aula3B uscaInf ormada.pdf, 2014. [11] Sandra Maria Aluı́sio. Busca uniforme.
Data de acesso : 04 de maio, 2022. https://sites.icmc.usp.br/sandra/G2t 2/Busca.html, 2006.
[6] Jackson Rodrigues. Inteligência artificial - métodos de busca. Data de acesso : 10demaio, 2022.

Você também pode gostar