Skip to content

Types

Core types used across all solvOR solvers.

Overview

Every solver returns a Result object containing the solution, objective value, and status information. The Status enum tells you whether the solve succeeded, and Progress is used for monitoring long-running solvers.

Type Purpose
Result[T] Returned by all solvers - contains solution, objective, status, iterations, evaluations
Status Enum: OPTIMAL, FEASIBLE, INFEASIBLE, UNBOUNDED, MAX_ITER
Progress Progress info passed to on_progress callbacks during optimization
ProgressCallback Type alias for progress callback functions

Result

The Result dataclass is generic over the solution type. Common fields:

result.solution    # The best solution found (type depends on solver)
result.objective   # Objective value (float)
result.iterations  # Number of solver iterations
result.evaluations # Number of objective function evaluations
result.status      # Status enum value
result.ok          # True if OPTIMAL or FEASIBLE
result.error       # Error message if failed (None on success)
result.solutions   # Multiple solutions when solution_limit > 1

Status Values

Status Meaning
OPTIMAL Proven optimal solution (exact solvers)
FEASIBLE Feasible but not proven optimal (heuristics)
INFEASIBLE No feasible solution exists
UNBOUNDED Objective can improve infinitely
MAX_ITER Iteration limit reached

Quick Usage

from solvor import solve_lp, Status

result = solve_lp(c=[1, 2], A=[[1, 1]], b=[4])

if result.ok:  # True if OPTIMAL or FEASIBLE
    print(result.solution)
    print(result.objective)
elif result.status == Status.INFEASIBLE:
    print("No solution exists")

Progress Callbacks

Long-running solvers support progress monitoring via callbacks:

from solvor import anneal, Progress

def monitor(p: Progress) -> bool | None:
    print(f"iter {p.iteration}: obj={p.objective}, best={p.best}")
    if p.objective < 0.01:  # Early stopping
        return True
    return None

result = anneal(initial, cost_fn, neighbors, on_progress=monitor, progress_interval=100)

Reference

solvor.types

Shared types for all solvers.

Core data structures returned by solvers and used for progress tracking.

from solvor.types import Result, Status, Progress

result = solve_lp(c, A, b)
if result.ok:
    print(f"Solution: {result.solution}, cost: {result.objective}")

Progress dataclass

Solver progress info passed to callbacks.

Attributes:

Name Type Description
iteration int

Current iteration number

objective float

Current objective value

best float | None

Best objective found so far (None if same as objective)

evaluations int

Number of objective function evaluations

Source code in solvor/types.py
@dataclass(frozen=True, slots=True)
class Progress:
    """Solver progress info passed to callbacks.

    Attributes:
        iteration: Current iteration number
        objective: Current objective value
        best: Best objective found so far (None if same as objective)
        evaluations: Number of objective function evaluations
    """

    iteration: int
    objective: float
    best: float | None = None
    evaluations: int = 0

Result dataclass

Solver result containing solution, objective, and metadata.

Attributes:

Name Type Description
solution T

The solution found (type varies by solver)

objective float

Objective value (cost, distance, makespan, etc.)

iterations int

Number of iterations performed

evaluations int

Number of objective function evaluations

status Status

Outcome status (OPTIMAL, FEASIBLE, INFEASIBLE, etc.)

error str | None

Error message if status indicates failure

solutions tuple[T, ...] | None

Multiple solutions when solution_limit > 1

Source code in solvor/types.py
@dataclass(frozen=True, slots=True)
class Result[T]:
    """Solver result containing solution, objective, and metadata.

    Attributes:
        solution: The solution found (type varies by solver)
        objective: Objective value (cost, distance, makespan, etc.)
        iterations: Number of iterations performed
        evaluations: Number of objective function evaluations
        status: Outcome status (OPTIMAL, FEASIBLE, INFEASIBLE, etc.)
        error: Error message if status indicates failure
        solutions: Multiple solutions when solution_limit > 1
    """

    solution: T
    objective: float
    iterations: int = 0
    evaluations: int = 0
    status: Status = Status.OPTIMAL
    error: str | None = None
    solutions: tuple[T, ...] | None = None

    @property
    def ok(self) -> bool:
        """True if solution is usable (OPTIMAL or FEASIBLE)."""
        return self.status in (Status.OPTIMAL, Status.FEASIBLE)

    def log(self, prefix: str = "") -> "Result":
        """Print debug info if DEBUG=1. Returns self for chaining."""
        if _DEBUG:
            msg = f"{prefix}{self.status.name}: obj={self.objective}, iter={self.iterations}"
            if self.error:
                msg += f" - {self.error}"
            print(msg)
        return self

    def __repr__(self) -> str:
        """Concise representation for debugging."""
        return f"Result({self.status.name}, obj={self.objective:.6g}, iter={self.iterations})"

ok property

True if solution is usable (OPTIMAL or FEASIBLE).

__repr__()

Concise representation for debugging.

Source code in solvor/types.py
def __repr__(self) -> str:
    """Concise representation for debugging."""
    return f"Result({self.status.name}, obj={self.objective:.6g}, iter={self.iterations})"

log(prefix='')

Print debug info if DEBUG=1. Returns self for chaining.

Source code in solvor/types.py
def log(self, prefix: str = "") -> "Result":
    """Print debug info if DEBUG=1. Returns self for chaining."""
    if _DEBUG:
        msg = f"{prefix}{self.status.name}: obj={self.objective}, iter={self.iterations}"
        if self.error:
            msg += f" - {self.error}"
        print(msg)
    return self

Status

Bases: IntEnum

Solver outcome status.

Source code in solvor/types.py
class Status(IntEnum):
    """Solver outcome status."""

    OPTIMAL = auto()  # Proven optimal (exact solvers)
    FEASIBLE = auto()  # Feasible but not proven optimal (heuristics)
    INFEASIBLE = auto()  # No feasible solution exists
    UNBOUNDED = auto()  # Objective can improve infinitely
    MAX_ITER = auto()  # Iteration limit reached