Benchmark Problems¶
PyGAD bundles common benchmark problems under pygad.benchmarks. Each problem is a class callable with (ga, solution, sol_idx) and returns a fitness in PyGAD’s maximisation format. Minimisation values are negated.
Class attributes for setting up the GA:
num_genes: number of decision variables.num_objectives: number of objectives (1for single-objective).bounds:(low, high)tuple of variable bounds.
ZDT classes also have a pareto_front(num_points) method that returns true-front reference points. Pass these to the IGD or GD indicators as reference_front.
A runnable example per benchmark lives under examples/benchmarks/.
Single-Objective Problems¶
Available in pygad.benchmarks.classic:
Class |
Global minimum |
Bounds |
|---|---|---|
|
f(0, …, 0) = 0 |
|
|
f(0, …, 0) = 0 |
|
|
f(1, …, 1) = 0 |
|
|
f(0, …, 0) = 0 |
|
|
f(420.97, …, 420.97) ≈ 0 |
|
|
f(0, …, 0) = 0 |
|
|
four equal minima at f = 0 (2D only) |
|
Multi-Objective Problems (ZDT family)¶
In pygad.benchmarks.zdt. Two objectives, variables in [0, 1] (ZDT4 uses [-5, 5] for the rest).
Class |
Pareto front shape |
|---|---|
|
convex |
|
non-convex |
|
disconnected (five pieces) |
|
convex, many local minima in the search space |
|
non-uniform |
Many-Objective Problems (DTLZ family)¶
In pygad.benchmarks.dtlz. Any number of objectives M. Decision variables: M + k - 1, where k is the distance-variable count.
Class |
Default M |
Pareto front shape |
|---|---|---|
|
3 |
linear hyperplane ( |
|
3 |
unit sphere first orthant |
|
3 |
unit sphere with hard multimodal g-function |
|
3 |
unit sphere with strong bias toward one corner |
Combinatorial Problems¶
Two combinatorial benchmarks: 0/1 Knapsack and TSP.
Knapsack¶
In pygad.benchmarks.knapsack. Knapsack takes three arguments: 1D arrays of weights and values, and a numeric capacity. A solution is a binary vector (1 = pick the item). Fitness is the total value within capacity, or a negative penalty scaled by the overweight amount.
Class attributes gene_space=[0, 1] and gene_type=int plug into PyGAD as is:
import pygad
from pygad.benchmarks.knapsack import Knapsack
problem = Knapsack(weights=[2, 3, 4, 5],
values=[3, 4, 5, 6],
capacity=5)
ga = pygad.GA(
num_generations=50,
num_parents_mating=10,
fitness_func=problem,
sol_per_pop=30,
num_genes=problem.num_genes,
gene_space=problem.gene_space,
gene_type=problem.gene_type,
)
ga.run()
Travelling Salesman Problem¶
In pygad.benchmarks.tsp. Build TSP from either a 2D coordinates array or a square distance_matrix. A solution is a permutation of city indices and the fitness is the negative tour length (the tour closes back to the start). Non-permutation candidates get a large negative penalty.
Class attributes gene_space=list(range(num_cities)), gene_type=int, and allow_duplicate_genes=False keep the permutation constraint:
import pygad
from pygad.benchmarks.tsp import TSP
problem = TSP(coordinates=[[0.0, 0.0],
[1.0, 0.0],
[1.0, 1.0],
[0.0, 1.0]])
ga = pygad.GA(
num_generations=200,
num_parents_mating=10,
fitness_func=problem,
sol_per_pop=30,
num_genes=problem.num_genes,
gene_space=problem.gene_space,
gene_type=problem.gene_type,
allow_duplicate_genes=problem.allow_duplicate_genes,
)
ga.run()
Example: SOO¶
import pygad
from pygad.benchmarks.classic import Sphere
problem = Sphere(num_genes=10)
ga = pygad.GA(
num_generations=100,
num_parents_mating=10,
fitness_func=problem,
sol_per_pop=20,
num_genes=problem.num_genes,
init_range_low=problem.bounds[0],
init_range_high=problem.bounds[1],
crossover_type='sbx',
sbx_crossover_eta=30,
mutation_type='polynomial',
polynomial_mutation_eta=20,
)
ga.run()
Example: MOO¶
import pygad
from pygad.benchmarks.zdt import ZDT1
from pygad.utils.quality_indicators import inverted_generational_distance
problem = ZDT1(num_genes=10)
ga = pygad.GA(
num_generations=200,
num_parents_mating=20,
fitness_func=problem,
sol_per_pop=30,
num_genes=problem.num_genes,
init_range_low=problem.bounds[0],
init_range_high=problem.bounds[1],
parent_selection_type='nsga2',
crossover_type='sbx',
sbx_crossover_eta=30,
mutation_type='polynomial',
polynomial_mutation_eta=20,
)
ga.run()
# IGD against the true front.
true_front = problem.pareto_front(num_points=100)
igd = inverted_generational_distance(ga.last_generation_fitness, true_front)
print(f'IGD = {igd}')