Simulated Annealing#

Source: examples/patterns/simulated_annealing.py

Introduction#

Simulated annealing is useful when a design space has a numeric objective, lightweight constraints, and local moves that may temporarily get worse before finding a better basin. This example keeps the delegates deterministic so the runtime contract is easy to inspect without an LLM dependency.

Technical Implementation#

  1. Define a local objective delegate for a one-dimensional quadratic target.

  2. Define a neighbor delegate that proposes bounded local moves.

  3. Execute SimulatedAnnealingPattern.run(...) through the public patterns API.

  4. Print a compact JSON payload for deterministic tests and docs examples.

        flowchart LR
    A["Initial state"] --> B["SimulatedAnnealingPattern.run(...)"]
    B --> C["neighbor_delegate proposes local moves"]
    C --> D["objective_delegate scores each state"]
    D --> E["Metropolis acceptance + convergence checks"]
    E --> F["ExecutionResult/payload"]
    F --> G["Printed JSON output"]
    
 1from __future__ import annotations
 2
 3import json
 4from collections.abc import Mapping
 5
 6from design_research_agents import (
 7    AdaptiveSchedule,
 8    ExponentialSchedule,
 9    LinearSchedule,
10    LogarithmicSchedule,
11    SimulatedAnnealingPattern,
12    TemperatureSchedule,
13)
14
15_SCHEDULES = [
16    LinearSchedule(alpha=10.0),
17    ExponentialSchedule(alpha=0.95),
18    LogarithmicSchedule(c=100.0, d=2.0),
19    AdaptiveSchedule(delta=0.5),
20]
21assert all(isinstance(s, TemperatureSchedule) for s in _SCHEDULES)
22
23
24def _state_float(state: Mapping[str, object], key: str) -> float:
25    value = state[key]
26    if not isinstance(value, (int, float)):
27        raise ValueError(f"{key} must be numeric.")
28    return float(value)
29
30
31def main() -> None:
32    """Run one deterministic local simulated annealing workflow."""
33
34    def objective_delegate(state: Mapping[str, object]) -> float:
35        x = _state_float(state, "x")
36        return (x - 3.0) ** 2
37
38    def neighbor_delegate(state: Mapping[str, object]) -> Mapping[str, object]:
39        x = _state_float(state, "x")
40        step = 1.0 if x < 3.0 else -1.0
41        return {"x": x + step}
42
43    pattern = SimulatedAnnealingPattern(
44        neighbor_delegate=neighbor_delegate,
45        objective_delegate=objective_delegate,
46        initial_state={"x": 0.0},
47        expected_keys={"x"},
48        state_validator=lambda state: -10.0 <= _state_float(state, "x") <= 10.0,
49        initial_temperature=1.0,
50        max_iterations=6,
51        convergence_steps=3,
52        random_seed=7,
53    )
54    result = pattern.run(
55        "Minimize the distance from x to the target value 3.",
56        request_id="example-pattern-simulated-annealing-001",
57    )
58
59    final_output = result.output["final_output"]
60    print(
61        json.dumps(
62            {
63                "success": result.success,
64                "best_state": final_output["best_state"],
65                "best_objective_value": final_output["best_objective_value"],
66                "iterations": final_output["iterations"],
67                "terminated_reason": result.output["terminated_reason"],
68            },
69            ensure_ascii=True,
70            indent=2,
71            sort_keys=True,
72        )
73    )
74
75
76if __name__ == "__main__":
77    main()

Expected Results#

Run Command

PYTHONPATH=src python3 examples/patterns/simulated_annealing.py

Example output shape:

{
  "best_objective_value": 0.0,
  "best_state": {
    "x": 3.0
  },
  "iterations": 6,
  "success": true,
  "terminated_reason": "max_iterations_reached"
}

References#