Initial commit

This commit is contained in:
Zhongwei Li
2025-11-30 08:30:10 +08:00
commit f0bd18fb4e
824 changed files with 331919 additions and 0 deletions

View File

@@ -0,0 +1,181 @@
"""
Custom problem definition example using pymoo.
This script demonstrates how to define a custom optimization problem
and solve it using pymoo.
"""
from pymoo.core.problem import ElementwiseProblem
from pymoo.algorithms.moo.nsga2 import NSGA2
from pymoo.optimize import minimize
from pymoo.visualization.scatter import Scatter
import numpy as np
class MyBiObjectiveProblem(ElementwiseProblem):
"""
Custom bi-objective optimization problem.
Minimize:
f1(x) = x1^2 + x2^2
f2(x) = (x1-1)^2 + (x2-1)^2
Subject to:
0 <= x1 <= 5
0 <= x2 <= 5
"""
def __init__(self):
super().__init__(
n_var=2, # Number of decision variables
n_obj=2, # Number of objectives
n_ieq_constr=0, # Number of inequality constraints
n_eq_constr=0, # Number of equality constraints
xl=np.array([0, 0]), # Lower bounds
xu=np.array([5, 5]) # Upper bounds
)
def _evaluate(self, x, out, *args, **kwargs):
"""Evaluate objectives for a single solution."""
# Objective 1: Distance from origin
f1 = x[0]**2 + x[1]**2
# Objective 2: Distance from (1, 1)
f2 = (x[0] - 1)**2 + (x[1] - 1)**2
# Return objectives
out["F"] = [f1, f2]
class ConstrainedProblem(ElementwiseProblem):
"""
Custom constrained bi-objective problem.
Minimize:
f1(x) = x1
f2(x) = (1 + x2) / x1
Subject to:
x2 + 9*x1 >= 6 (g1 <= 0)
-x2 + 9*x1 >= 1 (g2 <= 0)
0.1 <= x1 <= 1
0 <= x2 <= 5
"""
def __init__(self):
super().__init__(
n_var=2,
n_obj=2,
n_ieq_constr=2, # Two inequality constraints
xl=np.array([0.1, 0.0]),
xu=np.array([1.0, 5.0])
)
def _evaluate(self, x, out, *args, **kwargs):
"""Evaluate objectives and constraints."""
# Objectives
f1 = x[0]
f2 = (1 + x[1]) / x[0]
out["F"] = [f1, f2]
# Inequality constraints (g <= 0)
# Convert g1: x2 + 9*x1 >= 6 → -(x2 + 9*x1 - 6) <= 0
g1 = -(x[1] + 9 * x[0] - 6)
# Convert g2: -x2 + 9*x1 >= 1 → -(-x2 + 9*x1 - 1) <= 0
g2 = -(-x[1] + 9 * x[0] - 1)
out["G"] = [g1, g2]
def solve_custom_problem():
"""Solve custom bi-objective problem."""
print("="*60)
print("CUSTOM PROBLEM - UNCONSTRAINED")
print("="*60)
# Define custom problem
problem = MyBiObjectiveProblem()
# Configure algorithm
algorithm = NSGA2(pop_size=100)
# Solve
result = minimize(
problem,
algorithm,
('n_gen', 200),
seed=1,
verbose=False
)
print(f"Number of solutions: {len(result.F)}")
print(f"Objective space range:")
print(f" f1: [{result.F[:, 0].min():.3f}, {result.F[:, 0].max():.3f}]")
print(f" f2: [{result.F[:, 1].min():.3f}, {result.F[:, 1].max():.3f}]")
# Visualize
plot = Scatter(title="Custom Bi-Objective Problem")
plot.add(result.F, color="blue", alpha=0.7)
plot.show()
return result
def solve_constrained_problem():
"""Solve custom constrained problem."""
print("\n" + "="*60)
print("CUSTOM PROBLEM - CONSTRAINED")
print("="*60)
# Define constrained problem
problem = ConstrainedProblem()
# Configure algorithm
algorithm = NSGA2(pop_size=100)
# Solve
result = minimize(
problem,
algorithm,
('n_gen', 200),
seed=1,
verbose=False
)
# Check feasibility
feasible = result.CV[:, 0] == 0 # Constraint violation = 0
print(f"Total solutions: {len(result.F)}")
print(f"Feasible solutions: {np.sum(feasible)}")
print(f"Infeasible solutions: {np.sum(~feasible)}")
if np.any(feasible):
F_feasible = result.F[feasible]
print(f"\nFeasible objective space range:")
print(f" f1: [{F_feasible[:, 0].min():.3f}, {F_feasible[:, 0].max():.3f}]")
print(f" f2: [{F_feasible[:, 1].min():.3f}, {F_feasible[:, 1].max():.3f}]")
# Visualize feasible solutions
plot = Scatter(title="Constrained Problem - Feasible Solutions")
plot.add(F_feasible, color="green", alpha=0.7, label="Feasible")
if np.any(~feasible):
plot.add(result.F[~feasible], color="red", alpha=0.3, s=10, label="Infeasible")
plot.show()
return result
if __name__ == "__main__":
# Run both examples
result1 = solve_custom_problem()
result2 = solve_constrained_problem()
print("\n" + "="*60)
print("EXAMPLES COMPLETED")
print("="*60)

View File

@@ -0,0 +1,161 @@
"""
Multi-criteria decision making example using pymoo.
This script demonstrates how to select preferred solutions from
a Pareto front using various MCDM methods.
"""
from pymoo.algorithms.moo.nsga2 import NSGA2
from pymoo.problems import get_problem
from pymoo.optimize import minimize
from pymoo.mcdm.pseudo_weights import PseudoWeights
from pymoo.visualization.scatter import Scatter
from pymoo.visualization.petal import Petal
import numpy as np
def run_optimization_for_decision_making():
"""Run optimization to obtain Pareto front."""
print("Running optimization to obtain Pareto front...")
# Solve ZDT1 problem
problem = get_problem("zdt1")
algorithm = NSGA2(pop_size=100)
result = minimize(
problem,
algorithm,
('n_gen', 200),
seed=1,
verbose=False
)
print(f"Obtained {len(result.F)} solutions in Pareto front\n")
return problem, result
def apply_pseudo_weights(result, weights):
"""Apply pseudo-weights MCDM method."""
print(f"Applying Pseudo-Weights with weights: {weights}")
# Normalize objectives to [0, 1]
F_norm = (result.F - result.F.min(axis=0)) / (result.F.max(axis=0) - result.F.min(axis=0))
# Apply MCDM
dm = PseudoWeights(weights)
selected_idx = dm.do(F_norm)
selected_x = result.X[selected_idx]
selected_f = result.F[selected_idx]
print(f"Selected solution (decision variables): {selected_x}")
print(f"Selected solution (objectives): {selected_f}")
print()
return selected_idx, selected_x, selected_f
def compare_different_preferences(result):
"""Compare selections with different preference weights."""
print("="*60)
print("COMPARING DIFFERENT PREFERENCE WEIGHTS")
print("="*60 + "\n")
# Define different preference scenarios
scenarios = [
("Equal preference", np.array([0.5, 0.5])),
("Prefer f1", np.array([0.8, 0.2])),
("Prefer f2", np.array([0.2, 0.8])),
]
selections = {}
for name, weights in scenarios:
print(f"Scenario: {name}")
idx, x, f = apply_pseudo_weights(result, weights)
selections[name] = (idx, f)
# Visualize all selections
plot = Scatter(title="Decision Making - Different Preferences")
plot.add(result.F, color="lightgray", alpha=0.5, s=20, label="Pareto Front")
colors = ["red", "blue", "green"]
for (name, (idx, f)), color in zip(selections.items(), colors):
plot.add(f, color=color, s=100, marker="*", label=name)
plot.show()
return selections
def visualize_selected_solutions(result, selections):
"""Visualize selected solutions using petal diagram."""
# Get objective bounds for normalization
f_min = result.F.min(axis=0)
f_max = result.F.max(axis=0)
plot = Petal(
title="Selected Solutions Comparison",
bounds=[f_min, f_max],
labels=["f1", "f2"]
)
colors = ["red", "blue", "green"]
for (name, (idx, f)), color in zip(selections.items(), colors):
plot.add(f, color=color, label=name)
plot.show()
def find_extreme_solutions(result):
"""Find extreme solutions (best in each objective)."""
print("\n" + "="*60)
print("EXTREME SOLUTIONS")
print("="*60 + "\n")
# Best f1 (minimize f1)
best_f1_idx = np.argmin(result.F[:, 0])
print(f"Best f1 solution: {result.F[best_f1_idx]}")
print(f" Decision variables: {result.X[best_f1_idx]}\n")
# Best f2 (minimize f2)
best_f2_idx = np.argmin(result.F[:, 1])
print(f"Best f2 solution: {result.F[best_f2_idx]}")
print(f" Decision variables: {result.X[best_f2_idx]}\n")
return best_f1_idx, best_f2_idx
def main():
"""Main execution function."""
# Step 1: Run optimization
problem, result = run_optimization_for_decision_making()
# Step 2: Find extreme solutions
best_f1_idx, best_f2_idx = find_extreme_solutions(result)
# Step 3: Compare different preference weights
selections = compare_different_preferences(result)
# Step 4: Visualize selections with petal diagram
visualize_selected_solutions(result, selections)
print("="*60)
print("DECISION MAKING EXAMPLE COMPLETED")
print("="*60)
print("\nKey Takeaways:")
print("1. Different weights lead to different selected solutions")
print("2. Higher weight on an objective selects solutions better in that objective")
print("3. Visualization helps understand trade-offs")
print("4. MCDM methods help formalize decision maker preferences")
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,72 @@
"""
Many-objective optimization example using pymoo.
This script demonstrates many-objective optimization (4+ objectives)
using NSGA-III on the DTLZ2 benchmark problem.
"""
from pymoo.algorithms.moo.nsga3 import NSGA3
from pymoo.problems import get_problem
from pymoo.optimize import minimize
from pymoo.util.ref_dirs import get_reference_directions
from pymoo.visualization.pcp import PCP
import numpy as np
def run_many_objective_optimization():
"""Run many-objective optimization example."""
# Define the problem - DTLZ2 with 5 objectives
n_obj = 5
problem = get_problem("dtlz2", n_obj=n_obj)
# Generate reference directions for NSGA-III
# Das-Dennis method for uniform distribution
ref_dirs = get_reference_directions("das-dennis", n_obj, n_partitions=12)
print(f"Number of reference directions: {len(ref_dirs)}")
# Configure NSGA-III algorithm
algorithm = NSGA3(
ref_dirs=ref_dirs,
eliminate_duplicates=True
)
# Run optimization
result = minimize(
problem,
algorithm,
('n_gen', 300),
seed=1,
verbose=True
)
# Print results summary
print("\n" + "="*60)
print("MANY-OBJECTIVE OPTIMIZATION RESULTS")
print("="*60)
print(f"Number of objectives: {n_obj}")
print(f"Number of solutions: {len(result.F)}")
print(f"Number of generations: {result.algorithm.n_gen}")
print(f"Number of function evaluations: {result.algorithm.evaluator.n_eval}")
# Show objective space statistics
print("\nObjective space statistics:")
print(f"Minimum values per objective: {result.F.min(axis=0)}")
print(f"Maximum values per objective: {result.F.max(axis=0)}")
print("="*60)
# Visualize using Parallel Coordinate Plot
plot = PCP(
title=f"DTLZ2 ({n_obj} objectives) - NSGA-III Results",
labels=[f"f{i+1}" for i in range(n_obj)],
normalize_each_axis=True
)
plot.add(result.F, alpha=0.3, color="blue")
plot.show()
return result
if __name__ == "__main__":
result = run_many_objective_optimization()

View File

@@ -0,0 +1,63 @@
"""
Multi-objective optimization example using pymoo.
This script demonstrates multi-objective optimization using
NSGA-II on the ZDT1 benchmark problem.
"""
from pymoo.algorithms.moo.nsga2 import NSGA2
from pymoo.problems import get_problem
from pymoo.optimize import minimize
from pymoo.visualization.scatter import Scatter
import matplotlib.pyplot as plt
def run_multi_objective_optimization():
"""Run multi-objective optimization example."""
# Define the problem - ZDT1 (bi-objective)
problem = get_problem("zdt1")
# Configure NSGA-II algorithm
algorithm = NSGA2(
pop_size=100,
eliminate_duplicates=True
)
# Run optimization
result = minimize(
problem,
algorithm,
('n_gen', 200),
seed=1,
verbose=True
)
# Print results summary
print("\n" + "="*60)
print("MULTI-OBJECTIVE OPTIMIZATION RESULTS")
print("="*60)
print(f"Number of solutions in Pareto front: {len(result.F)}")
print(f"Number of generations: {result.algorithm.n_gen}")
print(f"Number of function evaluations: {result.algorithm.evaluator.n_eval}")
print("\nFirst 5 solutions (decision variables):")
print(result.X[:5])
print("\nFirst 5 solutions (objective values):")
print(result.F[:5])
print("="*60)
# Visualize results
plot = Scatter(title="ZDT1 - NSGA-II Results")
plot.add(result.F, color="red", alpha=0.7, s=30, label="Obtained Pareto Front")
# Add true Pareto front for comparison
pf = problem.pareto_front()
plot.add(pf, color="black", alpha=0.3, label="True Pareto Front")
plot.show()
return result
if __name__ == "__main__":
result = run_multi_objective_optimization()

View File

@@ -0,0 +1,59 @@
"""
Single-objective optimization example using pymoo.
This script demonstrates basic single-objective optimization
using the Genetic Algorithm on the Sphere function.
"""
from pymoo.algorithms.soo.nonconvex.ga import GA
from pymoo.problems import get_problem
from pymoo.optimize import minimize
from pymoo.operators.crossover.sbx import SBX
from pymoo.operators.mutation.pm import PM
from pymoo.operators.sampling.rnd import FloatRandomSampling
from pymoo.termination import get_termination
import numpy as np
def run_single_objective_optimization():
"""Run single-objective optimization example."""
# Define the problem - Sphere function (sum of squares)
problem = get_problem("sphere", n_var=10)
# Configure the algorithm
algorithm = GA(
pop_size=100,
sampling=FloatRandomSampling(),
crossover=SBX(prob=0.9, eta=15),
mutation=PM(eta=20),
eliminate_duplicates=True
)
# Define termination criteria
termination = get_termination("n_gen", 100)
# Run optimization
result = minimize(
problem,
algorithm,
termination,
seed=1,
verbose=True
)
# Print results
print("\n" + "="*60)
print("OPTIMIZATION RESULTS")
print("="*60)
print(f"Best solution: {result.X}")
print(f"Best objective value: {result.F[0]:.6f}")
print(f"Number of generations: {result.algorithm.n_gen}")
print(f"Number of function evaluations: {result.algorithm.evaluator.n_eval}")
print("="*60)
return result
if __name__ == "__main__":
result = run_single_objective_optimization()