Skip to content

Commit 10b170e

Browse files
andreslisztandresliszt
andauthored
Update RNSGA2 docs with Rust notebook example (#237)
* Add rnsga2 notebooks with Rust code * Add API docs --------- Co-authored-by: andresliszt <[email protected]>
1 parent de07953 commit 10b170e

File tree

10 files changed

+1350
-201
lines changed

10 files changed

+1350
-201
lines changed
37.8 KB
Loading

pymoors/docs/user_guide/algorithms/images/rnsga2_rust.svg

Lines changed: 299 additions & 0 deletions
Loading

pymoors/docs/user_guide/algorithms/python/rnsga2.ipynb

Lines changed: 139 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
2+
3+
4+
5+
6+
7+
8+
9+
10+
11+
12+
13+
14+
15+
16+
17+
18+
19+
20+
```python
21+
import numpy as np
22+
import matplotlib.pyplot as plt
23+
24+
from pymoors import (
25+
Rnsga2,
26+
RandomSamplingFloat,
27+
GaussianMutation,
28+
ExponentialCrossover,
29+
CloseDuplicatesCleaner,
30+
Constraints
31+
)
32+
from pymoors.schemas import Population
33+
from pymoors.typing import TwoDArray
34+
35+
np.seterr(invalid="ignore")
36+
37+
38+
def evaluate_ztd1(x: TwoDArray) -> TwoDArray:
39+
"""
40+
Evaluate the ZTD1 objectives in a fully vectorized manner.
41+
"""
42+
f1 = x[:, 0]
43+
g = 1 + 9.0 / (30 - 1) * np.sum(x[:, 1:], axis=1)
44+
f2 = g * (1 - np.power((f1 / g), 0.5))
45+
return np.column_stack((f1, f2))
46+
47+
48+
def ztd1_theoretical_front():
49+
"""
50+
Compute the theoretical Pareto front for ZTD1.
51+
"""
52+
f1_theo = np.linspace(0, 1, 200)
53+
f2_theo = 1 - np.sqrt(f1_theo)
54+
return f1_theo, f2_theo
55+
56+
57+
# Define two reference points (for example, points on the Pareto front)
58+
reference_points = np.array([[0.5, 0.2], [0.1, 0.6]])
59+
60+
# Set up RNSGA-II algorithm with epsilon = 0.01
61+
algorithm = Rnsga2(
62+
sampler=RandomSamplingFloat(min=0, max=1),
63+
crossover=ExponentialCrossover(exponential_crossover_rate=0.75),
64+
mutation=GaussianMutation(gene_mutation_rate=0.1, sigma=0.01),
65+
fitness_fn=evaluate_ztd1,
66+
constraints_fn=Constraints(lower_bound=0.0, upper_bound=1.0),
67+
duplicates_cleaner=CloseDuplicatesCleaner(epsilon=1e-8),
68+
num_vars=30,
69+
population_size=50,
70+
num_offsprings=50,
71+
num_iterations=700,
72+
mutation_rate=0.1,
73+
crossover_rate=0.9,
74+
keep_infeasible=False,
75+
reference_points=reference_points,
76+
verbose=False,
77+
epsilon=0.005,
78+
seed=1729,
79+
)
80+
81+
# Run the algorithm
82+
algorithm.run()
83+
84+
# Get the best Pareto front obtained (as a Population instance)
85+
best: Population = algorithm.population.best_as_population
86+
obtained_fitness = best.fitness
87+
88+
# Compute the theoretical Pareto front for ZTD1
89+
f1_theo, f2_theo = ztd1_theoretical_front()
90+
91+
# Plot the theoretical Pareto front, obtained front, and reference points
92+
plt.figure(figsize=(10, 6))
93+
plt.plot(f1_theo, f2_theo, "k-", linewidth=2, label="Theoretical Pareto Front")
94+
plt.scatter(
95+
obtained_fitness[:, 0],
96+
obtained_fitness[:, 1],
97+
c="r",
98+
marker="o",
99+
label="Obtained Front",
100+
)
101+
plt.scatter(
102+
[pt[0] for pt in reference_points],
103+
[pt[1] for pt in reference_points],
104+
marker="*",
105+
s=200,
106+
color="magenta",
107+
label="Reference Points",
108+
)
109+
plt.xlabel("$f_1$", fontsize=14)
110+
plt.ylabel("$f_2$", fontsize=14)
111+
plt.title("ZTD1 Pareto Front: Theoretical vs Obtained (RNSGA-II)", fontsize=16)
112+
plt.legend()
113+
plt.grid(True)
114+
plt.show()
115+
```
116+
117+
118+
![png](../images/rnsga2_python.png)

pymoors/docs/user_guide/algorithms/rnsga2.ipynb

Lines changed: 0 additions & 199 deletions
This file was deleted.
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# RNSGA-II
2+
3+
RNSGA-II is an advanced, elitist multiobjective evolutionary algorithm that extends NSGA-II by incorporating **reference points** to guide the search toward regions of interest specified by the decision-maker. This modification is introduced in the **survival selection** phase, where the algorithm not only considers Pareto dominance and crowding distance but also evaluates the proximity of each solution to predefined reference points.
4+
5+
## Key Features
6+
7+
- **Fast Nondominated Sorting:**
8+
RNSGA-II sorts the population based on Pareto dominance with a computational complexity of
9+
$O(MN^2)$, where $M$ is the number of objectives and $N$ is the population size.
10+
11+
- **Elitist Selection with Reference Points:**
12+
The algorithm forms a combined pool of parent and offspring populations. From this pool, the best solutions are selected not only based on fitness and diversity but also on their proximity to the reference points. This ensures that solutions closer to the preferred regions have a higher chance of survival.
13+
14+
- **Crowding Distance for Diversity Maintenance:**
15+
To maintain a diverse Pareto front, RNSGA-II computes the *crowding distance* for each individual. In addition, it assesses each solution’s distance from the reference points.
16+
17+
<div style="text-align: center;">
18+
<img src="../../images/rnsga2_ref_points.png" alt="RNSGA-II crowding distance illustration" width="600px" />
19+
</div>
20+
21+
Individuals with a **larger crowding distance** or those nearer to the reference points are favored, thus promoting diversity while also focusing the search in regions of interest.
22+
23+
- **Modified Survival Selection:**
24+
The survival selection process in RNSGA-II is enhanced by:
25+
- **Reference Point Proximity:** Evaluating how close each solution is to the predefined reference points.
26+
- **Combined Ranking:** First ranking solutions by Pareto dominance, then by crowding distance, and finally giving extra priority to those closer to the reference points.
27+
This approach effectively balances convergence toward the Pareto-optimal front with targeted exploration of preferred regions.
28+
29+
- **Constraint Handling:**
30+
When constraints_fn are present, feasible solutions are always favored. Among these, solutions with a better (i.e., lower) nondomination rank are preferred, and if ties occur, those with a higher crowding distance and closer to the reference points are selected.
31+
32+
## ZTD1 Problem
33+
34+
The **ZTD1** problem is commonly used as a benchmark problem to evaluate multiobjective optimization algorithms that incorporate reference points. It challenges the algorithm with:
35+
36+
- **Two Conflicting Objectives:**
37+
- $f_1(\mathbf{x}) = x_1$
38+
- $f_2(\mathbf{x}) = g(\mathbf{x}) \cdot h(f_1(\mathbf{x}), g(\mathbf{x}))$
39+
40+
- **Auxiliary Functions:**
41+
- $g(\mathbf{x}) = 1 + \frac{9}{n-1}\sum_{i=2}^{n} x_i$
42+
- $h(f_1, g) = 1 - \sqrt{\frac{f_1}{g}}$
43+
44+
- **Key Characteristics:**
45+
- **Continuous and Convex Pareto Front:**
46+
Unlike problems with discontinuous fronts, ZTD1 features a continuous and convex Pareto front. This facilitates convergence while still posing a challenge in maintaining solution diversity.
47+
- **Incorporation of Reference Points:**
48+
The use of reference points in RNSGA-II directs the search toward specific regions of the Pareto front, ensuring that the obtained solutions align with the decision-maker’s preferences.
49+
50+
**Domain:**
51+
Each decision variable $x_i$ is typically within the interval $[0, 1]$, and the problem is commonly defined with $n = 30$ variables.
52+
53+
=== "Rust"
54+
{% include-markdown "user_guide/algorithms/rust/rnsga2.md" %}
55+
56+
=== "Python"
57+
{% include-markdown "user_guide/algorithms/python/rnsga2.md" %}

0 commit comments

Comments
 (0)