-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathroot.py
More file actions
134 lines (119 loc) · 6.52 KB
/
root.py
File metadata and controls
134 lines (119 loc) · 6.52 KB
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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#!/usr/bin/env python
# ------------------------------------------------------------------------------------------------------%
# Python code created by "Thieu Nguyen" at 21:29, 12/06/2020 %
# %
# Email: nguyenthieu2102@gmail.com %
# Homepage: https://www.researchgate.net/profile/Thieu_Nguyen6 %
# Github: https://github.com/thieunguyen5991 %
#-------------------------------------------------------------------------------------------------------%
# Main paper (Please refer to the main paper):
# Slime Mould Algorithm: A New Method for Stochastic Optimization
# Shimin Li, Huiling Chen, Mingjing Wang, Ali Asghar Heidari, Seyedali Mirjalili
# Future Generation Computer Systems,2020
# DOI: https://doi.org/10.1016/j.future.2020.03.055
# https://www.sciencedirect.com/science/article/pii/S0167739X19320941
# ------------------------------------------------------------------------------------------------------------
# Website of SMA: http://www.alimirjalili.com/SMA.html
# You can find and run the SMA code online at http://www.alimirjalili.com/SMA.html
# You can find the SMA paper at https://doi.org/10.1016/j.future.2020.03.055
# Please follow the paper for related updates in researchgate:
# https://www.researchgate.net/publication/340431861_Slime_mould_algorithm_A_new_method_for_stochastic_optimization
# ------------------------------------------------------------------------------------------------------------
# Main idea: Shimin Li
# Author and programmer: Shimin Li,Ali Asghar Heidari,Huiling Chen
# e-Mail: simonlishimin@foxmail.com
# ------------------------------------------------------------------------------------------------------------
# Co-author:
# Huiling Chen(chenhuiling.jlu@gmail.com)
# Mingjing Wang(wangmingjing.style@gmail.com)
# Ali Asghar Heidari(aliasghar68@gmail.com, as_heidari@ut.ac.ir)
# Seyedali Mirjalili(ali.mirjalili@gmail.com)
#
# Researchgate: Ali Asghar Heidari https://www.researchgate.net/profile/Ali_Asghar_Heidari
# Researchgate: Seyedali Mirjalili https://www.researchgate.net/profile/Seyedali_Mirjalili
# Researchgate: Huiling Chen https://www.researchgate.net/profile/Huiling_Chen
# ------------------------------------------------------------------------------------------------------------
from numpy import where, clip, logical_and, ones, array, ceil
from numpy.random import uniform
from copy import deepcopy
class Root:
""" This is root of all Algorithms """
ID_MIN_PROB = 0 # min problem
ID_MAX_PROB = -1 # max problem
ID_POS = 0 # Position
ID_FIT = 1 # Fitness
EPSILON = 10E-10
def __init__(self, obj_func=None, lb=None, ub=None, problem_size=50, verbose=True):
"""
Parameters
----------
obj_func : function
lb : list
ub : list
problem_size : int, optional
batch_size: int, optional
verbose : bool, optional
"""
self.obj_func = obj_func
if (lb is None) or (ub is None):
if problem_size is None:
print("Problem size must be an int number")
exit(0)
elif problem_size <= 0:
print("Problem size must > 0")
exit(0)
else:
self.problem_size = int(ceil(problem_size))
self.lb = -1 * ones(problem_size)
self.ub = 1 * ones(problem_size)
else:
if isinstance(lb, list) and isinstance(ub, list) and not (problem_size is None):
if (len(lb) == len(ub)) and (problem_size > 0):
if len(lb) == 1:
self.problem_size = problem_size
self.lb = lb[0] * ones(problem_size)
self.ub = ub[0] * ones(problem_size)
else:
self.problem_size = len(lb)
self.lb = array(lb)
self.ub = array(ub)
else:
print("Lower bound and Upper bound need to be same length. Problem size must > 0")
exit(0)
else:
print("Lower bound and Upper bound need to be a list. Problem size is an int number")
exit(0)
self.verbose = verbose
self.epoch, self.pop_size = None, None
self.solution, self.loss_train = None, []
def create_solution(self, minmax=0):
""" Return the position position with 2 element: position of position and fitness of position
Parameters
----------
minmax
0 - minimum problem, else - maximum problem
"""
position = uniform(self.lb, self.ub)
fitness = self.get_fitness_position(position=position, minmax=minmax)
return [position, fitness]
def get_fitness_position(self, position=None, minmax=0):
""" Assumption that objective function always return the original value
:param position: 1-D numpy array
:param minmax: 0- min problem, 1 - max problem
:return:
"""
return self.obj_func(position) if minmax == 0 else 1.0 / (self.obj_func(position) + self.EPSILON)
def get_sorted_pop_and_global_best_solution(self, pop=None, id_fit=None, id_best=None):
""" Sort population and return the sorted population and the best position """
sorted_pop = sorted(pop, key=lambda temp: temp[id_fit])
return sorted_pop, deepcopy(sorted_pop[id_best])
def amend_position(self, position=None):
return clip(position, self.lb, self.ub)
def amend_position_random(self, position=None):
return where(logical_and(self.lb <= position, position <= self.ub), position, uniform(self.lb, self.ub))
def update_sorted_population_and_global_best_solution(self, pop=None, id_best=None, g_best=None):
""" Sort the population and update the current best position. Return the sorted population and the new current best position """
sorted_pop = sorted(pop, key=lambda temp: temp[self.ID_FIT])
current_best = sorted_pop[id_best]
g_best = deepcopy(current_best) if current_best[self.ID_FIT] < g_best[self.ID_FIT] else deepcopy(g_best)
return sorted_pop, g_best