Sunteți pe pagina 1din 28

[Digite texto] Inteligência Computacional I 1

Tecnologia em Análise e Desenvolvimento de Sistemas

1
Introdução à Inteligência Artificial

1.1. Definição

Inteligência é uma palavra de definição polêmica. Antes avaliada pelo raciocínio lógico, hoje
em dia há muitas discussões sobre a existência de diversos tipos de inteligência. Se definir inteligência
natural já é algo complicado, o que se pode falar sobre um tipo de inteligência introduzida em uma
máquina pelo homem?
Há muitas definições de Inteligência Artificial, dependendo do ponto de vista utilizado. Pode-
se dizer que a Inteligência Artificial é uma área da Ciência da Computação que procura utilizar
processos inteligentes em computadores visando torná-los mais úteis. Entendem-se como processos
inteligentes aqueles que estão presentes em nosso aprendizado, raciocínio, comunicação, adaptação,
tomada de decisão, dentre outros.
Para tornar a questão ainda mais conturbada, a caracterização da Inteligência Artificial como
uma área da Ciência da Computação é contestada por alguns cientistas. Estes repudiam até mesmo a
palavra artificial. O cientista Aaron Sloman, por exemplo, defende o nome Ciência da Inteligência,
sendo esta interessada em como os sistemas artificiais e os organismos vivos adquirem, manipulam,
armazenam, utilizam e transmitem informações, além de descobrir os mecanismos dos desejos e dos
sentimentos.
Apesar de ser uma área recente, a Inteligência Artificial herdou muitas ideias e técnicas de
outras disciplinas tais como a Filosofia (teorias sobre aprendizado e raciocínio, a concepção da mente
como um sistema físico), a Matemática (lógica, probabilidade, teoria da decisão), a Ciência da
Computação (ferramentas para a implementação das técnicas de Inteligência Artificial), a Psicologia
(teorias de funcionamento do cérebro, teorias cognitivas) e a Linguística (teorias sobre a aquisição da
linguagem e seu significado). Como não poderia ser diferente, o enfoque deste texto será sempre nos
aspectos computacionais da Inteligência Artificial. Não haverá juízos definitivos a respeito dos
objetivos e da abrangência da disciplina.

1.2. Breve histórico

A história poderia ser contada a partir de, aproximadamente, 3000 aC quando foi elaborado o
primeiro conjunto de regras para diagnósticos de doenças, mas isto ficará para um outro texto. Os
primeiros trabalhos em Inteligência Artificial foram publicados antes mesmo dela ser batizada. Em
1943, pouco tempo depois da invenção do computador, Warren McCulloch e Walter Pitts propuseram
um modelo de neurônio artificial e mostraram que certos procedimentos computacionais poderiam ser
realizados por redes interconectadas desses neurônios, sendo chamadas de redes neurais artificiais.
Seis anos mais tarde Donald Hebb apresentaria a primeira técnica de aprendizado para os neurônios
artificiais.

Rogério Espíndola esqueca.me@gmail.com 2002-2010


[Digite texto] Inteligência Computacional I 2
Tecnologia em Análise e Desenvolvimento de Sistemas

No início dos anos 50, Claude Shannon e Alan Turing desenvolveram os primeiros programas
capazes de jogar xadrez. Nesta época, Marvin Minsky e Dean Edmonds desenvolveram o primeiro
computador baseado em redes neurais artificiais. Além disso, a primeira linguagem voltada para
Inteligência Artificial, a IPL-11, foi criada por Alan Newell, J. Shawn e Herbert Simon.
Em 1956, ano de criação do Fortran pela IBM, durante uma conferência em Dartmouth, o
termo Inteligência Artificial foi cunhado por John McCarthy. Neste evento, Newell, Shawn e Simon
apresentaram um programa que realizava demonstração de teoremas chamado Logic Theorist. No ano
seguinte, estes três cientistas criaram um programa que simulava a maneira humana de resolver
problemas, o General Problem Solver. Em 1958, McCarthy criou o Lisp, a segunda linguagem mais
antiga ainda em uso. A mais antiga é o Fortran. Um ano depois, a linguagem Cobol surgiu.
Pouco tempo depois, Hans-Paul Schwefel, Ingo Rechenberg e Lawrence Fogel apresentaram
os primeiros trabalhos que empregam a teoria da evolução de Darwin como um processo adaptativo de
otimização, ou seja, aplica simulações computacionais de mecanismos evolutivos em uma população
de estruturas de dados visando melhorar o seu desempenho. Com estes trabalhos, deram início à
computação evolucionária. Em 1965, Lofti Zadeh apresentou a lógica fuzzy (em português, difusa ou
nebulosa), que foi desenvolvida para superar diversos obstáculos que surgiam ao se aplicar a lógica
tradicional e a teoria dos conjuntos clássicos em problemas reais.
Ainda na década de 60, muito se falou que em pouco tempo seriam criadas máquinas capazes
de aprender, pensar e criar. Havia um grande otimismo em relação ao desenvolvimento de máquinas
inteligentes, mas a limitação tecnológica de hardware, a dificuldade de se lidar com problemas mais
complexos e de representar o conhecimento fizeram com que os recursos aplicados ao
desenvolvimento da Inteligência Artificial fossem bastante reduzidos.
Durante o final desta década e início da seguinte foram desenvolvidos os primeiros sistemas
destinados exclusivamente para realizar tarefas que eram executadas por especialistas humanos, os
chamados sistemas especialistas, sendo aplicados em diversas áreas, principalmente em medicina. A
linguagem Prolog também surgiu nesta época por intermédio de Robert Kowalski, Marteen van
Emden e Alain Colmerauer. Em 1975, John Holland apresenta os algoritmos genéticos, técnica que
constitui um ramo da computação evolucionária.
Na década de 80, os resultados obtidos das pesquisas em Inteligência Artificial passaram a ser
utilizados mais frequentemente na indústria, seja por motivos de redução de custos, seja por inovações
tecnológicas incorporadas aos produtos. O Japão dá início ao seu projeto de criação dos chamados
sistemas computacionais de quinta geração utilizando a lógica como linguagem de programação.
Houve também o ressurgimento do interesse da comunidade científica pelas redes neurais artificiais
com o trabalho de John Hopfield e Teuvo Kohonen.
Desde o final dos anos 80 ocorre um grande desenvolvimento de uma área interdisciplinar
chamada de descoberta de conhecimento em bases de dados – knowledge discovery in databases em
inglês ou simplesmente KDD –, cujo principal objetivo é extrair informações, normalmente
desconhecidas e/ou implícitas, a partir de bases de dados fazendo uso de diversas técnicas de
Inteligência Artificial, além de técnicas estatísticas e de visualização de dados. A apresentação deste
conhecimento descoberto em uma forma compreensível ao homem também ocupa papel de destaque
em KDD.

Rogério Espíndola esqueca.me@gmail.com 2002-2010


[Digite texto] Inteligência Computacional I 3
Tecnologia em Análise e Desenvolvimento de Sistemas

1.3. Aplicações e áreas de pesquisa

São inúmeras as aplicações da Inteligência Artificial. A listagem a seguir exibe algumas das
mais relevantes:

• escalonamento automático de tarefas;


• sistemas inteligentes para aprendizado;
• reconhecimento de voz, da face e de impressões digitais;
• transformação da fala em texto escrito;
• tradutores de texto;
• controle de dispositivos eletro-eletrônicos;
• previsão de eventos meteorológicos e de situações do mercado financeiro;
• investimentos automáticos no mercado financeiro;
• diagnósticos de falhas em equipamentos e de doenças;
• detecção de invasões em sistemas computacionais e de fraudes;
• aprovação de propostas de cartão de crédito;
• descoberta e caracterização de poços petrolíferos;
• descoberta de informações em bases de dados;
• condução automática de veículos;
• filtros para correio eletrônico;
• sistemas de busca de informações na Internet;
• jogos.

Esta listagem poderia continuar citando inúmeras outras aplicações, mas este não é o objetivo.
O mais importante nesta listagem é a exibição da relevância prática da Inteligência Artificial. Muitos
ainda associam Inteligência Artificial apenas a jogos, robôs e cientistas pouco normais, havendo então
a questão de definir a normalidade. Uma tarefa é deixada para o leitor: descubra em que área surgiram
a técnica de tempo compartilhado para os sistemas operacionais multitarefa e a estrutura de dados
chamada lista encadeada. Exibidas as aplicações, algumas das áreas de pesquisa em Inteligência
Artificial são:

• programação automática;
• processamento de linguagem natural;
• aquisição e representação do conhecimento;
• descoberta de conhecimento em bancos de dados;
• planejamento;
• aprendizado de máquina;
• prova automática de teoremas;
• controle de equipamentos;
• visão computacional;
• busca por soluções de problemas.

Rogério Espíndola esqueca.me@gmail.com 2002-2010


[Digite texto] Inteligência Computacional I 4
Tecnologia em Análise e Desenvolvimento de Sistemas

2
A resolução de problemas

2.1. Introdução

Qualquer tarefa computacional pode ser vista como um problema a ser resolvido. Entretanto, o
que aqui é considerado como resolução de problemas é uma tarefa que exige atividades inteligentes,
por exemplo, a identificação e a representação do problema e a aplicação de procedimentos que levem
a alguma solução.
Em Inteligência Artificial, grande parte dos métodos de resolução de problemas procuram uma
solução em um conjunto de possíveis soluções. Esta procura por soluções caracteriza os chamados
problemas de busca. Os métodos que abordam este tipo de problema são os métodos de busca.
Antes que o processo de busca por soluções seja iniciado, é necessário representar o problema
de modo adequado. Para um mesmo problema, diversas representações podem ser definidas. O modelo
de representação que será aqui exibido é o utilizado nos chamados sistemas de produção, exibido a
seguir.

2.2. Sistemas de Produção

Um sistema de produção é um programa composto por um conjunto de possíveis soluções,


uma lista ordenada de regras e um procedimento de controle.
As possíveis soluções são chamadas de estados e o seu conjunto de espaço de estados ou
base de estados ou espaço de busca. A representação dos estados leva em consideração todas as
variáveis relevantes para o problema. Uma possível solução não é a resposta para o problema, mas sim
uma configuração permitida para as suas variáveis. Assim, os estados representam as diversas
configurações que um problema pode assumir (Figura 1). Podem ser implementados como vetores,
matrizes, árvores, listas ou até mesmo como um banco de dados. Dois tipos de estados possuem papéis
especiais que são o estado inicial e o estado final (uma solução para o problema).

possíveis soluções ou estados

soluções impossíveis espaço de busca

Figura 1. Representação simples de uma base de estados

Rogério Espíndola esqueca.me@gmail.com 2002-2010


[Digite texto] Inteligência Computacional I 5
Tecnologia em Análise e Desenvolvimento de Sistemas

As regras de um sistema de produção são chamadas de regras de produção ou operadores e


possuem o seguinte formato:

Regra 1: Se condições_1, então ações_1. R1: c1→a1


...
Regra i: Se condições_i, então ações_i. Ri: ci→ai
...
Regra n: Se condições_n, então ações_n. Rn: cn→an

Cada regra representa uma ação que pode ser executada. Para determinar se uma regra será
aplicada é necessário que se verifique se o estado atual do problema satisfaz às suas condições. Caso
isto ocorra, as ações por ela definidas são efetuadas e o estado atual é transformado em um outro
estado, que pode ser novo ou não. Caso as condições não sejam satisfeitas, uma outra regra é avaliada
até que alguma ação seja executada. Os novos estados obtidos são colocados à disposição do sistema
de produção até que seja gerada uma solução final. Assim, a resolução de um problema constitui-se na
aplicação sucessiva de regras que transformam estados em outros até que se encontre um estado final
(Figura 2).
Além de determinar a regra a ser aplicada a cada momento, o sistema de controle identifica
quando parar o processo. Isto ocorre quando:

• não há suficientes recursos computacionais (por exemplo, pouca memória disponível);


• conclui-se que é impossível ser obtida uma solução para o problema;
• atinge-se um limite arbitrário definido pelo pesquisador (por exemplo, o tempo de
processamento);
• encontra-se uma solução satisfatória para um problema.

Rj Ri Rk
Estado Estado ... Estado
inicial 1 final

Figura 2. A obtenção dos estados de um problema pelas regras de produção

Ao se resolver um problema, também é interessante identificar de que modo se obteve a


solução por meio da sequência de regras aplicadas. Pode-se também desejar que esta sequência seja a
menor possível, caracterizando uma busca pela melhor das soluções. A qualidade de uma solução
também pode ser avaliada por meio do seu custo de obtenção.
Uma maneira bastante útil de representar os sistemas de produção é através do grafo de
estados. Nele, um nó representa um estado e um arco representa a regra cuja aplicação leva um estado
a outro. A Figura 2 apresenta um simples exemplo de grafo de estados e a Figura 3 exibe um exemplo
mais genérico. Para se resolver um problema deve-se percorrer o seu grafo de estados até que seja
obtida uma solução. As estratégias para realizar este procedimento constituem os métodos de busca,
descritos a seguir.

Rogério Espíndola esqueca.me@gmail.com 2002-2010


[Digite texto] Inteligência Computacional I 6
Tecnologia em Análise e Desenvolvimento de Sistemas

Re Rd
E2 E4 E6
Rb E0: estado inicial
Ra Ra
Rc Rc E1...E6: estados
Rb
Ra intermediários
E0 E7
Rc E7: estado final
Rd Re
Ra Rd
Ra...Re: regras
E1 Rb Rc
E3 E5
Figura 3. Exemplo de um grafo de estados

2.3. Métodos de busca

De modo simplificado, os métodos ou estratégias de busca podem ser vistos como receitas de
como realizar as escolhas das ações durante a busca por soluções.
A medida que um método de busca progride examinando um grafo de estados, um outro grafo
de estados é gerado. Chamado de árvore de busca (Figura 4), este grafo possui o estado inicial como
o nó raiz. A aplicação dos operadores a um estado produz os seus nós filhos, sendo ele chamado de nó
pai. Observe que o nó raiz é o único que não possui um nó pai. Nós que não possuem filhos são
chamados de nós folhas. O caminho do nó raiz a um nó folha é chamado de ramo.
Um conceito importante em árvores é o de profundidade. A profundidade de um nó é igual a
quantidade de nós existentes do nó raiz, exclusive, até ele. Dessa forma, o nó raiz possui profundidade
igual a zero, seus filhos profundidade igual a um, os filhos desses profundidade igual a dois e assim
por diante (Figura 4). Como será visto mais tarde, para alguns métodos de busca a profundidade está
diretamente ligada à qualidade de uma solução. Em algumas situações neste texto, a palavra nível
também será usada como sinônimo de profundidade.

nó raiz
profundidade = 0

profundidade = 1
nó folha

profundidade = 2
nó folha nó folha

profundidade = 3
nós folhas nós folhas

Figura 4. Uma árvore-exemplo com profundidade igual a 3.

Rogério Espíndola esqueca.me@gmail.com 2002-2010


[Digite texto] Inteligência Computacional I 7
Tecnologia em Análise e Desenvolvimento de Sistemas

Durante a construção da árvore de busca, o processo de geração dos nós filhos de um


determinado nó é chamado de expansão deste nó. Assim, um nó pode ser caracterizado como:

• a abrir: um nó que ainda não foi gerado;


• aberto ou a expandir: se nenhum de seus nós filhos foi gerado;
• explorado: se algum de seus nós filhos foi gerado;
• fechado ou expandido: se todos os seus nós filhos foram gerados.

As estratégias de busca podem ser classificadas como:

a) desinformadas ou cegas: não utilizam informações sobre o quão distante um determinado


nó está da solução do problema, sendo capaz apenas de identificar se ele é a solução ou
não;
b) informadas ou heurísticas ou guiadas ou direcionadas: utilizam informações sobre o
domínio do problema e sobre as soluções desejadas de modo a guiar a busca na direção de
regiões mais promissoras do espaço de estados.

Além disso, as estratégias de busca podem ser caracterizadas como:

a) completas: se são capazes de explorar todo o espaço de busca;


b) ótimas: se sempre encontram a melhor solução possível.

Nas seções seguintes serão apresentados diversos métodos informados ou não. Entretanto,
todos seguem aproximadamente o algoritmo apresentado na Figura 5. Algo que precisa estar bem
esclarecido é que um nó não é equivalente a um estado. Além do estado que ele representa, um nó
deve armazenar diversas informações importantes para o método de busca tais como a sua
profundidade, quem é o seu nó pai, o operador que o gerou e o seu custo quando for necessário. Outras
informações que sejam julgadas importantes também podem ser adicionadas a esta lista.

resposta = nulo
lista-de-abertos = estado inicial
sucesso = falso
enquanto (sucesso = falso) e (lista-de-abertos ≠ vazio) faça
nó-candidato = algum nó de lista-de-abertos
se nó-candidato é a solução
então
sucesso = verdadeiro
resposta = nó-candidato
senão
expandir o nó-candidato
coloque o(s) nó(s) gerado(s) em lista-de-abertos
fim-se
fim-enquanto
retorna sucesso e reposta

Figura 5. Algoritmo básico para os métodos de busca.

Rogério Espíndola esqueca.me@gmail.com 2002-2010


[Digite texto] Inteligência Computacional I 8
Tecnologia em Análise e Desenvolvimento de Sistemas

3
Buscas desinformadas

3.1. Introdução

As técnicas de busca desinformadas são as mais simples pois não utilizam informações
específicas de um problema. Há o método irrevogável, que não retorna a situações anteriores, e os
revogáveis que podem retornar a elas caso seja conveniente. A seguir, dois problemas clássicos em
inteligência artificial são apresentados. Embora bastante simples, eles são muito úteis para ilustrar o
comportamento de cada método na busca por soluções.

A. Problema do labirinto

Dado um labirinto qualquer como o da figura abaixo, encontrar um caminho entre a entrada e
a saída.

A E I N Entrada: A Saída: S

Regras:
B F J O R
Regra 1: ↓ Regra 2: ←
C G L P S Regra 3: ↑ Regra 4: →

Estratégia:
D H M Q
As regras são aplicadas na ordem acima

B. Problema dos jarros de água

Existem dois jarros inicialmente vazios. Um possui capacidade igual a 3 litros e o outro igual a
4 litros. Ambos podem ser enchidos completamente utilizando uma torneira e podem também ser
esvaziados, despejando a água em um ralo. Além disso, a água presente em um jarro pode ser passada
para o outro. Os jarros não possuem marcações e não é permitido o uso de qualquer instrumento de
medida. Deseja-se colocar exatamente dois litros de água no jarro maior.
Pode-se representar as quantidades de água presentes nos dois jarros pelo par ordenado (x,y),
em que x é a quantidade de água no jarro menor e y a quantidade no jarro maior. Então, o estado
inicial (ambos vazios) é o par (0,0) e o objetivo é encontrar um par do tipo (x,2), isto é, dois litros no
jarro maior e qualquer quantidade no jarro menor. As regras que definem as ações permitidas são
exibidas a seguir, observando que a estratégia de aplicação das mesmas é a ordem de apresentação:

Rogério Espíndola esqueca.me@gmail.com 2002-2010


[Digite texto] Inteligência Computacional I 9
Tecnologia em Análise e Desenvolvimento de Sistemas

R1: Se x < 3, então (3,y). // regra para encher o jarro menor


R2: Se y < 4, então (x,4). // regra para encher o jarro maior
R3: Se x > 0, então (0,y). // regra para esvaziar o jarro menor
R4: Se y > 0, então (x,0). // regra para esvaziar o jarro maior
R5: Se y > 0 e x+y ≤ 3, então (x+y,0). // regra para passar toda a água do jarro maior para o menor
R6: Se y > 0 e x+y > 3, então (3,y – (3–x)). // regra para passar parte do maior para o menor
R7: Se x > 0 e x+y ≤ 4, então (0,x+y). // regra para passar toda a água do jarro menor para o maior
R8: Se x > 0 e x+y > 4, então (x – (4–y),4). // regra para passar parte do menor para o maior

3.2. Método irrevogável

A partir do nó raiz os operadores são aplicados sucessivamente segundo a estratégia definida


até que a solução seja encontrada ou quando o método não pode mais continuar. Repetições de nós já
existentes são desconsideradas. A Figura 6 apresenta o algoritmo do método.
Além de não garantir que alguma solução será encontrada, o método irrevogável também não
garante que, caso a encontre, ela seja a melhor possível, isto é, que ela tenha sido obtida com a menor
quantidade de aplicações de operadores. Então, o método irrevogável não é completo nem ótimo.
Observe que uma menor quantidade de regras aplicadas ocasiona menor quantidade de nós gerados e
menor utilização dos recursos computacionais (tempo de processamento, memória etc.).
Respectivamente, a Figura 7 ilustra a aplicação do método nos dois problemas-exemplos.
Como pode ser visto, no problema do labirinto o método não encontra uma solução, mas encontra uma
no outro problema, quando foi gerada uma árvore com 9 nós. O valor dentro de um nó indica a sua
ordem de geração.

resposta = nulo
nó-candidato = estado inicial
sucesso = falso
continua =sim
enquanto (sucesso = falso) e (continua = sim) faça
se nó-candidato é a solução
então
sucesso = verdadeiro
resposta = nó-candidato
senão
se existe regra que gere um novo nó-candidato
então nó-candidato = novo nó-candidato
senão continua = não
fim-se
fim-se
fim-enquanto
retorna sucesso e reposta

Figura 6. Algoritmo básico do método irrevogável

Rogério Espíndola esqueca.me@gmail.com 2002-2010


[Digite texto] Inteligência Computacional I 10
Tecnologia em Análise e Desenvolvimento de Sistemas

A (0,0) (0,1) 5 6 (1,0)


R5
R1 R1 R3 R2
B 1 (3,0) 1 (3,1) 4 7 (1,4)
R1 R2 R6 R6
R3
C 2 (3,4) 2 3 (0,4) 8 (3,2)

(a) (b)

Figura 7. Árvores obtidas pelo método irrevogável nos problemas-exemplos

3.3. Métodos revogáveis

3.3.1. Busca em profundidade

A busca em profundidade se caracteriza por priorizar os nós em níveis mais profundos da


árvore. Inicialmente, o método expande o nó raiz, isto é, gera todos os seus filhos. Se um desses filhos
for a solução do problema, então o método é interrompido. Caso nenhum deles seja a solução, um
deles é escolhido segundo algum critério para ser expandido e seus filhos são testados para saber se
algum representa a solução. Em geral, este critério seleciona o nó que está em maior profundidade e
mais à esquerda na árvore de busca.
O processo continua até que alguma solução seja encontrada ou um nó selecionado para a
expansão não possua filhos (nó folha). Neste caso, os irmãos deste nó folha são verificados até que se
encontre um em que a busca possa continuar em níveis mais profundos, isto é, até se obter um nó que
possa ser expandido. Se todos os irmãos também forem nós folhas, o método retorna ao nível anterior
da árvore e passa a avaliar os irmãos do nó expandido deste nível, repetindo-se todo o procedimento.
A Figura 8 ilustra o comportamento da busca em profundidade em uma árvore-exemplo. A
numeração ao lado dos nós indica a ordem de geração dos mesmos.

2 3 4

5 6 9 10

7 8 11 12

Figura 8. Ordem de geração dos nós de uma árvore-exemplo durante a busca em profundidade

Rogério Espíndola esqueca.me@gmail.com 2002-2010


[Digite texto] Inteligência Computacional I 11
Tecnologia em Análise e Desenvolvimento de Sistemas

A Figura 9 apresenta o seu algoritmo. A Figura 10 mostra as árvores obtidas nos problemas-
exemplo, observando-se que o valor dentro de um nó indica a sua ordem de geração.

resposta = nulo
pilha-de-abertos = estado inicial
lista-de-fechados = nulo
sucesso = falso
enquanto (sucesso = falso) e (pilha-de-abertos ≠ vazio) faça
nó-candidato = elemento do topo da pilha-de-abertos
remova o elemento do topo da pilha-de-abertos
coloque-o em lista-de-fechados
expanda nó-candidato
se algum filho de nó-candidato é a solução
então
sucesso = verdadeiro
resposta = filho-solução de nó-candidato
senão
coloque o(s) nó(s) filho(s) no topo de pilha-de-abertos
fim-se
fim-enquanto
retorna sucesso e reposta

Figura 9. Algoritmo básico da busca em profundidade

A (0,0)
R1 R4 R1 R2
B 1 2 E (3,0) 1 2 (0,4)
R1 R4 R2 R7
C 3 4 F (3,4) 3 4 (0,3)
R1
R1
5 G
5 (3,3)
R1 R4
R8
H 6 7 L
6 (2,4)
R2 R1
M R4
D 8 9
7 (2,0)
R4
R7
10 Q
(a) 8 (0,2)
R3
11 P
R3 R4 (b)

O 12 13 S

Figura 10. Árvores obtidas pela busca em profundidade nos problemas-exemplos

Rogério Espíndola esqueca.me@gmail.com 2002-2010


[Digite texto] Inteligência Computacional I 12
Tecnologia em Análise e Desenvolvimento de Sistemas

Existem casos em que a árvore de busca possui profundidade infinita e, então, a busca em
profundidade pode continuar a testar os nós mais profundos de um ramo que não contenha alguma
solução e ser incapaz de retornar e testar outros ramos. Assim, ela não é uma busca completa.
Por isso, muitas implementações deste método incorporam o conceito de limite de
profundidade, sendo chamadas de busca em profundidade limitada. Deste modo, a árvore não é
explorada além deste limite pré-estabelecido e a busca retorna a níveis anteriores quando um nó é
identificado como folha ou quando o limite de profundidade foi alcançado. É necessário ter muito
cuidado na determinação deste limite para evitar que somente haja soluções em profundidades maiores
que ele. Em árvores finitas, a busca em profundidade é sempre capaz de encontrar alguma solução, se
esta existir, mas não garante que ela seja a melhor. Portanto, não é uma técnica ótima.

3.3.2. Backtracking

O método de backtracking é uma versão especial da busca em profundidade em que apenas


um filho é gerado por vez. Ele tenta encontrar uma solução gerando um ramo da árvore de busca. Caso
este ramo não contenha uma solução, um segundo ramo é gerado. Se este também não possuir uma
solução, um outro é gerado e assim o processo continua até que a solução seja encontrada, se esta
existir.
Mais detalhadamente, a partir do nó raiz um operador selecionado segundo a estratégia
definida produz um nó filho. Se ele for a solução o processo é interrompido. Caso não seja, um filho
para este nó também é produzido e avaliado, repetindo-se o procedimento de geração e avaliação de
nós até que a solução seja encontrada ou quando o método não pode mais continuar.
Quando isto ocorre, a busca produziu um nó folha. Então, ela retorna um nível na árvore – isto
é, retorna ao nó pai do nó folha em questão – e tenta gerar um novo nó filho aplicando outro operador.
Se obtiver êxito nesta tarefa, a busca prossegue normalmente aplicando as regras segundo a estratégia
estipulada. Entretanto, se não for possível gerar algum filho com qualquer uma das regras do
problema, a busca retorna mais um nível na árvore e tenta gerar outro filho para o nó pai deste nível do
mesmo modo que o anterior. A Figura 11 ilustra a criação de uma árvore-exemplo com o
backtracking, em que os números indicam a ordem em que os nós foram gerados durante a busca.

2 7 8

3 4 9

5 6 10 11

Figura 11. Ordem de geração dos nós de uma árvore-exemplo durante o backtracking

Rogério Espíndola esqueca.me@gmail.com 2002-2010


[Digite texto] Inteligência Computacional I 13
Tecnologia em Análise e Desenvolvimento de Sistemas

A Figura 12 apresenta o algoritmo de backtracking e as Figuras 13 e 14 ilustram a sua


aplicação nos problemas-exemplos, observando-se que o valor dentro de um nó indica a sua ordem de
geração.

resposta = nulo
pilha-de-abertos = estado inicial
lista-de-fechados = nulo
sucesso = falso
enquanto (sucesso = falso) e (pilha-de-abertos ≠ vazio) faça
nó-candidato = elemento do topo da pilha-de-abertos
se for possível gerar um filho inédito para o nó-candidato
então
gere-o
se nó filho recém-gerado é a solução
então
sucesso = verdadeiro
resposta = nó-filho
senão
coloque o nó filho no topo da pilha-de-abertos
fim-se
senão
remova o elemento do topo da pilha-de-abertos
coloque-o em lista-de-fechados
fim-se
fim-enquanto
retorna sucesso e reposta

Figura 12. Algoritmo básico do backtracking

A
R1
R3
B 1
10 P
R1 R4
R3 R4
C 2 3 F
O 11 17 S
R1
G R2 R4
4

R1 R4 J 12 16 R

H 5 7 L R3

R2 R1 13 I

D 6 8 M R2 R4
R4 E 14 15 N
9 Q

Figura 13. Árvore obtida pelo backtracking no problema do labirinto

Rogério Espíndola esqueca.me@gmail.com 2002-2010


[Digite texto] Inteligência Computacional I 14
Tecnologia em Análise e Desenvolvimento de Sistemas

(0,0) (0,1) 5 6 (1,0)


R5
R1 R3 R2
(3,0) 1 (3,1) 4 7 (1,4)
R2 R6 R6
R3
(3,4) 2 3 (0,4) 8 (3,2)

Figura 14. Árvore obtida pelo backtracking no problema dos jarros d`água

Em particular, no problema dos jarros d`água não houve necessidade de retorno da busca.

3.3.3. Busca em largura

Diferentemente da busca em profundidade, a busca em largura prioriza os nós mais próximos


do nó raiz, isto é, os de menor profundidade. Ela expande os nós na ordem em que são gerados
fazendo com que os nós de uma determinada profundidade somente são gerados e avaliados se os da
profundidade anterior já tiverem sido abordados.
Inicialmente, o nó raiz é expandido e seus filhos avaliados. Se nenhum corresponder a alguma
solução, então o filho mais à esquerda é expandido. Se os filhos deste também não representarem
alguma solução, então o segundo filho do nó raiz é expandido. E assim o método continua expandindo
os filhos do nó raiz até encontrar alguma solução ou não haver mais filhos a serem expandidos.
Se nenhuma solução for encontrada na profundidade 2, então os nós da profundidade 3 passam
a ser expandidos repetindo-se todo o procedimento de expansão e avaliação nível a nível. A Figura 15
ilustra o processo de geração de uma árvore-exemplo pela busca em largura.

2 3 4

5 6 7 8

9 10 11 12

Figura 15. Ordem de geração dos nós de uma árvore-exemplo durante a busca em largura

A busca em largura avalia todos os ramos de uma árvore. Assim, além de garantir o encontro
de uma solução se ela existir, esta solução é ótima. Portanto, é uma busca completa e ótima.

Rogério Espíndola esqueca.me@gmail.com 2002-2010


[Digite texto] Inteligência Computacional I 15
Tecnologia em Análise e Desenvolvimento de Sistemas

Entretanto, há uma grande necessidade de memória para armazenar toda a árvore. A Figura 16
exibe o algoritmo da busca em largura e a Figura 17 apresenta a sua aplicação nos problemas-
exemplos. O valor dentro de um nó indica a sua ordem de geração.

resposta = nulo
fila-de-abertos = estado inicial
lista-de-fechados = nulo
sucesso = falso
enquanto (sucesso = falso) e (fila-de-abertos ≠ vazio) faça
nó-candidato = elemento do início da fila-de-abertos
remova o elemento do início da fila-de-abertos
coloque-o em lista-de-fechados
expanda nó-candidato
se algum filho de nó-candidato é a solução
então
sucesso = verdadeiro
resposta = filho-solução de nó-candidato
senão
coloque o(s) nó(s) filho(s) ao final da fila-de-abertos
fim-se
fim-enquanto
retorna sucesso e reposta

Figura 16. Algoritmo básico da busca em largura

A (0,0)
R1 R4 R1 R2
B 1 2 E (3,0) 1 2 (0,4)
R1 R4 R4 R2 R5 R6
(3,4)
C 3 4 F 5 I 3 4 (0,3) 5 (3,1)
R1 R1 R4
R1 R3
6 G 7 J 8 N
6 (3,3) 7 (0,1)
R1
R4 R4
R8 R5
H 9 10 L 11 O
R4 8 (2,4) 9 (1,0)
R2 R1 R1
R4 R2
D 12 13 M 14 P 15 R
10 (2,0) 11 (1,4)
R4 R4
R7
16 Q 17 S
12 (0,2)

(a) (b)

Figura 17. Árvores obtidas pela busca em largura nos problemas-exemplos

Rogério Espíndola esqueca.me@gmail.com 2002-2010


[Digite texto] Inteligência Computacional I 16
Tecnologia em Análise e Desenvolvimento de Sistemas

3.3.4. Busca em profundidade iterativa

A busca em profundidade iterativa procura combinar as virtudes da busca em profundidade e


da busca em largura. São elas a relativamente pouca necessidade de memória e a capacidade de
examinar todo o espaço de estados encontrando a solução ótima, respectivamente.
Como definir uma profundidade máxima de exploração é uma questão crítica quando se
realiza uma busca em profundidade limitada, a determinação de limites crescentes a cada iteração
consegue evitá-la. Na primeira iteração, a árvore é gerada utilizando a busca em profundidade limitada
com limite igual a 1. Se a solução não foi encontrada, inicia-se a segunda iteração: toda a árvore
anterior é descartada e uma nova é construída através da busca em profundidade limitada com limite
igual a 2. Se ao final da segunda iteração a solução ainda não tiver sido obtida, o processo continua
definindo o limite igual a 3 e assim sucessivamente. A busca pára quando a solução é encontrada ou
quando toda a árvore for gerada.
Por questões de espaço, a busca em profundidade iterativa não será aplicada aos problemas-
exemplos. Esta atividade fica como exercício. A Figura 18 exibe o seu algoritmo fazendo referência ao
algoritmo da busca em profundidade e a Figura 19 exibe o seu funcionamento em uma árvore-
exemplo. Observe que a solução foi encontrada na profundidade 3.

resposta = nulo
sucesso = falso
limite = 1
enquanto (sucesso = falso) faça
resposta e sucesso = busca em profundidade com o valor limite
se (sucesso = falso) então limite = limite + 1
fim-enquanto
retorna sucesso e reposta

Figura 18. Algoritmo básico da busca em profundidade iterativa

iteração 3 1
iteração 1 1
limite = 3
limite = 1
2 3 4
2 3 4

5 6 9 10
1
iteração 2
limite = 2
2 3 4
7 8 11 12

5 6 7 8

Figura 19. A busca em profundidade iterativa em uma árvore-exemplo

Rogério Espíndola esqueca.me@gmail.com 2002-2010


[Digite texto] Inteligência Computacional I 17
Tecnologia em Análise e Desenvolvimento de Sistemas

Pode-se pensar que se realiza um esforço desnecessário ao se gerar e descartar árvores. Isto
realmente ocorre em problemas bastante simples. Entretanto, este método se mostra eficiente em
problemas mais complexos que possuem maiores espaços de busca e que não se tem conhecimento a
respeito da profundidade da solução.
Analogamente, há o método backtracking iterativo que utiliza o backtracking no lugar da
busca em profundidade.

3.3.5. Busca ordenada

A busca em largura e a busca em profundidade iterativa sempre encontrarão a melhor solução


de um problema se ela existir. O conceito de melhor solução utilizado pelos métodos anteriores foi
definido como aquela que estava mais próxima da raiz, ou seja, a que foi obtida com a menor
quantidade de aplicações de regras. A utilização dessas regras não estava associada a qualquer custo.
Isto porque nos problemas estudados não havia interesse em se descobrir o custo de uma solução.
Entretanto, há muitos problemas em que o custo de uma solução desempenha um papel fundamental
na sua aceitação. Como exemplo pode ser citado o clássico problema cujo objetivo é encontrar o
caminho mais curto entre duas localidades.
Para esse tipo de problema pode-se aplicar o método chamado de busca ordenada ou busca de
custo uniforme. Esse método é uma versão mais genérica da busca em largura mas, em vez de
expandir os nós menos profundos, os nós expandidos são aqueles que possuem o menor custo de
obtenção. Para um determinado nó, este custo é o somatório dos custos dos operadores aplicados
desde o nó raiz até ele. Dessa maneira, considerando apenas custos não-negativos, os nós filhos
sempre terão custos maiores ou iguais que os custos de seus pais.
Em outras palavras, o método inicia expandindo o nó raiz. Se nenhum dos nós filhos for
alguma solução, então aquele que tiver o menor custo de obtenção é expandido. Se alguma solução
ainda não tiver sido encontrada, então de todos os nós abertos, expande-se aquele que tiver o menor
custo e assim por diante. Ressalta-se que os nós abertos podem estar em qualquer profundidade. A
busca ordenada não leva em consideração a posição de um nó, mas sim o seu custo.
Mesmo que uma solução seja obtida ainda não se tem certeza que ela seja a de menor custo.
Para descobrir é necessário verificar se há algum nó aberto que possua custo inferior ao da solução
encontrada. Se não houver, então conclui-se que a solução realmente é a de menor custo. Caso
contrário, a busca prossegue a sua exploração enquanto houver algum nó aberto de custo inferior ao de
uma solução. Isto equivale dizer que a busca termina quando o nó aberto que representa uma solução
for escolhido para ser expandido.
Frequentemente, durante a expansão da árvore, é gerado um nó filho que representa um estado
já codificado em um nó anterior. Assim, se o nó anterior já estiver fechado, então não é necessário
avaliar o novo nó nem colocá-lo na árvore. Por outro lado, se o nó anterior ainda estiver aberto, deve-
se determinar o custo do novo nó e manter aquele que tiver o menor custo.
Vale ressaltar que o custo nem sempre está associado a algum valor monetário. Ele pode
assumir diversos outros conceitos tais como o tempo gasto para ir de um estado a outro, a quantidade
de energia consumida, a quantidade de pessoas utilizadas e, mais comumente, a distância entre os
estados.

Rogério Espíndola esqueca.me@gmail.com 2002-2010


[Digite texto] Inteligência Computacional I 18
Tecnologia em Análise e Desenvolvimento de Sistemas

A Figura 20 apresenta o algoritmo da busca ordenada. Para ilustrar o funcionamento do


método, é necessário definir outros problemas-exemplos. Os dois problemas-exemplos anteriores
poderiam ser modificados de modo que incorporassem custos aos operadores mas isto não será feito
neste texto. Serão utilizados dois exemplos do problema de caminho mais curto.
Considere os grafos exibidos nas Figura 21. Os valores próximos das arestas indicam a
distância em quilômetros entre as diversas localidades. Em cada problema, deseja-se descobrir o
caminho mais curto entre o local A e o local G.
A Figura 22 apresenta as árvores produzidas, em que os números dentro dos círculos indicam
a ordem de geração e os outros informam os custos dos nós. Nesta figura, os nós que foram criados e
posteriormente descartados estão indicados pelos arcos tracejados.

resposta = nulo
lista-de-abertos = estado inicial
lista-de-fechados = nulo
sucesso = falso
enquanto (sucesso = falso) e (lista-de-abertos ≠ vazio) faça
nó-candidato = elemento de menor custo da lista-de-abertos
remova o elemento de menor custo da lista-de-abertos
coloque-o em lista-de-fechados
se nó-candidato é solução
então
sucesso = verdadeiro
resposta = nó-candidato
senão
expanda nó-candidato
coloque o(s) nó(s) filho(s) na lista-de-abertos
fim-se
fim-enquanto
retorna sucesso e reposta

Figura 20. Algoritmo básico da busca ordenada ou de custo uniforme

B E
Problema 1 10
7
9 3 6
13 14
A G
D
5 10
12
C F

Figura 21. Problemas-exemplos de caminho mais curto entre A e G (continua)

Rogério Espíndola esqueca.me@gmail.com 2002-2010


[Digite texto] Inteligência Computacional I 19
Tecnologia em Análise e Desenvolvimento de Sistemas

Problema 2 B 7 E
15
8 8 5
16 10
A G
D
14 6
3 17
6
C F

Figura 21. Problemas-exemplos de caminho mais curto entre A e G (continuação)

Problema 1
A,0

B,9 C,5 D,13


1 2 3

D,12 4 5 E,19 6 F,17

E,18 7 8 G,26 9 G,27

10 G,25

Problema 2
A,0

B,8 C,3 D,16


1 2 3

F,9
D,16 6 7 E,14 4 5
D,17
G,26
D,19 10 11 G,29 8 D,15 9

12 G,25

local,custo

Figura 22. Árvores geradas pela busca ordenada para os problemas-exemplos

Rogério Espíndola esqueca.me@gmail.com 2002-2010


[Digite texto] Inteligência Computacional I 20
Tecnologia em Análise e Desenvolvimento de Sistemas

4
Buscas informadas

4.1. Introdução

Já foi visto que os algoritmos anteriores não utilizam qualquer informação do problema que
estiver sendo abordado a respeito da proximidade da solução durante a escolha de um nó para a
expansão. Frequentemente, esses métodos geram e avaliam uma grande quantidade de nós antes de
uma solução ser encontrada. Devido aos limites de memória disponível e de tempo para a execução da
busca, é desejável que a resolução de um problema seja obtida de uma maneira mais eficiente.
A Figura 23 exibe o algoritmo básico das buscas informadas que serão apresentados neste
texto.

resposta = nulo
lista-de-abertos = estado inicial
lista-de-fechados = nulo
sucesso = falso
enquanto (sucesso = falso) e (lista-de-abertos ≠ vazio) faça
nó-candidato = elemento de melhor avaliação da lista-de-abertos
remova o elemento de melhor avaliação da lista-de-abertos
coloque-o em lista-de-fechados
se nó-candidato é a solução
então
sucesso = verdadeiro
resposta = nó-candidato
senão
expanda nó-candidato
para cada filho de nó-candidato gerado faça
avalie-o
se filho for inédito
então coloque-o em lista-de-abertos
senão
se avaliação nova melhor que antiga
então
remova a configuração antiga
coloque-o em lista-de-abertos
fim-se
fim-se
fim-para
fim-se
fim-enquanto
retorna sucesso e reposta

Figura 23. Algoritmo básico das buscas informadas.

Rogério Espíndola esqueca.me@gmail.com 2002-2010


[Digite texto] Inteligência Computacional I 21
Tecnologia em Análise e Desenvolvimento de Sistemas

Os algoritmos que serão vistos a seguir utilizam informações sobre o problema abordado –
heurísticas – de modo a selecionar um nó que seja mais promissor para o encontro da solução,
evitando que nós presentes em caminhos inúteis sejam selecionados. A caracterização de um nó como
promissor é realizada pela função de avaliação ou função de avaliação heurística. Quanto menor o
valor retornado por esta função para um nó, isto é, quanto menor a sua avaliação, maior a sua
possibilidade de estar no melhor caminho do nó raiz até o nó-solução. A distinção entre os métodos
ocorre na maneira de realizar esta avaliação.

4.2. Busca gulosa

É um método bastante simples que procura minimizar o custo estimado para se obter uma
solução, sempre expandindo o nó mais próximo da solução.
A estimativa de custo é realizada por uma função chamada de função heurística ou apenas
heurística, sendo representada por h(n). Em um dado nó, a função heurística informa o custo estimado
do caminho mais barato entre este nó e a solução (Figura 24). Um detalhe importante é que o custo
estimado do nó-solução deve ser zero, ou seja, h(solução) = 0. Uma vez que a busca tenha encontrado
o nó-solução, não há mais caminho a seguir e, portanto, não há mais custo. Assim, a avaliação de cada
nó é realizada pela função heurística.
Inicialmente o nó raiz é expandido e seus filhos avaliados segundo uma função heurística. Se
nenhum deles for a solução, aquele que tiver o menor custo estimado é expandido e seus filhos são
avaliados. Se nenhum desses filhos for a solução, o processo é repetido com um deles, isto é, com o
que tiver menor custo estimado e assim por diante. Quando um nó folha é selecionado para a
expansão, ele é fechado e a busca continua com o nó aberto de menor avaliação.
As estimativas não são necessariamente cálculos exatos dos custos. Por exemplo, uma
heurística eficiente em problemas de rotas – como os da Figura 21 – é a distância em linha reta entre
duas localidades. É importante observar que quanto mais precisa for a definição de uma heurística
melhor será o comportamento da busca. Além disso, a definição de uma função heurística para um
problema depende dos pontos de vista de um pesquisador e de suas fontes de informação.
A ilustração da busca gulosa será realizada utilizando-se os problemas-exemplos da Figura 21.
Estes problemas são reexibidos na Figura 25 juntamente com as tabelas de distâncias em linhas retas
das diversas localidades para os destinos G.

caminho mais barato

nó n nó solução

Figura 24. Diversos caminhos podem conectar um nó à solução, sendo um deles o mais barato

Rogério Espíndola esqueca.me@gmail.com 2002-2010


[Digite texto] Inteligência Computacional I 22
Tecnologia em Análise e Desenvolvimento de Sistemas

Problema 1 B E
10
7
9 3 6
13 14
A G
D
5 10
12
C F

Nós A B C D E F G
h(nó) 24 15 22 12 7 7 0

Problema 2 B E
7
15
8 8 5
16 10
A G
D
14 6
3 17
6
C F

Nós A B C D E F G
h(nó) 16 13 15 7 10 10 0

Figura 25. Grafos dos problemas-exemplos e suas funções heurísticas

A Figura 26 exibe as árvores de busca geradas. Nelas, foram omitidos os nós que representam
estados já presentes em nós anteriores por possuírem o mesmo custo. Os números ao lado das letras
indicam os valores das funções heurísticas, enquanto que a numeração dentro dos nós indica a ordem
de geração dos mesmos. Os nós que foram criados e posteriormente descartados estão destacados
pelos arcos tracejados.
Considerando o primeiro problema, a busca gulosa encontrou uma solução por meio da rota
A-D-G que possui custo igual a 27. Pode-se observar que esta solução não é ótima, bastando compará-
la a solução obtida pela busca ordenada – rota A-B-D-E-G com custo igual a 25 (Figura 22). Ainda
comparando com a busca ordenada, menos nós foram gerados e avaliados. No segundo problema, a
solução também não foi ótima – rota A-D-G de custo igual a 26 – e, novamente, menos nós foram
gerados e avaliados em relação à busca ordenada.

Rogério Espíndola esqueca.me@gmail.com 2002-2010


[Digite texto] Inteligência Computacional I 23
Tecnologia em Análise e Desenvolvimento de Sistemas

Problema 1 A,24

B,15 C,22 D,12


1 2 3

E,7 4 5 G,0

Problema 2
A,16

B,13 C,15 D,7


1 2 3

E,10 4 5 6 G,0
F,10

local,custo

Figura 26. Árvores geradas pela busca gulosa para os problemas-exemplos

Estes exemplos mostram uma característica marcante de algoritmos que implementam a busca
gulosa. Eles possuem boas chances de encontrar uma solução rapidamente, mas não necessariamente a
melhor, pois a primeira solução obtida interrompe o processo. Além disso, pode ocorrer de nenhuma
solução ser encontrada pela busca. Por exemplo, quando se trabalha com uma árvore infinita e a busca
segue por um ramo que não contém a solução. Observa-se, então, que o comportamento da busca
gulosa é semelhante ao da busca em profundidade.

4.3. Algoritmo A*

Como foi visto, a busca ordenada seleciona o nó com o menor custo associado da origem até
ele. Já a busca gulosa escolhe o nó com a menor estimativa de custo a partir dele até uma solução. O
algoritmo A* combina as duas estratégias visando tirar proveito das características de ambas: soluções
ótimas e capacidade de explorar todo o espaço de busca (busca ordenada), e rapidez e relativamente
pouca necessidade de memória (busca gulosa).
Esta combinação ocorre através da seguinte função de avaliação:

f(n) = g(n) + h(n)

Rogério Espíndola esqueca.me@gmail.com 2002-2010


[Digite texto] Inteligência Computacional I 24
Tecnologia em Análise e Desenvolvimento de Sistemas

em que:

g(n) é a função que retorna o custo real da origem até o nó n


h(n) é a função heurística que retorna o custo estimado a partir do nó até a solução

Observe que com g(n) = 0, a busca torna-se gulosa e com h(n) = 0 a busca é a ordenada. A
Figura 27 ilustra a definição desta função de avaliação.

custo
custo real
estimado
g(n) h(n)
nó raiz nó solução
nó n

Figura 27. Representação da função de avaliação do algoritmo A*

A Figura 28 exibe as árvores geradas pelo A* para os problemas apresentados na Figura 25.
Assim como em figuras anteriores, os nós que foram criados e posteriormente descartados estão
indicados pelos arcos tracejados. Os números ao lado das letras indicam, respectivamente, o custo real
até um determinado nó e o valor da função heurística para ele. A numeração dentro dos nós indica a
ordem de geração dos mesmos. Observa-se que o uso de informação sobre o problema permitiu que o
método produzisse menos nós que a busca ordenada.
Se as funções estiverem bem definidas, o A* é eficiente e sempre encontrará a solução ótima
de um problema se este possuir alguma. Para que isso ocorra, um cuidado a ser tomado é que a função
h(n) não deve superar o custo real do caminho entre um nó e a solução.

Problema 1
A,0,24

B,9,15 D,13,12
1 2 3
C,5,22

D,12,12 4 5 E,19,7

E,18,7 7 8 G,26,0

9 G,25,0

local, custo real, custo estimado

Figura 28. Árvores geradas pelo algoritmo A* para os problemas-exemplos (continua)

Rogério Espíndola esqueca.me@gmail.com 2002-2010


[Digite texto] Inteligência Computacional I 25
Tecnologia em Análise e Desenvolvimento de Sistemas

Problema 2
A,0,16

B,8,13
1 2 3 D,16,7
C,3,15

D,16,7 8 9 4 5 F,9,10
E,15,10 D,17,7
12 D,15,7 6 7 G,26,0
G,30,0
E,20,10 10 11 G,25,0

local, custo real, custo estimado

Figura 28. Árvores geradas pelo algoritmo A* para os problemas-exemplos (continuação)

Para um mesmo problema várias estimativas de custos de nós podem ser definidas, havendo
diferenças em desempenho. Por exemplo, suponha que um problema possua duas heurísticas, h1 e h2,
tais que h2 ≥ h1 para todo nó. Então, diz-se que a heurística h2 é mais informada que a h1. Como
consequência, a árvore gerada por h2 é na média menor do que a obtida por h1. Assim, ao se utilizar de
heurísticas mais informadas, o algoritmo A* obtém maior eficiência.

4.4. A* iterativo em profundidade

Mesmo sendo eficiente, há muitas situações em que o algoritmo A* enfrenta dificuldades em


termos de espaço disponível em memória e de tempo de processamento. Assim, foram desenvolvidas
algumas estratégias para contornar este problema. Uma das primeiras é o algoritmo A* iterativo em
profundidade ou simplesmente IDA*. A cada iteração, o método aplica o A* em uma profundidade
diferente até ser encontrada a solução.
O conceito de profundidade aqui utilizado é totalmente diferente do que foi empregado
anteriormente. A profundidade está agora relacionada a avaliações de custos. Pode-se pensar a
profundidade como um limite máximo para os custos. Os nós de uma árvore cujos custos estão além
desse limite são criados, avaliados e descartados.
Na primeira iteração, a profundidade máxima ou o limite máximo de custos é a avaliação do
nó raiz. Este é expandido e seus filhos avaliados. Os nós que tiverem avaliações superiores ao limite
estipulado são descartados. Os outros nós são mantidos e se nenhum deles for a solução, então aquele
que tiver a melhor avaliação, ou seja, o menor custo, é expandido do mesmo modo que o nó raiz.

Rogério Espíndola esqueca.me@gmail.com 2002-2010


[Digite texto] Inteligência Computacional I 26
Tecnologia em Análise e Desenvolvimento de Sistemas

O processo continua expandindo os nós e mantendo apenas aqueles de avaliações não maiores
que o limite estipulado até que a solução seja encontrada, quando então o algoritmo termina, ou até
que toda a árvore seja gerada sem encontrá-la. Neste caso, o algoritmo realiza uma nova iteração.
Antes de o IDA* iniciar efetivamente mais uma iteração, ele redefine o limite máximo para
expansão. O novo valor passa a ser a menor das avaliações dos nós descartados na última iteração. A
árvore que foi gerada anteriormente é descartada e uma nova é construída do mesmo modo utilizando
o novo valor de limite máximo ou profundidade. Observe que o aumento da profundidade ocasiona
uma árvore maior.
O processo de redefinição de limite, de geração e de descarte de árvores se repete até que a
solução seja encontrada. Observa-se que, quando um nó solução for utilizado para definir o próximo
limite, o algoritmo pára pois ele já determinou um caminho ótimo do nó raiz até a solução. O IDA*,
assim como o A*, é ótimo e completo. A Figura 29 exibe o seu algoritmo básico e a Figura 30 a sua
aplicação aos problemas-exemplos da Figura 25.

resposta = nulo
sucesso = falso
limite-máximo = avaliação do estado inicial
enquanto (sucesso = falso) faça
resposta e sucesso = A* com limite-máximo
se (sucesso = falso)
então limite-máximo = melhor avaliação dos nós descartados
fim-se
fim-enquanto
retorna sucesso e reposta

Figura 29. Algoritmo básico do algoritmo IDA*

Problema 1
A,0,24

iteração 1
limite = 24 B,9,15 D,13,12
1 2 3
C,5,22

D,12,12 4 5 E,19,7
próximo limite = 25

E,18,7 7 8 G,26,0

local, custo real, custo estimado

Figura 30. Árvores geradas pelo algoritmo IDA* para os problemas-exemplos (continua)

Rogério Espíndola esqueca.me@gmail.com 2002-2010


[Digite texto] Inteligência Computacional I 27
Tecnologia em Análise e Desenvolvimento de Sistemas

Problema 1
A,0,24

iteração 2
B,9,15 D,13,12
limite = 25
1 2 3
C,5,22
D,12,12 4 5 E,19,7

E,18,7 7 8 G,26,0

9 G,25,0

Problema 2

A,0,16
iteração 1
limite = 16

B,8,13 1 2 3 D,16,7
C,3,15
próximo limite = 18
iteração 2 A,0,16
limite = 18

B,8,13
1 2 3 D,16,7
C,3,15

4 5 F,9,10
D,17,7
próximo limite = 19
iteração 3 A,0,16
limite = 19

B,8,13
1 2 3 D,16,7
C,3,15

4 5 F,9,10
próximo limite = 21 D,17,7

D,15,7 6 7 G,26,0

local, custo real, custo estimado

Figura 30. Árvores geradas pelo algoritmo IDA* para os problemas-exemplos (continuação)

Rogério Espíndola esqueca.me@gmail.com 2002-2010


[Digite texto] Inteligência Computacional I 28
Tecnologia em Análise e Desenvolvimento de Sistemas

iteração 4 A,0,16
limite = 21

B,8,13
1 2 3 D,16,7
C,3,15

D,16,7 8 9 4 5 F,9,10
E,14,10 D,17,7

D,15,7 6 7 G,26,0

próximo limite = 22

iteração 5 A,0,16
limite = 22

B,8,13
1 2 3 D,16,7
C,3,15

D,16,7 8 9 4 5 F,9,10
E,15,10 D,17,7

D,15,7 6 7 G,26,0
próximo limite = 25
E,20,10 10 11 G,25,0

iteração 6
A,0,16
limite = 25

B,8,13
1 2 3 D,16,7
C,3,15

D,16,7 8 9 4 5 F,9,10
E,15,10 D,17,7

D,15,7 6 7 G,26,0

E,20,10 10 11 G,25,0

local, custo real, custo estimado

Figura 30. Árvores geradas pelo algoritmo IDA* para os problemas-exemplos (continuação)

Rogério Espíndola esqueca.me@gmail.com 2002-2010

S-ar putea să vă placă și