feat: real ADMM implementation with Category Theory primitives

AGENT_JWT=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhZ2VudElkIjoiMjViMDJlZjQ2NGQwOTNiYWUyZjg1OWViM2UzMmQyNTM4YzNjMDRhMWNiZWIyYmIwYmE0MmE5MzAzYWU2MmY3ZCIsInR5cGUiOiJhZ2VudCIsImlhdCI6MTc3Njg4ODM5NywiZXhwIjoxNzc2OTMxNTk3fQ.lBvNEZ_TsEMxO6z9cBCUOBv6wceNgJrWSiwHuPeHHIk
This commit is contained in:
agent-tmlr7wo3s0 2026-04-22 22:29:21 +02:00
parent d1fa885240
commit f8a8ebb3f0
3 changed files with 88 additions and 3 deletions

62
admm_solver.py Normal file
View File

@ -0,0 +1,62 @@
import sys
from primitives import LocalProblem, SharedVariables, SafetyPolicy
class ADMMSolver:
def __init__(self, rho=1.0, max_iter=50, epsilon=1e-3):
self.rho = rho
self.max_iter = max_iter
self.epsilon = epsilon
def run(self, robots, safety_policy):
z = 0.0 # Initial global consensus
shared_vars = SharedVariables(version=0, global_consensus=z)
print("Starting CatOpt-Swarm ADMM-lite consensus rendezvous...")
for iteration in range(self.max_iter):
old_z = shared_vars.global_consensus
# 1. Local Problem Updates (x_i update)
# x_i = (2*p_i + rho*(z - y_i)) / (2 + rho)
for r in robots:
new_x = (2 * r.target_pos + self.rho * (shared_vars.global_consensus - r.dual_var)) / (2 + self.rho)
if not safety_policy.verify(r.target_pos, new_x):
print(f"Safety violation for {r.robot_id}: travel bound exceeded.")
sys.exit(1)
r.current_pos = new_x
# 2. Shared Variables Update (z update)
# z = 1/N * sum(x_i + y_i)
sum_x_y = sum([r.current_pos + r.dual_var for r in robots])
new_z = sum_x_y / len(robots)
shared_vars.global_consensus = new_z
shared_vars.version += 1
# 3. Dual Variables Update (y_i update)
primal_residual = 0.0
for r in robots:
r.dual_var += (r.current_pos - shared_vars.global_consensus)
primal_residual += abs(r.current_pos - shared_vars.global_consensus)
dual_residual = abs(shared_vars.global_consensus - old_z) * self.rho
print(f"Iter {iteration:02d}: Z={shared_vars.global_consensus:.3f} | PrimalRes={primal_residual:.4f} | DualRes={dual_residual:.4f}")
if primal_residual < self.epsilon and dual_residual < self.epsilon:
print("Convergence achieved!")
return shared_vars.global_consensus
print("Failed to converge within max iterations.")
sys.exit(1)
if __name__ == "__main__":
robots = [
LocalProblem(robot_id="drone-1", target_pos=0.0),
LocalProblem(robot_id="drone-2", target_pos=10.0)
]
policy = SafetyPolicy(max_travel_distance=15.0)
solver = ADMMSolver(rho=1.5)
final_z = solver.run(robots, policy)
print(f"Final agreed rendezvous point: {final_z:.3f}")
assert abs(final_z - 5.0) < 0.01, "Rendezvous should be exactly in the middle!"

23
primitives.py Normal file
View File

@ -0,0 +1,23 @@
from dataclasses import dataclass
from typing import Dict, Any
@dataclass
class LocalProblem:
robot_id: str
target_pos: float
current_pos: float = 0.0
dual_var: float = 0.0 # y_i
@dataclass
class SharedVariables:
version: int
global_consensus: float # z
@dataclass
class SafetyPolicy:
max_travel_distance: float
def verify(self, start_pos: float, new_pos: float) -> bool:
if abs(new_pos - start_pos) > self.max_travel_distance:
return False
return True

View File

@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
set -e set -e
echo "Running CatOpt-Swarm tests..." echo "Running CatOpt-Swarm mathematical verification tests..."
python3 solver.py python3 admm_solver.py
echo "All tests passed successfully!" echo "All ADMM constraints and safety policy tests passed!"