import
numpy as np
from
numpy.random
import
uniform
from
copy
import
deepcopy
def
Sphere_func(x):
fitness
=
0.0
for
i
in
range
(
len
(x)):
fitness
+
=
(x[i]
*
x[i])
return
fitness
class
HGSO():
ID_MIN_PROB
=
0
ID_MAX_PROB
=
-
1
ID_POS
=
0
ID_FIT
=
1
def
__init__(
self
, obj_func
=
None
, lb
=
None
, ub
=
None
,
verbose
=
True
, epoch
=
750
, pop_size
=
100
,
n_clusters
=
2
,
*
*
kwargs):
self
.epoch
=
epoch
self
.pop_size
=
pop_size
self
.n_clusters
=
n_clusters
self
.n_elements
=
int
(
self
.pop_size
/
self
.n_clusters)
self
.lb
=
lb
self
.ub
=
ub
self
.verbose
=
verbose
self
.T0
=
298.15
self
.K
=
1.0
self
.beta
=
1.0
self
.alpha
=
1
self
.epxilon
=
0.05
self
.obj_func
=
obj_func
self
.l1
=
5E
-
2
self
.l2
=
100.0
self
.l3
=
1E
-
2
self
.H_j
=
self
.l1
*
uniform()
self
.P_ij
=
self
.l2
*
uniform()
self
.C_j
=
self
.l3
*
uniform()
self
.solution,
self
.loss_train
=
None
, []
def
get_fitness_position(
self
, position
=
None
, minmax
=
0
):
return
self
.obj_func(position)
if
minmax
=
=
0
else
1.0
/
(
self
.obj_func(position)
+
10E
-
10
)
def
get_fitness_solution(
self
, solution
=
None
, minmax
=
0
):
return
self
.get_fitness_position(solution[
self
.ID_POS], minmax)
def
get_global_best_solution(
self
, pop
=
None
, id_fit
=
None
, id_best
=
None
):
sorted_pop
=
sorted
(pop, key
=
lambda
temp: temp[id_fit])
return
deepcopy(sorted_pop[id_best])
def
update_global_best_solution(
self
, pop
=
None
, id_best
=
None
, g_best
=
None
):
sorted_pop
=
sorted
(pop, key
=
lambda
temp: temp[
self
.ID_FIT])
current_best
=
sorted_pop[id_best]
return
deepcopy(current_best)
if
current_best[
self
.ID_FIT] <\
g_best[
self
.ID_FIT]
else
deepcopy(g_best)
def
create_population__(
self
, minmax
=
0
, n_clusters
=
0
):
pop
=
[]
group
=
[]
for
i
in
range
(n_clusters):
team
=
[]
for
j
in
range
(
self
.n_elements):
solution
=
uniform(
self
.lb,
self
.ub)
fitness
=
self
.obj_func(
solution)
if
minmax
=
=
0
else
1.0
/
(
self
.obj_func(solution)
+
10E
-
10
)
team.append([solution, fitness, i])
pop.append([solution, fitness, i])
group.append(team)
return
pop, group
def
get_best_solution_in_team(
self
, group
=
None
):
list_best
=
[]
for
i
in
range
(
len
(group)):
sorted_team
=
sorted
(group[i], key
=
lambda
temp: temp[
self
.ID_FIT])
list_best.append(deepcopy(sorted_team[
self
.ID_MIN_PROB]))
return
list_best
def
train(
self
):
pop, group
=
self
.create_population__(
self
.ID_MIN_PROB,
self
.n_clusters)
g_best
=
self
.get_global_best_solution(
pop,
self
.ID_FIT,
self
.ID_MIN_PROB)
p_best
=
self
.get_best_solution_in_team(
group)
for
epoch
in
range
(
self
.epoch):
for
i
in
range
(
self
.n_clusters):
for
j
in
range
(
self
.n_elements):
F
=
-
1.0
if
uniform() <
0.5
else
1.0
self
.H_j
=
self
.H_j
*
\
np.exp(
-
self
.C_j
*
(
1.0
/
np.exp(
-
epoch
/
self
.epoch)
-
1.0
/
self
.T0))
S_ij
=
self
.K
*
self
.H_j
*
self
.P_ij
gamma
=
self
.beta
*
\
np.exp(
-
((p_best[i][
self
.ID_FIT]
+
self
.epxilon)
/
(group[i][j][
self
.ID_FIT]
+
self
.epxilon)))
X_ij
=
group[i][j][
self
.ID_POS]
+
F
*
uniform()
*
gamma
*
\
(p_best[i][
self
.ID_POS]
-
group[i][j][
self
.ID_POS])
+
\
F
*
uniform()
*
self
.alpha
*
\
(S_ij
*
g_best[
self
.ID_POS]
-
group[i][j][
self
.ID_POS])
fit
=
self
.get_fitness_position(X_ij,
self
.ID_MIN_PROB)
group[i][j]
=
[X_ij, fit, i]
pop[i
*
self
.n_elements
+
j]
=
[X_ij, fit, i]
self
.H_j
=
self
.H_j
*
\
np.exp(
-
self
.C_j
*
(
1.0
/
np.exp(
-
epoch
/
self
.epoch)
-
1.0
/
self
.T0))
S_ij
=
self
.K
*
self
.H_j
*
self
.P_ij
N_w
=
int
(
self
.pop_size
*
(uniform(
0
,
0.1
)
+
0.1
))
sorted_id_pos
=
np.argsort([x[
self
.ID_FIT]
for
x
in
pop])
for
item
in
range
(N_w):
id
=
sorted_id_pos[item]
j
=
id
%
self
.n_elements
i
=
int
((
id
-
j)
/
self
.n_elements)
X_new
=
uniform(
self
.lb,
self
.ub)
fit
=
self
.get_fitness_position(X_new,
self
.ID_MIN_PROB)
pop[
id
]
=
[X_new, fit, i]
group[i][j]
=
[X_new, fit, i]
p_best
=
self
.get_best_solution_in_team(group)
g_best
=
self
.update_global_best_solution(
pop,
self
.ID_MIN_PROB, g_best)
self
.loss_train.append(g_best[
self
.ID_FIT])
if
self
.verbose:
print
(
"Epoch: {}, Best fitness value: {}"
.
format
(
epoch
+
1
, g_best[
self
.ID_FIT]))
self
.solution
=
g_best
return
g_best[
self
.ID_POS], g_best[
self
.ID_FIT],
self
.loss_train
lb
=
[
-
10
]
ub
=
[
10
]
epoch
=
100
verbose
=
True
pop_size
=
50
obj
=
HGSO(Sphere_func, lb, ub, verbose, epoch, pop_size)
obj.train()