In Action: Optimization Solver API

Vibe Prompt

"Build a general-purpose optimization API with FastAPI: users input an objective function and bounds, and the backend solves it using simulated annealing."

from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
import random, math

app = FastAPI(title="Optimization Solver API")

class OptimizeRequest(BaseModel):
    objective: str  # Mathematical expression, e.g. "x**2 + y**2"
    bounds: list[list[float]]  # [[x_min,x_max], [y_min,y_max]]
    algorithm: str = "simulated_annealing"

class OptimizeResponse(BaseModel):
    best_solution: list[float]
    best_value: float
    algorithm: str
    iterations: int

@app.post("/optimize", response_model=OptimizeResponse)
def optimize(req: OptimizeRequest):
    dim = len(req.bounds)
    
    def objective(x):
        # Safe eval
        env = {"x": x} if dim == 1 else {f"x{i}": x[i] for i in range(dim)}
        env.update({"sin": math.sin, "cos": math.cos, "sqrt": math.sqrt,
                     "abs": abs, "sum": sum, "pow": pow})
        return eval(req.objective, {"__builtins__": {}}, env)
    
    best = None
    best_val = float('inf')
    
    if req.algorithm == "simulated_annealing":
        current = [random.uniform(b[0], b[1]) for b in req.bounds]
        current_val = objective(current)
        temp = 1000
        iterations = 0
        
        while temp > 0.01:
            neighbor = [current[i] + random.uniform(-1, 1) for i in range(dim)]
            neighbor = [max(req.bounds[i][0], min(req.bounds[i][1], neighbor[i])) 
                       for i in range(dim)]
            neighbor_val = objective(neighbor)
            delta = neighbor_val - current_val
            
            if delta < 0 or random.random() < math.exp(-delta/temp):
                current = neighbor
                current_val = neighbor_val
                if current_val < best_val:
                    best = current[:]
                    best_val = current_val
            
            temp *= 0.995
            iterations += 1
    
    return OptimizeResponse(
        best_solution=best, best_value=round(best_val, 6),
        algorithm=req.algorithm, iterations=iterations
    )

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8000)

Summary

  • ✅ Simulated Annealing
  • ✅ Genetic Algorithms
  • ✅ PSO
  • ✅ Hyperparameter Tuning
  • ✅ Optimization API

Chapter Summary

  • Understand the core concepts and theory
  • Master implementation methods and techniques
  • Learn common issues and their solutions
  • Apply knowledge to real-world projects

Further Reading

  • Official documentation and API references
  • Open source projects on GitHub
  • Related technical books and courses
  • Community discussions and technical blogs

Implementation Examples

Basic Examples

# This section provides a complete implementation example
# to help you apply what you've learned to real projects

Steps

  1. Initialization: Set up the development environment and required tools
  2. Data Preparation: Collect and organize the required data
  3. Core Implementation: Implement the main functionality and logic
  4. Testing & Validation: Ensure the functionality works correctly
  5. Optimization: Tune performance and user experience

Common Errors

| Error Type | Possible Cause | Solution | |-----------|---------------|----------| | Compilation Error | Syntax issues | Check code syntax | | Runtime Error | Environment issues | Verify dependencies are installed | | Logic Error | Algorithm issues | Step-by-step debugging and testing | | Performance Issue | Efficiency issues | Use performance analysis tools |

Code Example

# Example code
import sys

def main():
    # Main program logic
    print("Hello, World!")

if __name__ == "__main__":
    main()

Optimization API Architecture

A well-designed optimization API separates the algorithm from the problem definition.

API Design

| Endpoint | Method | Description | |----------|--------|-------------| | /optimize | POST | Run optimization with specified algorithm and problem | | /status/{job_id} | GET | Check optimization progress | | /results/{job_id} | GET | Get optimization results | | /algorithms | GET | List available algorithms |

Request Format

{
  "algorithm": "genetic_algorithm",
  "parameters": {
    "pop_size": 100,
    "mutation_rate": 0.01,
    "crossover_rate": 0.8,
    "generations": 200
  },
  "problem": {
    "type": "max_one",
    "dimensions": 50
  }
}

Response Format

{
  "job_id": "opt-abc123",
  "status": "completed",
  "best_solution": [1, 1, 0, 1, ...],
  "best_fitness": 47,
  "history": [
    {"generation": 0, "best": 25, "avg": 24.3},
    {"generation": 50, "best": 42, "avg": 38.7},
    {"generation": 200, "best": 47, "avg": 45.2}
  ],
  "runtime_seconds": 12.5
}

FastAPI Implementation

from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from typing import Literal
import uuid
import time

app = FastAPI(title="Optimization API")

# In-memory job store
jobs = {}

class OptimizeRequest(BaseModel):
    algorithm: Literal["genetic_algorithm", "simulated_annealing", "pso"]
    parameters: dict
    problem: dict

@app.post("/optimize")
async def optimize(request: OptimizeRequest):
    job_id = str(uuid.uuid4())[:8]
    jobs[job_id] = {
        "status": "running",
        "algorithm": request.algorithm,
        "started_at": time.time()
    }
    
    # Run optimization in background (simplified)
    result = run_algorithm(request.algorithm, request.parameters, request.problem)
    
    jobs[job_id]["status"] = "completed"
    jobs[job_id]["result"] = result
    
    return {"job_id": job_id, "status": "completed", "result": result}

@app.get("/algorithms")
async def list_algorithms():
    return {
        "algorithms": [
            {
                "name": "genetic_algorithm",
                "description": "Population-based evolutionary algorithm",
                "parameters": ["pop_size", "mutation_rate", "crossover_rate", "generations"]
            },
            {
                "name": "simulated_annealing",
                "description": "Single-solution with probabilistic escape",
                "parameters": ["T0", "alpha", "max_iter"]
            },
            {
                "name": "pso",
                "description": "Particle swarm optimization",
                "parameters": ["swarm_size", "w", "c1", "c2", "max_iter"]
            }
        ]
    }

Running Optimization Jobs

Track progress and retrieve results asynchronously.

@app.get("/status/{job_id}")
async def get_status(job_id: str):
    job = jobs.get(job_id)
    if not job:
        raise HTTPException(status_code=404, detail="Job not found")
    return {"job_id": job_id, "status": job["status"]}

@app.get("/results/{job_id}")
async def get_results(job_id: str):
    job = jobs.get(job_id)
    if not job:
        raise HTTPException(status_code=404, detail="Job not found")
    if job["status"] != "completed":
        raise HTTPException(status_code=400, detail="Job not completed yet")
    return job["result"]

Summary

Building an optimization API lets users run metaheuristic algorithms programmatically. FastAPI provides the framework for exposing optimization as a service.

Key takeaways: | Optimization API: POST /optimize, GET /status, GET /results, GET /algorithms | | Request specifies algorithm, parameters, and problem definition | | Response includes job_id, best solution, fitness history, and runtime | | FastAPI: automatic OpenAPI docs, Pydantic validation, async by default | | Job tracking: status field (running/completed). Results retrieved separately | | Background execution: run optimization asynchronously, poll for completion | | Multiple algorithms: GA, SA, PSO available through the same interface |

You've completed this course! You now understand metaheuristic algorithms.

Unlock Full Tutorial

This chapter is paid content. Join the project to unlock over 5000 words of deep analysis, including 10+ god-tier Prompts and real Source Code examples!