-
Notifications
You must be signed in to change notification settings - Fork 203
/
Copy pathbuild_new_optimizer.py
114 lines (93 loc) · 4.41 KB
/
build_new_optimizer.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#!/usr/bin/env python
# Created by "Thieu" at 18:01, 28/08/2022 ----------%
# Email: [email protected] %
# Github: https://github.com/thieu1995 %
# --------------------------------------------------%
import numpy as np
from mealpy.optimizer import Optimizer
class MyAlgorithm(Optimizer):
"""
This is an example how to build new optimizer
Notes
~~~~~
+ Read more at: https://mealpy.readthedocs.io/en/latest/pages/build_new_optimizer.html
"""
def __init__(self, epoch=10000, pop_size=100, m_clusters=2, p1=0.75, **kwargs):
"""
Args:
epoch (int): maximum number of iterations, default = 10000
pop_size (int): number of population size, default = 100
m_clusters (int): number of clusters
p1 (float): the probability of updating the worst solution
"""
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.m_clusters = self.validator.check_int("m_clusters", m_clusters, [2, 5])
self.p1 = self.validator.check_float("p1", p1, (0, 1.0))
self.nfe_per_epoch = self.pop_size
self.sort_flag = True
# Determine to sort the problem or not in each epoch
## if True, the problem always sorted with fitness value increase
## if False, the problem is not sorted
def initialize_variables(self):
"""
This is method is called before initialization() method.
Returns:
"""
## Support variables
self.n_agents = int(self.pop_size / self.m_clusters)
self.space = self.problem.ub - self.problem.lb
def initialization(self):
"""
Override this method if needed. But the first 2 lines of code is required.
"""
### Required code
if self.pop is None:
self.pop = self.create_population(self.pop_size)
### Your additional code can be implemented here
self.mean_pos = np.mean([agent[self.ID_POS] for agent in self.pop])
def evolve(self, epoch):
"""
You can do everything in this function (i.e., Loop through the population multiple times)
Args:
epoch (int): The current iteration
"""
epxilon = 1 - 1 * (epoch + 1) / self.epoch # The epxilon in each epoch is changing based on this equation
## 1. Replace the almost worst agent by random agent
if np.random.uniform() < self.p1:
idx = np.random.randint(self.n_agents, self.pop_size)
solution_new = self.create_solution(self.problem.lb, self.problem.ub)
self.pop[idx] = solution_new
## 2. Replace all bad solutions by current_best + noise
for idx in range(self.n_agents, self.pop_size):
pos_new = self.pop[0][self.ID_POS] + epxilon * self.space * np.random.normal(0, 1)
pos_new = self.amend_position(pos_new, self.problem.lb, self.problem.ub)
fit_new = self.get_target_wrapper(pos_new)
if self.compare_agent([pos_new, fit_new], self.pop[idx]):
self.pop[idx] = [pos_new, fit_new]
## 3. Move all good solutions toward current best solution
for idx in range(0, self.n_agents):
if idx == 0:
pos_new = self.pop[idx][self.ID_POS] + epxilon * self.space * np.random.uniform(0, 1)
else:
pos_new = self.pop[idx][self.ID_POS] + epxilon * self.space * (self.pop[0][self.ID_POS] - self.pop[idx][self.ID_POS])
pos_new = self.amend_position(pos_new, self.problem.lb, self.problem.ub)
fit_new = self.get_target_wrapper(pos_new)
if self.compare_agent([pos_new, fit_new], self.pop[idx]):
self.pop[idx] = [pos_new, fit_new]
## Do additional works here if needed.
## Time to test our new optimizer
def fitness(solution):
return np.sum(solution**2)
problem_dict1 = {
"fit_func": fitness,
"lb": [-100, ]*100,
"ub": [100, ]*100,
"minmax": "min",
}
epoch = 50
pop_size = 50
model = MyAlgorithm(epoch, pop_size)
best_position, best_fitness = model.solve(problem_dict1)
print(f"Solution: {best_position}, Fitness: {best_fitness}")