Código da aula: Github
Aula 02 - Inteligência Coletiva: Agentes e Enxames na Prática
Introdução
Na aula anterior, conhecemos os
agentes reativos, que reagem ao ambiente de maneira simples, mas eficiente para tarefas específicas. Hoje, vamos explorar um nível mais sofisticado de agentes: os
agentes deliberativos. Esses agentes são capazes de planejar suas ações, usar raciocínio lógico e até mesmo adaptar suas estratégias conforme o ambiente muda.
Esses agentes são amplamente usados em contextos como
logística, planejamento urbano, navegação autônoma, e simulação de sistemas complexos. Nesta aula, você aprenderá a teoria por trás desses agentes e implementará um exemplo prático em Python.
O que são Agentes Deliberativos?
Os agentes deliberativos possuem um modelo interno do mundo, o que significa que eles conseguem representar o ambiente de forma abstrata para tomar decisões baseadas em objetivos de longo prazo. Eles geralmente seguem um ciclo básico:
- Percepção: Observam o ambiente e coletam informações relevantes.
- Planejamento: Analisam o estado atual e planejam ações para atingir seus objetivos.
- Ação: Executam as ações planejadas no ambiente.
- Adaptação: Ajustam suas estratégias com base nos resultados observados.
Exemplo Prático: Planejamento de Rotas com o Algoritmo A*
Vamos implementar um agente que utiliza o algoritmo
A* para encontrar a melhor rota entre dois pontos em um mapa com obstáculos.
O
A* (
A-Star) é um algoritmo de busca que encontra o caminho mais curto entre um ponto de início e um ponto de destino em um espaço definido (como um mapa, uma grade ou um grafo). Ele é amplamente utilizado em jogos, robótica e sistemas de navegação.
Aplicações Reais do A*
- Sistemas de Navegação (GPS, Google Maps, Waze).
- Jogos (NPCs encontrando caminhos em mapas).
- Robótica (Drones, aspiradores inteligentes como o Roomba).
- Otimização de Rotas (Logística de entregas).
O A* combina duas abordagens de busca:
- Busca Cega (Dijkstra): Explora todas as possibilidades até encontrar o caminho mais curto.
- Busca Heurística (Gulosa): Usa uma função heurística para priorizar caminhos promissores.
O objetivo do
A* é encontrar um caminho com
o menor custo total, que é a soma de:
- Custo acumulado do caminho já percorrido (
g(n)) → Quanto já percorremos até um nó.
- Estimativa do custo restante (
h(n)) → Distância estimada até o destino.
A função final que o
A* usa para decidir qual caminho explorar é:
f(n) = g(n) + h(n) é a
função de custo total usada pelo Algoritmo
A*. Ela ajuda a decidir qual nó (ou célula do mapa) deve ser explorado primeiro.
f(n) → Custo total estimado para chegar ao destino passando pelo nó n. A soma dos dois ( g(n) + h(n) ), que é usada para decidir qual nó explorar primeiro.
g(n) → Custo real do caminho desde o ponto inicial até o nó n. Ou seja, quanto já andamos desde o início.
h(n) → Estimativa do custo restante (heurística), isto é, quão longe n ainda está do destino.
| Nó |
g(n) (Caminho percorrido) |
h(n) (Estimativa até o destino) |
f(n) = g(n) + h(n) |
| (0,0) |
0 |
8 |
8 |
| (0,1) |
1 |
7 |
8 |
| (1,1) |
2 |
6 |
8 |
| (2,1) |
3 |
5 |
8 |
| (2,2) |
4 |
4 |
8 |
| (3,2) |
5 |
3 |
8 |
| (3,3) |
6 |
2 |
8 |
| (3,4) |
7 |
1 |
8 |
| (4,4) |
8 |
0 |
8 |
O
A* sempre escolhe o nó com o menor
f(n), garantindo que ele siga o caminho mais curto possível.
O
A* escolhe
o menor f(n) disponível, garantindo que o agente tome o caminho mais eficiente.
Comparação com Outros Algoritmos
| Algoritmo |
Usa Heurística? |
Garante Melhor Caminho? |
Complexidade |
| Dijkstra |
❌ Não |
✅ Sim |
O(V^2) (ou O(E log V) com heap) |
| Busca Gulosa |
✅ Sim |
❌ Não |
O(b^d) (rápido, mas não confiável) |
| A* |
✅ Sim |
✅ Sim |
O(b^d) (mais eficiente que Dijkstra) |
Vantagens do A* ✔️
Mais rápido que Dijkstra em mapas grandes.
✔️
Garante o menor caminho.
✔️
Flexível (pode ajustar heurísticas para diferentes cenários).
Veja esses vídeos para um melhor entendimento do A*:
https://www.youtube.com/watch?v=71CEj4gKDnE&t=2s
https://www.youtube.com/watch?v=lusRf5v-TI0
Multi-Agent Systems tutorial/route-planner-agent/route-planner-agent.py
import heapq
import matplotlib.pyplot as plt
class AgentePlanejadorRotas:
def __init__(self, mapa, inicio, destino):
self.mapa = mapa
self.posicao = inicio
self.destino = destino
self.caminho = []
self.historico = [inicio] # Para armazenar as posições percorridas
def planejar_rota(self):
self.caminho = self.busca_a_estrela(self.posicao, self.destino)
def busca_a_estrela(self, inicio, fim):
def heuristica(a, b):
return abs(a[0] - b[0]) + abs(a[1] - b[1])
fila = []
heapq.heappush(fila, (0, inicio))
custos = {inicio: 0}
caminhos = {inicio: None}
while fila:
_, atual = heapq.heappop(fila)
if atual == fim:
caminho = []
while atual:
caminho.append(atual)
atual = caminhos[atual]
return caminho[::-1]
x, y = atual
for dx, dy in [(-1, 0), (1, 0), (0, -1), (0, 1)]:
vizinho = (x + dx, y + dy)
if 0 <= vizinho[0] < len(self.mapa) and 0 <= vizinho[1] < len(self.mapa[0]) and self.mapa[vizinho[0]][vizinho[1]] != 1:
novo_custo = custos[atual] + 1
if vizinho not in custos or novo_custo < custos[vizinho]:
custos[vizinho] = novo_custo
prioridade = novo_custo + heuristica(vizinho, fim)
heapq.heappush(fila, (prioridade, vizinho))
caminhos[vizinho] = atual
return []
def mover(self):
if self.caminho:
nova_posicao = self.caminho.pop(0)
print(f"Movendo para {nova_posicao}")
self.posicao = nova_posicao
self.historico.append(nova_posicao) # Adiciona ao histórico
else:
print("Destino alcançado")
def agir(self):
if not self.caminho:
self.planejar_rota()
self.mover()
# Configuração do mapa
mapa = [
[0, 0, 0, 0, 1],
[0, 1, 1, 0, 1],
[0, 1, 0, 0, 0],
[0, 0, 0, 1, 0],
[1, 1, 0, 0, 0]
]
inicio = (0, 0)
destino = (4, 4)
# Função para desenhar o mapa
def desenhar_mapa(mapa, agente, historico):
plt.imshow(mapa, cmap="Greys", origin="upper")
plt.scatter(inicio[1], inicio[0], c="green", s=200, label="Início") # Início
plt.scatter(destino[1], destino[0], c="red", s=200, label="Destino") # Destino
# Exibe o histórico
if historico:
y, x = zip(*historico)
plt.plot(x, y, c="blue", linewidth=2, label="Caminho")
plt.scatter(agente.posicao[1], agente.posicao[0], c="yellow", s=200, label="Agente") # Posição atual do agente
plt.legend()
plt.pause(0.5)
plt.clf()
# Executa o agente com visualização
# Executa o agente com visualização
agente = AgentePlanejadorRotas(mapa, inicio, destino)
plt.figure(figsize=(8, 8))
plt.ion() # Ativa o modo interativo
# Loop para agir enquanto não alcança o destino
while agente.posicao != destino:
desenhar_mapa(mapa, agente, agente.historico)
agente.agir()
# Mostra o mapa final sem limpar ou fechar
plt.ioff() # Desativa o modo interativo
desenhar_mapa(mapa, agente, agente.historico) # Desenha o estado final
plt.show() # Mantém o gráfico aberto até o usuário fechá-lo
Pra executar:
python route-planner-agent.py
Movendo para (0, 0)
Movendo para (0, 1)
Movendo para (0, 2)
Movendo para (0, 3)
Movendo para (1, 3)
Movendo para (2, 3)
Movendo para (2, 4)
Movendo para (3, 4)
Movendo para (4, 4)
Explicação do Código com Matplotlib
Seções do Código
1. Importação de Bibliotecas
Importamos as bibliotecas necessárias:
import heapq
import matplotlib.pyplot as plt
- heapq: Usada para implementar a fila de prioridade no algoritmo A*.
- matplotlib.pyplot: Para criar a visualização gráfica do mapa e o movimento do agente.
2. Classe AgentePlanejadorRotas
Define o agente deliberativo que usa o algoritmo A* para planejar e seguir um caminho no mapa.
class AgentePlanejadorRotas:
def __init__(self, mapa, inicio, destino):
self.mapa = mapa
self.posicao = inicio
self.destino = destino
self.caminho = []
self.historico = [inicio]
- Inicializa o mapa, a posição inicial, o destino e o caminho planejado.
- A lista
historico armazena todas as posições que o agente percorreu para exibição no gráfico.
3. Planejamento da Rota
def planejar_rota(self):
self.caminho = self.busca_a_estrela(self.posicao, self.destino)
Chama o método
busca_a_estrela para calcular a melhor rota até o destino.
4. Implementação do Algoritmo A*
def busca_a_estrela(self, inicio, fim):
def heuristica(a, b):
return abs(a[0] - b[0]) + abs(a[1] - b[1])
fila = []
heapq.heappush(fila, (0, inicio))
custos = {inicio: 0}
caminhos = {inicio: None}
while fila:
_, atual = heapq.heappop(fila)
if atual == fim:
caminho = []
while atual:
caminho.append(atual)
atual = caminhos[atual]
return caminho[::-1]
x, y = atual
for dx, dy in [(-1, 0), (1, 0), (0, -1), (0, 1)]:
vizinho = (x + dx, y + dy)
if 0 <= vizinho[0] < len(self.mapa) and 0 <= vizinho[1] < len(self.mapa[0]) and self.mapa[vizinho[0]][vizinho[1]] != 1:
novo_custo = custos[atual] + 1
if vizinho not in custos or novo_custo < custos[vizinho]:
custos[vizinho] = novo_custo
prioridade = novo_custo + heuristica(vizinho, fim)
heapq.heappush(fila, (prioridade, vizinho))
caminhos[vizinho] = atual
return []
Esse método:
- Utiliza uma fila de prioridade (
heapq) para ordenar os nós explorados.
- Aplica uma função heurística para estimar a distância restante até o destino.
- Retorna o caminho mais curto como uma lista de coordenadas.
5. Movimento do Agente
def mover(self):
if self.caminho:
nova_posicao = self.caminho.pop(0)
print(f"Movendo para {nova_posicao}")
self.posicao = nova_posicao
self.historico.append(nova_posicao)
else:
print("Destino alcançado")
O agente se move célula por célula, atualizando a posição e registrando no histórico.
6. Execução da Ação
def agir(self):
if not self.caminho:
self.planejar_rota()
self.mover()
Se o agente ainda não tiver um caminho planejado, ele calcula a rota e inicia os movimentos.
7. Mapa do Ambiente
mapa = [
[0, 0, 0, 0, 1],
[0, 1, 1, 0, 1],
[0, 1, 0, 0, 0],
[0, 0, 0, 1, 0],
[1, 1, 0, 0, 0]
]
inicio = (0, 0)
destino = (4, 4)
0 representa caminhos livres.
1 representa obstáculos.
8. Função de Visualização
def desenhar_mapa(mapa, agente, historico):
plt.imshow(mapa, cmap="Greys", origin="upper")
plt.scatter(inicio[1], inicio[0], c="green", s=200, label="Início")
plt.scatter(destino[1], destino[0], c="red", s=200, label="Destino")
if historico:
y, x = zip(*historico)
plt.plot(x, y, c="blue", linewidth=2, label="Caminho")
plt.scatter(agente.posicao[1], agente.posicao[0], c="yellow", s=200, label="Agente")
plt.legend()
plt.pause(0.5)
plt.clf()
A função:
- Exibe o mapa.
- Marca início, destino e posição do agente.
- Desenha o caminho percorrido pelo agente.
9. Execução Principal
plt.figure(figsize=(8, 8))
plt.ion()
while agente.posicao != destino:
desenhar_mapa(mapa, agente, agente.historico)
agente.agir()
plt.ioff()
desenhar_mapa(mapa, agente, agente.historico)
plt.show()
Nessa parte:
plt.ion(): Ativa o modo interativo para animação.
while: O agente se move até alcançar o destino.
plt.ioff(): Desativa o modo interativo no final.
plt.show(): Mantém o gráfico aberto até que o usuário o feche.
Resumo
O código implementa um agente que:
- Usa o algoritmo A* para planejar a rota.
- Segue o caminho célula por célula.
- Exibe a movimentação em tempo real com matplotlib.
- Mantém o gráfico final aberto para análise.
Próximos Passos
- Expandir o mapa com novos obstáculos.
- Adicionar interatividade para definir início e destino dinamicamente.
- Incorporar mudanças no ambiente em tempo real.
Aplicações Reais de Agentes Deliberativos
1. Controle de Tráfego Urbano
Em cidades inteligentes, agentes deliberativos podem ser usados para otimizar o fluxo de tráfego. Semáforos equipados com sensores podem se comunicar para ajustar os tempos de luz verde e minimizar engarrafamentos.
2. Navegação Autônoma
Veículos autônomos usam agentes deliberativos para planejar rotas, evitando obstáculos e reagindo a mudanças no ambiente em tempo real.
3. Planejamento Logístico
Empresas de transporte utilizam agentes deliberativos para planejar rotas eficientes de entrega, levando em conta fatores como tráfego, clima e urgência.
4. Simulação de Mercados
Em simulações financeiras, agentes deliberativos podem representar investidores que analisam dados do mercado e tomam decisões para maximizar retornos.
Extensões para o Futuro
Na próxima aula, exploraremos como integrar APIs externas, como a API do DeepSeek, para criar agentes ainda mais poderosos. Essas ferramentas permitem que os agentes acessem dados externos em tempo real, expandindo suas capacidades e aplicações.
Conclusão
Os agentes deliberativos são fundamentais em sistemas complexos, oferecendo capacidade de planejamento e adaptação. Com o exemplo prático de planejamento de rotas e as aplicações reais, esperamos que você tenha compreendido o potencial desses agentes.
Prepare-se para a próxima aula, onde daremos o próximo passo na criação de sistemas multi-agentes mais sofisticados!