Una guía de codificación para construir un sistema logístico autónomo de múltiples agentes con planificación de rutas, subastas dinámicas y visualización en tiempo real mediante simulación basada en gráficos

En este tutorial, creamos una simulación logística avanzada y totalmente autónoma en la que múltiples camiones de reparto inteligentes operan dentro de una red de carreteras dinámica en toda la ciudad. Diseñamos el sistema para que cada camión se comporte como un agente capaz de pujar por los pedidos de entrega, planificar rutas óptimas, gestionar los niveles de batería, buscar estaciones de carga y maximizar los beneficios mediante una toma de decisiones interesada. A través de cada fragmento de código, exploramos cómo los comportamientos de agencia surgen de reglas simples, cómo la competencia da forma a la asignación de pedidos y cómo un mundo basado en gráficos permite restricciones realistas de movimiento, enrutamiento y recursos. Consulta los CÓDIGOS COMPLETOS aquí.

importar networkx como nx importar matplotlib.pyplot como plt importar tiempo de importación aleatorio desde IPython.display importar clear_output desde clases de datos importar clase de datos, campo desde escribir import List, Dict, opcional NUM_NODES = 30 CONNECTION_RADIUS = 0.25 NUM_AGENTS = 5 STARTING_BALANCE = 1000 FUEL_PRICE = 2.0 PAYOUT_MULTIPLIER = 5.0 BATTERY_CAPACITY = 100 CRITICAL_BATTERY = 25 @dataclass clase Orden: id: str target_node: int peso_kg: int pago: float estado: str = clase “pendiente” AgenticTruck: def __init__(self, agent_id, start_node, gráfico, capacidad=100): self.id = agent_id self.current_node = start_node self.graph = gráfico self.battery = BATTERY_CAPACITY self.balance = STARTING_BALANCE self.capacity = capacidad self.state = “IDLE” self.path: Lista[int] = []
self.current_order: Opcional[Order] = Ninguno self.target_node: int = start_node

Configuramos todos los componentes básicos de la simulación, incluidas las importaciones, los parámetros globales y las estructuras de datos básicas. También definimos la clase AgenticTruck e inicializamos atributos clave, incluida la posición, la batería, el equilibrio y el estado operativo. Sentamos las bases para que evolucionen todos los comportamientos de los agentes. Consulta los CÓDIGOS COMPLETOS aquí.

def get_path_cost(self, start, end): prueba: longitud = nx.shortest_path_length(self.graph, start, end, peso=”weight”) ruta = nx.shortest_path(self.graph, start, end, peso=”weight”) longitud de retorno, ruta excepto nx.NetworkXNoPath: return float(‘inf’), []

def find_nearest_charger(self): cargadores = [n for n, attr in self.graph.nodes(data=True) if attr.get(‘type’) == ‘charger’]
best_charger = Ninguno min_dist = float(‘inf’) best_path = []
para cargador en cargadores: dist, ruta = self.get_path_cost(self.current_node, cargador) if dist < min_dist: min_dist = dist best_charger = cargador best_path = ruta return mejor_cargador, mejor_ruta def calcular_bid(self, orden): if order.weight_kg > self.capacity: return float(‘inf’) if self.state != “IDLE” o self.battery < BATERÍA_CRÍTICA: return float('inf') dist_to_target, _ = self.get_path_cost(self.current_node, order.target_node) costo_combustible = dist_to_target * PRECIO_COMBUSTIBLE beneficio_esperado = pedido.pago - costo_combustible si beneficio_esperado < 10: return float('inf') return dist_to_target def asignar_orden(self, orden): self.current_order = orden self.state = "MOVING" self.target_node = order.target_node _, self.path = self.get_path_cost(self.current_node, self.target_node) if self.path: self.path.pop(0) def go_charge(self): cargador_nodo, ruta = self.find_nearest_charger() si el cargador_nodo no es Ninguno: self.state = "TO_CHARGER" self.target_node = cargador_nodo self.path = ruta si self.path: self.path.pop(0)

Implementamos lógica avanzada de toma de decisiones para los camiones. Calculamos los caminos más cortos, identificamos estaciones de carga cercanas y evaluamos si un pedido es rentable y factible. También preparamos el camión para aceptar asignaciones o buscar cargas de manera proactiva cuando sea necesario. Consulta los CÓDIGOS COMPLETOS aquí.

def paso(self): if self.state == “IDLE” and self.battery < CRITICAL_BATTERY: self.go_charge() if self.state == "CHARGING": self.battery += 10 self.balance -= 5 if self.battery >= 100: self.battery = 100 self.state = “IDLE” return if self.path: next_node = self.path[0]
edge_data = self.graph.get_edge_data(self.current_node, next_node) distancia = edge_data[‘weight’]
self.current_node = next_node self.path.pop(0) self.battery -= (distancia * 2) self.balance -= (distancia * PRECIO_COMBUSTIBLE) si no self.path: if self.state == “EN MOVIMIENTO”: self.balance += self.current_order.payout self.current_order.status = “completado” self.current_order = Ninguno self.state = “IDLE” elif self.state == “TO_CHARGER”: self.state = “CARGANDO”

Gestionamos las acciones paso a paso de cada camión mientras se ejecuta la simulación. Nos encargamos de la recarga de baterías, los impactos financieros del movimiento, el consumo de combustible y la finalización de pedidos. Nos aseguramos de que los agentes realicen una transición fluida entre estados, como en movimiento, cargando e inactivo. Consulta los CÓDIGOS COMPLETOS aquí.

Simulación de clase: def __init__(self): self.setup_graph() self.setup_agents() self.orders = []
self.order_count = 0 def setup_graph(self): self.G = nx.random_geometric_graph(NUM_NODES, CONNECTION_RADIUS) para (u, v) en self.G.edges(): self.G.edges[u, v][‘weight’] = random.uniform(1.0, 3.0) para i en self.G.nodes(): r = random.random() si r < 0,15: self.G.nodes[i]['type'] = 'cargador' self.G.nodos[i]['color'] = 'rojo' else: self.G.nodes[i]['type'] = 'casa' self.G.nodos[i]['color'] = '#A0CBE2' def setup_agents(self): self.agents = [] para i en el rango (NUM_AGENTS): start_node = random.randint(0, NUM_NODES-1) cap = random.choice([50, 100, 200]) self.agents.append(AgenticTruck(i, start_node, self.G, capacidad=cap)) def generate_order(self): objetivo = random.randint(0, NUM_NODES-1) peso = random.randint(10, 120) pago = random.randint(50, 200) orden = Orden(id=f"ORD-{self.order_count}", target_node=objetivo, peso_kg=peso, pago=pago) self.orders.append(order) self.order_count += 1 orden de devolución def run_market(self): para orden en self.orders: if order.status == "pendiente": ofertas = {agente: agente.calcular_bid(orden) para agente en self.agents} valid_bids = {k: v para k, v en bids.items() if v != float('inf')} if valid_bids: ganador = min(valid_bids, key=valid_bids.get) ganador.assign_order(order) order.status = "asignado"

Creamos el mundo simulado y organizamos las interacciones de los agentes. Generamos la ciudad basada en gráficos, generamos camiones con diferentes capacidades y producimos nuevos pedidos de entrega. También implementamos un mercado simple donde los agentes ofertan por tareas en función de la rentabilidad y la distancia. Consulta los CÓDIGOS COMPLETOS aquí.

def paso(self): si random.random() < 0.3: self.generate_order() self.run_market() para agente en self.agents: agente.step() def visualizar(self, step_num): clear_output(wait=True) plt.figure(figsize=(10, 8)) pos = nx.get_node_attributes(self.G, 'pos') node_colors = [self.G.nodes[n]['color'] para n en self.G.nodes()]nx.draw(self.G, pos, node_color=node_colors, with_labels=True, node_size=300, edge_color="gray", alpha=0.6) para agente en self.agents: x, y = pos[agent.current_node] jitter_x = x + random.uniform(-0.02, 0.02) jitter_y = y + random.uniform(-0.02, 0.02) color="verde" si agente.estado == "IDLE" else ('naranja' si agente.estado == "EN MOVIMIENTO" else 'rojo') plt.plot(jitter_x, jitter_y, marcador="s", tamaño de marcador=12, color=color, Markeredgecolor="black") plt.text(jitter_x, jitter_y+0.03, f"A{agent.id}\n${int(agent.balance)}\n{int(agent.battery)}%", fontsize=8, ha="center", fontweight="bold", bbox=dict(facecolor="white", alpha=0.7, pad=1)) para orden en self.orders: si order.status en ["assigned", "pending"]: buey, oy = pos[order.target_node] plt.plot(ox, oy, Marker="*", Markersize=15, color="gold", Markeredgecolor="black") plt.title(f"Enjambre de logística basada en gráficos | Paso: {step_num}\nNodos rojos = Cargadores | Estrellas doradas = Órdenes", fontsize=14) plt.show() print("Inicializando simulación avanzada...") sim = Simulación() for t in range(60): sim.step() sim.visualize

Pasamos por el ciclo completo de simulación y visualizamos el enjambre logístico en tiempo real. Actualizamos los estados de los agentes, dibujamos la red, mostramos pedidos activos y animamos el movimiento de cada camión. Al ejecutar este ciclo, observamos la coordinación y competencia emergentes que definen nuestro ecosistema logístico de múltiples agentes.

En conclusión, vimos cómo los componentes individuales, la generación de gráficos, el enrutamiento autónomo, la gestión de baterías, las subastas y la visualización, se unen para formar un sistema vivo y en evolución de camiones agentes. Observamos cómo los agentes negocian cargas de trabajo, compiten por oportunidades rentables y responden a presiones ambientales como la distancia, los costos de combustible y las necesidades de carga. Al ejecutar la simulación, observamos dinámicas emergentes que reflejan el comportamiento de la flota en el mundo real, proporcionando una poderosa zona de pruebas para experimentar con inteligencia logística.

Consulta los CÓDIGOS COMPLETOS aquí. Además, no dude en seguirnos en Twitter y no olvide unirse a nuestro SubReddit de más de 100.000 ML y suscribirse a nuestro boletín. ¡Esperar! estas en telegrama? Ahora también puedes unirte a nosotros en Telegram.

Asif Razzaq es el director ejecutivo de Marktechpost Media Inc.. Como empresario e ingeniero visionario, Asif está comprometido a aprovechar el potencial de la inteligencia artificial para el bien social. Su esfuerzo más reciente es el lanzamiento de una plataforma de medios de inteligencia artificial, Marktechpost, que se destaca por su cobertura en profundidad del aprendizaje automático y las noticias sobre aprendizaje profundo que es técnicamente sólida y fácilmente comprensible para una amplia audiencia. La plataforma cuenta con más de 2 millones de visitas mensuales, lo que ilustra su popularidad entre el público.