Problem definition¶
Wrap an objective function with make_problem, or implement the Problem interface. The guide explains scalar and vectorized evaluation, bounds, encodings, and constraints.
Stable public API. The 1.x compatibility policy defines the supported surface; import from the public facade shown below.
from vamos import Problem, make_problem
Solve your own problem · Built-in problem catalogue · Problem discovery
make_problem(fn, *, n_var, n_obj, bounds=None, xl=None, xu=None, vectorized=False, encoding, name=None, constraints=None, n_constraints=0)
¶
Create a VAMOS-compatible problem from a plain Python function.
This is the friendliest way to define a custom optimization problem. Your function receives decision variables and returns objective values -- VAMOS handles bounds, protocol adaptation, and optional batched execution.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
fn
|
callable
|
Objective function.
|
required |
n_var
|
int
|
Number of decision variables. |
required |
n_obj
|
int
|
Number of objectives to minimize. |
required |
bounds
|
sequence of (lower, upper) tuples
|
Per-variable bounds, e.g. |
None
|
xl
|
float or array - like
|
Lower / upper bounds for all variables. A scalar applies the same bound to every variable. Mutually exclusive with bounds. |
None
|
xu
|
float or array - like
|
Lower / upper bounds for all variables. A scalar applies the same bound to every variable. Mutually exclusive with bounds. |
None
|
vectorized
|
bool
|
If |
False
|
encoding
|
str
|
Variable encoding: |
required |
name
|
str
|
Human-readable name shown in logs and results. Defaults to the function name. |
None
|
constraints
|
callable
|
Constraint function following the same signature convention as
fn. Must return |
None
|
n_constraints
|
int
|
Number of constraint values. Required when constraints is provided. |
0
|
Returns:
| Type | Description |
|---|---|
FunctionalProblem
|
A problem object ready to pass to |
Raises:
| Type | Description |
|---|---|
TypeError
|
If fn is not callable. |
ValueError
|
If bounds and xl/xu are both provided, if bounds length does not match n_var, or if n_constraints > 0 but no constraints callable is given. |
Examples:
Minimal two-objective problem::
from vamos import make_problem, optimize
problem = make_problem(
lambda x: [x[0], 1 - x[0] ** 0.5],
n_var=2, n_obj=2,
bounds=[(0, 1), (0, 1)],
encoding="real",
)
result = optimize(problem, algorithm="nsgaii", max_evaluations=2000)
Vectorized for better performance::
import numpy as np
def my_objectives(X):
f1 = X[:, 0]
f2 = 1 - np.sqrt(X[:, 0])
return np.column_stack([f1, f2])
problem = make_problem(
my_objectives,
n_var=2, n_obj=2,
bounds=[(0, 1), (0, 1)],
vectorized=True,
encoding="real",
)
With constraints (g(x) <= 0 is feasible)::
problem = make_problem(
lambda x: [x[0] + x[1], x[0] * x[1]],
n_var=2, n_obj=2,
bounds=[(0, 5), (0, 5)],
encoding="real",
constraints=lambda x: [x[0] + x[1] - 4],
n_constraints=1,
)
Problem
¶
Base class for class-based custom optimization problems.
Subclass this when your problem needs state — a dataset, distance matrix,
simulator, or any data set up in __init__.
Required: set n_var, n_obj, xl, xu in __init__.
Optional: override encoding and n_constraints as class-level
attributes (not in __init__).
Example — unconstrained::
import numpy as np
from vamos import Problem, optimize
class MyProblem(Problem):
def __init__(self):
self.n_var = 3
self.n_obj = 2
self.xl = np.zeros(3)
self.xu = np.ones(3)
def objectives(self, X: np.ndarray) -> np.ndarray:
# X: (N, n_var) batch of candidate solutions
f1 = np.sum(X ** 2, axis=1)
f2 = np.sum((X - 1) ** 2, axis=1)
return np.column_stack([f1, f2])
result = optimize(MyProblem(), algorithm="nsgaii", max_evaluations=5000)
Example — constrained::
class MyConstrainedProblem(Problem):
n_constraints = 1 # declare at class level
def __init__(self):
self.n_var = 3
self.n_obj = 2
self.xl = np.zeros(3)
self.xu = np.ones(3)
def objectives(self, X):
f1 = np.sum(X ** 2, axis=1)
f2 = np.sum((X - 1) ** 2, axis=1)
return np.column_stack([f1, f2])
def constraints(self, X):
# Sign convention: g(x) <= 0 means feasible.
g = np.sum(X, axis=1) - 2.0 # sum(x) <= 2
return g.reshape(-1, 1)
encoding = 'real'
class-attribute
instance-attribute
¶
Variable encoding. Supported values: "real", "integer",
"binary", "permutation", "mixed". Default: "real".
n_constraints = 0
class-attribute
instance-attribute
¶
Number of inequality constraints. Default: 0 (unconstrained).
constraints(X)
¶
Compute constraint violations for a batch of solutions.
Override this method when your problem has inequality constraints.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
X
|
ndarray
|
Decision matrix of shape |
required |
Returns:
| Type | Description |
|---|---|
ndarray | None
|
Constraint array of shape |
evaluate(X, out)
¶
Framework evaluation entry point. Override :meth:objectives
(and optionally :meth:constraints) instead of this method.
objectives(X)
¶
Compute objective values for a batch of solutions.
Override this method in your subclass.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
X
|
ndarray
|
Decision matrix of shape |
required |
Returns:
| Type | Description |
|---|---|
ndarray
|
Objective array of shape |