/
ABC.jl
157 lines (124 loc) · 3.68 KB
/
ABC.jl
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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
include("bee_dynamics.jl")
mutable struct ABC <: AbstractParameters
N::Int
Ne::Int
No::Int
limit::Int
end
"""
ABC(;
N = 50,
Ne = div(N+1, 2),
No = div(N+1, 2),
limit=10,
information = Information(),
options = Options()
)
ABC implements the original parameters for the Artificial Bee Colony Algorithm.
`N` is the population size, `Ne` is the number of employees, `No` is the
number of outlookers bees. `limit` is related to the times that a solution
is visited.
# Example
```jldoctest
julia> f(x) = sum(x.^2)
f (generic function with 1 method)
julia> optimize(f, [-1 -1 -1; 1 1 1.0], ABC())
+=========== RESULT ==========+
iteration: 595
minimum: 4.03152e-28
minimizer: [1.489845115451046e-14, 1.2207275971717747e-14, -5.671872444705246e-15]
f calls: 30020
total time: 0.0360 s
+============================+
julia> optimize(f, [-1 -1 -1; 1 1 1.0], ABC(N = 80, No = 20, Ne = 50, limit=5))
+=========== RESULT ==========+
iteration: 407
minimum: 8.94719e-08
minimizer: [8.257485723496422e-5, 0.0002852795196258074, -3.5620824723352315e-5]
f calls: 30039
total time: 0.0432 s
+============================+
```
"""
function ABC(;
N = 50,
Ne = div(N+1, 2),
No = div(N+1, 2),
limit=10,
kargs...
)
parameters = ABC(N, Ne, No, limit)
Algorithm(
parameters;
kargs...
)
end
function initialize!(
status,
parameters::ABC,
problem,
information,
options,
args...;
kargs...
)
options.parallel_evaluation &&
error("ABC is not supporting parallel evaluation. Put `options.parallel_evaluation=false`")
D = getdim(problem)
if options.f_calls_limit == 0
options.f_calls_limit = 10000D
options.iterations = parameters.N + 10000D ÷ parameters.N
options.debug && @info "Increasing f calls limit to $(options.f_calls_limit)"
end
_st = gen_initial_state(problem,parameters,information,options,status)
bees = [Bee(sol) for sol in _st.population]
nevals = length(bees)
best_sol = deepcopy(getBestBee(bees))
population = bees
f_calls = nevals
return State(best_sol, population; f_calls = f_calls)
end
function update_state!(
status,#::State{Bee},
parameters::ABC,
problem,
information,
options,
args...;
kargs...
)
D = getdim(problem)
fobj = problem.f
bees = status.population
Ne = parameters.Ne
No = parameters.No
bounds = problem.search_space
a = bounds.lb
b = bounds.ub
employedPhase!(bees,problem, Ne, options.rng)
outlookerPhase!(bees,problem, No, options.rng)
@inline genPos(D=D, a=a, b=b) = a + (b - a) .* rand(options.rng, D)
best = chooseBest(bees, status.best_sol)
status.f_calls += Ne + No + scoutPhase!(bees, problem, genPos, parameters.limit)
status.best_sol = best
stop_criteria!(status, parameters, problem, information, options)
end
function final_stage!(
status,#::State{Bee{xf_indiv}},
parameters::ABC,
problem::AbstractProblem,
information::Information,
options::Options,
args...;
kargs...
)
status.final_time = time()
# status.population = map(b -> b.sol, status.population)
# status.best_sol = status.best_sol.sol
end
is_better_abc(bee1, bee2) = is_better(bee1.sol, bee2.sol)
function accuracy_stop_check(status::State{Bee}, information, options)
cond = !isnan(information.f_optimum) && abs(fval(status.best_sol) - information.f_optimum) < options.f_tol
cond && (status.termination_status_code = ACCURACY_LIMIT)
cond
end