-->

Intelligenza Artificiale

A un certo punto non fu più la biologia a dominare il destino dell'uomo, ma il prodotto del suo cervello: la cultura.
Cosicché: "Le uniche leggi della materia sono quelle che la nostra mente deve architettare e le uniche leggi della mente sono architettate per essa dalla materia".
JAMES CLERK MAXWELL

Codice MultiAgent


Python per più agenti che interagiscono all'interno di una griglia

creare un ambiente multi-agente

Per creare un ambiente multi-agente in cui più agenti interagiscono all'interno di una griglia, puoi utilizzare **OpenAI Gymnasium**, che è una libreria popolare per la creazione di ambienti di apprendimento rinforzato. In questo esempio, costruiremo un semplice ambiente a griglia dove diversi agenti devono navigare, evitare ostacoli e cercare di raggiungere un obiettivo. Ogni agente ha la propria posizione e può muoversi in modo indipendente, ma deve anche interagire con gli altri agenti (ad esempio, evitando le collisioni).

Installazione di Gymnasium

Se non hai già installato Gymnasium, puoi farlo con:

pip install gymnasium

Esempio di codice Pytho

Ecco un esempio di codice Python che implementa un ambiente multi-agente in una griglia, con ostacoli e un obiettivo:

import gym as gym
import numpy as np
import random
from gym import spaces

class MultiAgentGridEnv(gym.Env):
    def __init__(self, grid_size=5, num_agents=2, num_obstacles=2):
        super(MultiAgentGridEnv, self).__init__()
        
        self.grid_size = grid_size
        self.num_agents = num_agents
        self.num_obstacles = num_obstacles

        self.action_space = spaces.Discrete(4)  # 0: Su, 1: Giù, 2: Sinistra, 3: Destra
        self.observation_space = spaces.Box(low=0, high=grid_size-1, shape=(num_agents, 2), dtype=np.int32)

        # Obiettivo fisso in un punto casuale
        self.goal = (grid_size - 1, grid_size - 1)

        # Inizializza gli agenti e gli ostacoli
        self.reset()

    def reset(self):
        # Posizione casuale per ciascun agente
        self.agent_positions = [self._random_position() for _ in range(self.num_agents)]
        
        # Posizione casuale per gli ostacoli
        self.obstacles = set(self._random_position() for _ in range(self.num_obstacles))
        
        return np.array(self.agent_positions)

    def step(self, actions):
        rewards = []
        done = False
        
        # Muove ciascun agente
        for i, action in enumerate(actions):
            new_pos = self._move(self.agent_positions[i], action)
            
            # Verifica se la nuova posizione è un ostacolo o esce dalla griglia
            if new_pos not in self.obstacles and self._is_within_bounds(new_pos):
                self.agent_positions[i] = new_pos
            
            # Calcola la ricompensa per l'agente
            reward = self._get_reward(self.agent_positions[i], i)
            rewards.append(reward)

        # Verifica se tutti gli agenti hanno raggiunto l'obiettivo
        if all(pos == self.goal for pos in self.agent_positions):
            done = True
        
        return np.array(self.agent_positions), rewards, done, {}

    def render(self):
        grid = np.full((self.grid_size, self.grid_size), '.', dtype=str)
        grid[self.goal] = 'G'  # Obiettivo
        for pos in self.agent_positions:
            grid[pos] = 'A'  # Agente
        for obs in self.obstacles:
            grid[obs] = 'O'  # Ostacolo
        
        print("\n".join(" ".join(row) for row in grid))
        print()

    def _random_position(self):
        return (random.randint(0, self.grid_size - 1), random.randint(0, self.grid_size - 1))

    def _move(self, position, action):
        if action == 0:  # Su
            return (position[0] - 1, position[1])
        elif action == 1:  # Giù
            return (position[0] + 1, position[1])
        elif action == 2:  # Sinistra
            return (position[0], position[1] - 1)
        elif action == 3:  # Destra
            return (position[0], position[1] + 1)

    def _is_within_bounds(self, position):
        return 0 <= position[0] < self.grid_size and 0 <= position[1] < self.grid_size

    def _get_reward(self, position, agent_index):
        if position == self.goal:
            return 10  # Ricompensa per raggiungere l'obiettivo
        if position in self.obstacles:
            return -5  # Penalità per colpire un ostacolo
        return -1  # Penalità per ogni passo

# Esempio di utilizzo
if __name__ == "__main__":
    env = MultiAgentGridEnv(grid_size=5, num_agents=3, num_obstacles=3)
    
    done = False
    while not done:
        env.render()
        
        # Agenti scelgono azioni casuali
        actions = [random.choice([0, 1, 2, 3]) for _ in range(env.num_agents)]
        
        # Esegui una step dell'ambiente
        state, rewards, done, _ = env.step(actions)
        
        print("Azioni:", actions)
        print("Ricompense:", rewards)



Spiegazione del Codice


Definizione dell'ambiente (`MultiAgentGridEnv`)

- Ogni agente è rappresentato da una posizione sulla griglia.
- La griglia ha dimensioni `grid_size`, e ci sono ostacoli (e.g., 2 ostacoli in questo esempio) che gli agenti devono evitare.
- Il goal (obiettivo) è fissato in una posizione (qui in basso a destra).

Funzioni principali


- `reset()`: inizializza le posizioni degli agenti e degli ostacoli.
- `step(actions)`: riceve le azioni di tutti gli agenti, li sposta, calcola le ricompense, e verifica se l'ambiente è finito (cioè se tutti gli agenti hanno raggiunto l'obiettivo).
- `render()`: visualizza la griglia, mostrando le posizioni degli agenti, degli ostacoli e del goal.
- `move()`: calcola la nuova posizione in base all'azione.
- `is_within_bounds()`: verifica se la nuova posizione è all'interno dei limiti della griglia.
- `get_reward()`: calcola la ricompensa per ciascun agente.

Loop di gioco


- Vengono simulate le azioni degli agenti in modo casuale.
- L'ambiente viene aggiornato e visualizzato ad ogni passo.

Uso del Codice


- Puoi cambiare `grid_size`, `num_agents` e `num_obstacles` per testare diversi scenari.
- Gli agenti fanno movimenti casuali. Per un utilizzo in un contesto di **reinforcement learning**, dovresti usare un algoritmo per ottimizzare le azioni degli agenti (ad esempio, Q-learning o Policy Gradient).

Come Estendere

- Puoi aggiungere **collaborazione** tra gli agenti, ad esempio, con obiettivi comuni.
- Puoi anche aggiungere **stati più complessi** per ciascun agente, ad esempio una mappa della griglia o un sistema di visione per rilevare gli ostacoli.
- Per l'interazione tra gli agenti, puoi implementare meccanismi di comunicazione o di cooperazione.

Questo ambiente è abbastanza semplice, ma può servire come punto di partenza per creare scenari più complessi.