OptiQ / api /routes /optimize.py
mohammademad2003's picture
first commit
7477316
"""
Optimize endpoint — Runs the hybrid Quantum-AI-Classical pipeline.
Supports all solver modes: classical, quantum, ai, hybrid.
"""
from __future__ import annotations
import time
from fastapi import APIRouter, HTTPException
from pydantic import BaseModel, Field
from src.grid.loader import load_network
from src.grid.power_flow import get_baseline, evaluate_topology
from src.grid.reconfiguration import branch_exchange_search
from src.hybrid.pipeline import run_hybrid_pipeline
from src.evaluation.metrics import compute_impact, compute_speedup
router = APIRouter()
class OptimizeRequest(BaseModel):
system: str = Field(default="case33bw", description="IEEE test system name")
method: str = Field(
default="hybrid",
description="Optimization method: 'classical', 'quantum', 'ai', or 'hybrid'",
)
quantum_iters: int = Field(default=300, description="SA iterations for quantum solver")
quantum_restarts: int = Field(default=3, description="SA restarts")
quantum_top_k: int = Field(default=5, description="Number of candidate topologies")
open_lines: list[int] | None = Field(
default=None,
description="User's current open lines to use as starting point for optimisation",
)
@router.post("/optimize")
def optimize(req: OptimizeRequest):
"""Run optimization on the specified IEEE system."""
try:
net = load_network(req.system)
except ValueError as exc:
raise HTTPException(status_code=400, detail=str(exc))
baseline = get_baseline(net)
if not baseline.get("converged"):
raise HTTPException(status_code=500, detail="Baseline did not converge.")
t_start = time.perf_counter()
if req.method == "classical":
result = branch_exchange_search(net, verbose=False, initial_open_lines=req.open_lines)
if "error" in result:
raise HTTPException(status_code=500, detail=result["error"])
optimized = evaluate_topology(net, result["best_open_lines"])
if not optimized.get("converged"):
raise HTTPException(status_code=500, detail="Optimized topology did not converge.")
t_end = time.perf_counter()
impact = compute_impact(baseline, optimized)
return {
"system": req.system,
"method": "classical",
"baseline": baseline,
"optimized": optimized,
"impact": impact,
"solver": {
"method": "branch_exchange",
"iterations": result["iterations"],
"time_sec": result["time_sec"],
},
"total_time_sec": round(t_end - t_start, 4),
}
elif req.method in ("quantum", "hybrid", "ai"):
use_quantum = req.method in ("quantum", "hybrid")
use_ai = req.method in ("ai", "hybrid")
pipeline_result = run_hybrid_pipeline(
net,
use_quantum=use_quantum,
use_ai=use_ai,
quantum_iters=req.quantum_iters,
quantum_restarts=req.quantum_restarts,
quantum_top_k=req.quantum_top_k,
initial_open_lines=req.open_lines,
)
if "error" in pipeline_result:
raise HTTPException(status_code=500, detail=pipeline_result["error"])
return {
"system": req.system,
"method": pipeline_result["method"],
"baseline": pipeline_result["baseline"],
"optimized": pipeline_result["optimized"],
"impact": pipeline_result["impact"],
"candidates": pipeline_result.get("all_evaluated", []),
"timings": pipeline_result["timings"],
"total_time_sec": pipeline_result["timings"]["total_sec"],
}
else:
raise HTTPException(status_code=400, detail=f"Unknown method: {req.method}")