#!/usr/bin/env python
# Created by "Thieu" at 17:48, 21/05/2022 ----------%
# Email: nguyenthieu2102@gmail.com %
# Github: https://github.com/thieu1995 %
# --------------------------------------------------%
import numpy as np
from mealpy.optimizer import Optimizer
[docs]class OriginalDMOA(Optimizer):
"""
The original version of: Dwarf Mongoose Optimization Algorithm (DMOA)
Links:
1. https://doi.org/10.1016/j.cma.2022.114570
2. https://www.mathworks.com/matlabcentral/fileexchange/105125-dwarf-mongoose-optimization-algorithm
Notes:
1. The Matlab code differs slightly from the original paper
2. There are some parameters and equations in the Matlab code that don't seem to have any meaningful purpose.
3. The algorithm seems to be weak on solving several problems.
Examples
~~~~~~~~
>>> import numpy as np
>>> from mealpy import FloatVar, DMOA
>>>
>>> def objective_function(solution):
>>> return np.sum(solution**2)
>>>
>>> problem_dict = {
>>> "bounds": FloatVar(n_vars=30, lb=(-10.,) * 30, ub=(10.,) * 30, name="delta"),
>>> "minmax": "min",
>>> "obj_func": objective_function
>>> }
>>>
>>> model = DMOA.OriginalDMOA(epoch=1000, pop_size=50, n_baby_sitter = 3, peep = 2)
>>> 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}")
References
~~~~~~~~~~
[1] Agushaka, J. O., Ezugwu, A. E., & Abualigah, L. (2022). Dwarf mongoose optimization algorithm.
Computer methods in applied mechanics and engineering, 391, 114570.
"""
def __init__(self, epoch: int = 10000, pop_size: int = 100, n_baby_sitter: int = 3, peep: float = 2, **kwargs: object) -> None:
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.n_baby_sitter = self.validator.check_int("n_baby_sitter", n_baby_sitter, [2, 10])
self.peep = self.validator.check_float("peep", peep, [1, 10.])
self.n_scout = self.pop_size - self.n_baby_sitter
self.is_parallelizable = False
self.set_parameters(["epoch", "pop_size", "n_baby_sitter", "peep"])
self.sort_flag = False
[docs] def initialize_variables(self):
self.C = np.zeros(self.pop_size)
self.tau = -np.inf
self.L = np.round(0.6 * self.problem.n_dims * self.n_baby_sitter)
[docs] def evolve(self, epoch):
"""
The main operations (equations) of algorithm. Inherit from Optimizer class
Args:
epoch (int): The current iteration
"""
## Abandonment Counter
CF = (1. - epoch/self.epoch)**(2.*epoch/self.epoch)
fit_list = np.array([agent.target.fitness for agent in self.pop])
mean_cost = np.mean(fit_list)
fi = np.exp(-fit_list / mean_cost)
for idx in range(0, self.pop_size):
alpha = self.get_index_roulette_wheel_selection(fi)
k = self.generator.choice(list(set(range(0, self.pop_size)) - {idx, alpha}))
## Define Vocalization Coeff.
phi = (self.peep / 2) * self.generator.uniform(-1, 1, self.problem.n_dims)
new_pos = self.pop[alpha].solution + phi * (self.pop[alpha].solution - self.pop[k].solution)
new_pos = self.correct_solution(new_pos)
agent = self.generate_agent(new_pos)
if self.compare_target(agent.target, self.pop[idx].target, self.problem.minmax):
self.pop[idx] = agent
else:
self.C[idx] += 1
SM = np.zeros(self.pop_size)
for idx in range(0, self.pop_size):
k = self.generator.choice(list(set(range(0, self.pop_size)) - {idx}))
## Define Vocalization Coeff.
phi = (self.peep / 2) * self.generator.uniform(-1, 1, self.problem.n_dims)
new_pos = self.pop[idx].solution + phi * (self.pop[idx].solution - self.pop[k].solution)
new_pos = self.correct_solution(new_pos)
agent = self.generate_agent(new_pos)
## Sleeping mould
SM[idx] = (agent.target.fitness - self.pop[idx].target.fitness)/np.max([agent.target.fitness, self.pop[idx].target.fitness])
if self.compare_target(agent.target, self.pop[idx].target, self.problem.minmax):
self.pop[idx] = agent
else:
self.C[idx] += 1
## Baby sitters
for idx in range(0, self.n_baby_sitter):
if self.C[idx] >= self.L:
self.pop[idx] = self.generate_agent()
self.C[idx] = 0
## Next Mongoose position
new_tau = np.mean(SM)
for idx in range(0, self.pop_size):
M = SM[idx] * self.pop[idx].solution / self.pop[idx].solution
phi = (self.peep / 2) * self.generator.uniform(-1, 1, self.problem.n_dims)
if new_tau > self.tau:
new_pos = self.pop[idx].solution - CF * phi * self.generator.random() * (self.pop[idx].solution - M)
else:
new_pos = self.pop[idx].solution + CF * phi * self.generator.random() * (self.pop[idx].solution - M)
self.tau = new_tau
new_pos = self.correct_solution(new_pos)
self.pop[idx] = self.generate_agent(new_pos)
[docs]class DevDMOA(Optimizer):
"""
The developed version of: Dwarf Mongoose Optimization Algorithm (DMOA)
Notes:
1. Removed the parameter n_baby_sitter
2. Changed in section # Next Mongoose position
3. Removed the meaningless variable tau
Examples
~~~~~~~~
>>> import numpy as np
>>> from mealpy import FloatVar, DMOA
>>>
>>> def objective_function(solution):
>>> return np.sum(solution**2)
>>>
>>> problem_dict = {
>>> "bounds": FloatVar(n_vars=30, lb=(-10.,) * 30, ub=(10.,) * 30, name="delta"),
>>> "minmax": "min",
>>> "obj_func": objective_function
>>> }
>>>
>>> model = DMOA.DevDMOA(epoch=1000, pop_size=50, peep = 2)
>>> 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}")
"""
def __init__(self, epoch: int = 10000, pop_size: int = 100, peep: float = 2, **kwargs: object) -> None:
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.peep = self.validator.check_float("peep", peep, [1, 10.])
self.set_parameters(["epoch", "pop_size", "peep"])
self.is_parallelizable = False
self.sort_flag = False
[docs] def initialize_variables(self):
self.C = np.zeros(self.pop_size)
self.L = np.round(0.6 * self.epoch)
[docs] def evolve(self, epoch):
"""
The main operations (equations) of algorithm. Inherit from Optimizer class
Args:
epoch (int): The current iteration
"""
## Abandonment Counter
CF = (1. - epoch / self.epoch) ** (2. * epoch / self.epoch)
fit_list = np.array([agent.target.fitness for agent in self.pop])
mean_cost = np.mean(fit_list)
fi = np.exp(-fit_list / mean_cost)
## Foraging led by Alpha female
for idx in range(0, self.pop_size):
alpha = self.get_index_roulette_wheel_selection(fi)
k = self.generator.choice(list(set(range(0, self.pop_size)) - {idx, alpha}))
## Define Vocalization Coeff.
phi = (self.peep / 2) * self.generator.uniform(-1, 1, self.problem.n_dims)
new_pos = self.pop[alpha].solution + phi * (self.pop[alpha].solution - self.pop[k].solution)
new_pos = self.correct_solution(new_pos)
agent = self.generate_agent(new_pos)
if self.compare_target(agent.target, self.pop[idx].target, self.problem.minmax):
self.pop[idx] = agent
else:
self.C[idx] += 1
## Scout group
SM = np.zeros(self.pop_size)
for idx in range(0, self.pop_size):
k = self.generator.choice(list(set(range(0, self.pop_size)) - {idx}))
## Define Vocalization Coeff.
phi = (self.peep / 2) * self.generator.uniform(-1, 1, self.problem.n_dims)
new_pos = self.pop[idx].solution + phi * (self.pop[idx].solution - self.pop[k].solution)
new_pos = self.correct_solution(new_pos)
agent = self.generate_agent(new_pos)
## Sleeping mould
SM[idx] = (agent.target.fitness - self.pop[idx].target.fitness) / np.max([agent.target.fitness, self.pop[idx].target.fitness])
if self.compare_target(agent.target, self.pop[idx].target, self.problem.minmax):
self.pop[idx] = agent
else:
self.C[idx] += 1
## Baby sitters
for idx in range(0, self.pop_size):
if self.C[idx] >= self.L:
self.pop[idx] = self.generate_agent()
self.C[idx] = 0
## Next Mongoose position
new_tau = np.mean(SM)
for idx in range(0, self.pop_size):
phi = (self.peep / 2) * self.generator.uniform(-1, 1, self.problem.n_dims)
if new_tau > SM[idx]:
new_pos = self.g_best.solution - CF * phi * (self.g_best.solution - SM[idx] * self.pop[idx].solution)
else:
new_pos = self.pop[idx].solution + CF * phi * (self.g_best.solution - SM[idx] * self.pop[idx].solution)
new_pos = self.correct_solution(new_pos)
agent = self.generate_agent(new_pos)
if self.compare_target(agent.target, self.pop[idx].target, self.problem.minmax):
self.pop[idx] = agent