Benchmarks and custom problems#
Numerical benchmarks#
Import concrete problem classes from evomo.problems.numerical:
Family |
Public classes |
Parameters and bounds |
|---|---|---|
ZDT |
|
Decision dimension is |
DTLZ |
|
|
WFG |
|
|
MaF |
|
Parameters include |
LSMOP |
|
Specify |
Numerical problems generally return an objective tensor of shape (N, M). Unlike constrained
problems, not every numerical class exposes lb and ub. Construct bounds from the problem
definition when needed.
pf() supplies a reference front or samples of it for analysis. ref_num is not always an
exact output count or strict upper bound; inspect the returned shape. Some reference fronts
use numerical samples or packaged data, so not every pf() result is an exact analytical front.
Constrained benchmarks#
evomo.problems.constrained exports:
Family |
Variants |
|---|---|
LIRCMOP |
|
DASCMOP |
|
CTP |
|
MW |
|
FCP |
|
DOC |
|
SDC |
|
LSCM |
|
These classes use evomo.problems.constrained.base.CMOP and expose decision dimension d,
objective count m, and bounds lb and ub. Some variants have fixed dimensions; passing
d or m does not universally change a problem’s definition. evaluate returns (fitness, cv).
See constrained optimization for a complete example.
A custom batched problem#
Subclass EvoX’s Problem and implement evaluate for an entire population at once.
This example minimizes squared distances to two centers:
"""A batched, two-objective problem integrated with an EvoMO workflow."""
import torch
from evox.core import Problem
from evomo.algorithms import NSGA2
from evomo.workflows import UnifiedWorkflow
class TwoCenters(Problem):
def evaluate(self, population: torch.Tensor) -> torch.Tensor:
objective_a = population.square().sum(dim=1)
objective_b = (population - 1).square().sum(dim=1)
return torch.stack((objective_a, objective_b), dim=1)
def main():
device = "cuda" if torch.cuda.is_available() else "cpu"
torch.set_default_device(device)
torch.manual_seed(42)
algorithm = NSGA2(pop_size=100, n_objs=2, lb=torch.zeros(10), ub=torch.ones(10), device=device)
workflow = UnifiedWorkflow(algorithm, TwoCenters(), device=device)
workflow.init_step()
for _ in range(30):
workflow.step()
print(workflow.algorithm.fit)
if __name__ == "__main__":
main()
python docs/examples/custom_problem.py
The first output dimension must correspond to input candidates, and the second must match
the algorithm’s n_objs. Derive computations from input tensors instead of converting to
NumPy or evaluating candidates one by one. Register constants as buffers during initialization,
or create them on the input’s device with its dtype.
A custom constrained problem can return (fitness, cv), where cv contains nonnegative
violations rather than unprocessed constraint functions. Connect it with UnifiedWorkflow
and an algorithm that uses violations in selection.