Source code for mealpy.physics_based.CEO

#!/usr/bin/env python
# Created by "Baran Akyıldız" on 01/01/2026
# Github: https://github.com/akyilidizbaran
# ----------------------------------------%

import numpy as np
from mealpy.optimizer import Optimizer
from mealpy.utils.opt_info import OptInfo


[docs]class OriginalCEO(Optimizer): """ The original version of: Cosmic Evolution Optimization (CEO) Parameters ---------- epoch : int Maximum number of iterations, in range [1, 100000]. Default is 1000. pop_size : int Number of population size, in range [10, 10000]. Default is 50. w1 : float Expansion weight, in range (0.0, 1.0). Default is 0.1. p_base : float Base collision probability, in range (0.0, 1.0). Default is 0.2. alpha : float Alignment parameter, in range (0.0, 1.0). Default is 0.7. References ~~~~~~~~~~ 1. Wang, Rui, Zhengxuan Jiang, and Guowen Ding. "Cosmic Evolution Optimization: A Novel Metaheuristic Algorithm for Numerical Optimization and Engineering Design." Mathematics 13.15 (2025): 2499. https://doi.org/10.3390/math13152499 Examples ~~~~~~~~ >>> import numpy as np >>> from mealpy import FloatVar, CEO >>> >>> def objective_function(solution): >>> return np.sum(solution**2) >>> >>> problem_dict = { >>> "bounds": FloatVar(lb=(-10.,) * 30, ub=(10.,) * 30, name="delta"), >>> "minmax": "min", >>> "obj_func": objective_function >>> } >>> >>> model = CEO.OriginalCEO(epoch=1000, pop_size=50, w1=0.1, p_base=0.2, alpha=0.7) >>> g_best = model.solve(problem_dict) >>> print(f"Solution: {g_best.solution}, Fitness: {g_best.target.fitness}") >>> print(f"Solution: {model.g_best.solution}, Fitness: {model.g_best.target.fitness}") """ OPT_INFO = OptInfo(name="Cosmic Evolution Optimization", year=2025, difficulty="hard", kind="original") def __init__(self, epoch: int = 1000, pop_size: int = 50, w1: float = 0.1, p_base: float = 0.2, alpha: float = 0.7, **kwargs: object) -> None: """ Args: epoch (int): maximum number of iterations, default = 1000 pop_size (int): number of population size, default = 50 w1 (float): Expansion weight, default=0.1 p_base (float): Base collision probability, default=0.2 alpha (float): Alignment parameter, default=0.7 """ super().__init__(**kwargs) self.epoch = self.validator.check_int("epoch", epoch, [1, 100000]) self.pop_size = self.validator.check_int("pop_size", pop_size, [10, 10000]) self.w1 = self.validator.check_float("w1", w1, (0., 1.0)) self.p_base = self.validator.check_float("p_base", p_base, (0., 1.0)) self.alpha = self.validator.check_float("alpha", alpha, (0., 1.0)) # Internal parameter C (number of systems) fixed to 3 as per paper specs self.C = 3 self.set_parameters(["epoch", "pop_size", "w1", "p_base", "alpha"]) self.sort_flag = True
[docs] def evolve(self, epoch): """ The main operations (equations) of algorithm. Inherit from Optimizer class Args: epoch (int): The current iteration """ # Eq(3) Expansion speed: Vep(t) vep = self.w1 * (1 - 0.001 * (epoch / self.epoch)) * np.exp(-4 * epoch / self.epoch) # Eq(13) alpha(t) alpha_t = self.alpha * (1 + 0.0005 * (epoch / self.epoch)) # Eq(15) Pglobal collision probability p_global = self.p_base * (1 - 0.0005 * (epoch / self.epoch)) * (1 - epoch / self.epoch) # Eq(17) Resonance probability Preson p_reson = 0.1 * np.exp(-3 * epoch / self.epoch) # Multi-stellar Setup (Top C solutions are centers) centers = [agent.solution for agent in self.pop[:self.C]] center_fits = [agent.target.fitness for agent in self.pop[:self.C]] # Eq(5) Calculate Radius Rc kc = max(2, int(round(self.pop_size / self.C))) radii = [] for idx in range(self.C): center_pos = centers[idx] dists = np.linalg.norm([agent.solution - center_pos for agent in self.pop], axis=1) sorted_dists = np.sort(dists) nearest_dists = sorted_dists[:kc] rc = np.mean(nearest_dists) radii.append(rc) r_bar = np.mean(radii) # Use abs(f_best) for Eq(7) abs_f_best = np.abs(self.g_best.target.fitness) pop_new = [] for idx in range(0, self.pop_size): agent = self.pop[idx] xi = agent.solution.copy() # --- Collision Strategy (Eq 16) --- if self.generator.random() < p_global: pos_new = xi + self.generator.normal(0, 1, self.problem.n_dims) * r_bar else: # --- Trajectory Update (Eq 14) --- # Eq(4) Expansion step part: Vep(t) * randn * (ub - lb) expansion = vep * self.generator.normal(0, 1, self.problem.n_dims) * (self.problem.ub - self.problem.lb) # Eq(6-9) Gravitational Force F(t) total_force = np.zeros(self.problem.n_dims) w_total = self.EPSILON for c in range(self.C): o_c = centers[c] f_c = center_fits[c] dist = np.linalg.norm(o_c - xi) # Eq(6) u_c and F_c u_c = (o_c - xi) / (dist + self.EPSILON) f_c_force = u_c * np.exp(-dist / (radii[c] + self.EPSILON)) # Eq(7) Weight coefficient w_c diff = (agent.target.fitness - f_c) if self.problem.minmax == "min" else (f_c - agent.target.fitness) w_c = np.exp(- diff / (abs_f_best + self.EPSILON)) total_force += w_c * f_c_force w_total += w_c # Eq(9) Combined force F_t = total_force / w_total # Eq(12) Alignment A(t) s_i = self.g_best.solution - xi A_t = alpha_t * s_i * self.generator.normal(0, 1, self.problem.n_dims) # Eq(14) Full update pos_new = xi + expansion + F_t + A_t # Check bounds and evaluate pos_new = self.correct_solution(pos_new) agent_new = self.generate_empty_agent(pos_new) pop_new.append(agent_new) if self.mode not in self.AVAILABLE_MODES: pop_new[idx].target = self.get_target(pos_new) if self.mode in self.AVAILABLE_MODES: pop_new = self.update_target_for_population(pop_new) # Elite retention / Greedy Selection for idx in range(self.pop_size): if self.compare_target(pop_new[idx].target, self.pop[idx].target, self.problem.minmax): self.pop[idx] = pop_new[idx] else: # Resonance Strategy Eq(17-18) if self.generator.random() < p_reson: delta_x = 0.01 * self.generator.normal(0, 1, self.problem.n_dims) * (self.problem.ub - self.problem.lb) pos_reson = pop_new[idx].solution + delta_x pos_reson = self.correct_solution(pos_reson) agent_new = self.generate_agent(pos_reson) if self.compare_target(agent_new.target, self.pop[idx].target, self.problem.minmax): self.pop[idx] = agent_new