-
Notifications
You must be signed in to change notification settings - Fork 1
/
IPO.m
140 lines (118 loc) · 4.34 KB
/
IPO.m
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
function [worsts, meanfits, bests, bestfit, bestpop, Neval] = IPO(numofballs, numofdims, numofiterations, stallgenlimit, TolFun, c1, c2, shift1, shift2, scale1, scale2, Xmininit, Xmaxinit, fitnessfunc, glocal, localnum, plots)
%% Mechanical Motion Optimization function
% By Hamed Mozaffari, Hamed Abdy, and Seyyed Hamid Zahiri
% Revision 2012/01/03
%% Initialization
% glocal = 0: Global search, 1: Local search
% localdist: maximum distance used for choosing local balls within it
fitnessfunc = str2func(fitnessfunc);
% bestfit = Inf; % stores previous total best
Neval = 0; % number of evaluating fitness function
% expanding Xmin, Xmax to cover all balls
Xmin = repmat(Xmininit, numofballs, 1);
Xmax = repmat(Xmaxinit, numofballs, 1);
% generating initial balls
% an option to generate custom initial balls can be added later
X = Xmin + (Xmax - Xmin) .* rand(numofballs, numofdims);
% initializing balls acceleration
A = zeros(numofballs, numofdims);
% initializes some variables for displaying the results
meanfits = zeros(numofiterations, 1);
bests = zeros(numofiterations, 1);
worsts = zeros(numofiterations, 1);
heights = fitnessfunc(X);
Neval = Neval + numofballs;
[tmpbestfit, tmpbestfitidx] = min(heights);
bestfit = tmpbestfit;
bestpop = X(tmpbestfitidx, :);
stallgenctrl = 0;
t = 1;
if plots
hold on;
end
%% Main loop
while ((t <= numofiterations) && (stallgenctrl <= stallgenlimit))
% calculating the acceleration for each ball
A(:, :) = 0;
% Choosing global or local algorithm
% glocal = 0: Global search, 1: Local search
if glocal
% local version
for i = 1:numofballs
dists = dist(X(i, :), X');
[~, localind] = sort(dists);
localind = localind(2:localnum + 1);
for j = 1:localnum
dheight = heights(localind(j)) - heights(i);
% uses better balls to estimate the slope and calculate the
% acceleration. In addition, it ensures (X(i, :) - X(j, :)) > 0
% for all dimensions.
if dheight < 0
A(i, :) = A(i, :) + sin(atan(dheight ./ (X(i, :) - X(localind(j), :))));
end
end
end
else
% global version
for i = 1:numofballs
for j = 1:numofballs
dheight = heights(j) - heights(i);
% uses better balls to estimate the slope and calculate the
% acceleration. In addition, it ensures (X(i, :) - X(j, :)) > 0
% for all dimensions.
if dheight < 0
A(i, :) = A(i, :) + sin(atan(dheight ./ (X(i, :) - X(j, :))));
end
end
end
end
% sigmoid method for changing coefficient:
% higher c1: faster convergence in first steps, worst local search
% lower c1: slower convergence and better global search in first steps,
% better local search
% c2 results to better local search
k1 = c1 ./ (1 + exp((t - shift1) .* scale1));
k2 = c2 ./ (1 + exp(-(t - shift2) .* scale2));
% updating balls
besttoX = repmat(bestpop, numofballs, 1) - X;
X = X + k1 .* rand(numofballs, numofdims) .* A + ...
k2 .* rand(numofballs, numofdims) .* besttoX;
% ensures that all balls lie in the problem's boundaries
tmpmaxchk = X > Xmax;
tmpminchk = X < Xmin;
X = X .* ~(tmpmaxchk | tmpminchk) + Xmax .* tmpmaxchk + Xmin .* tmpminchk;
% evaluates fitness of each ball
heights = fitnessfunc(X);
Neval = Neval + numofballs;
% finding and storing the global best ball and its fitness
[tmpbestfit, tmpbestfitidx] = min(heights);
if abs(tmpbestfit - bestfit) < TolFun
stallgenctrl = stallgenctrl + 1;
else
stallgenctrl = 0;
end
if tmpbestfit < bestfit
bestfit = tmpbestfit;
bestpop = X(tmpbestfitidx, :);
end
t = t + 1;
% updating variables for displaying the results
meanfits(t) = mean(heights);
bests(t) = bestfit;
worsts(t) = max(heights);
if plots
plot(t, bests(t), '.k');
plot(t, meanfits(t), '.b');
plot(t, worsts(t), '.r');
figure(gcf);
end
end
%% End of main loop
% if (stallgenctrl > stallgenlimit)
% display('Halted for stallgen');
% display(t);
% end
if plots
hold off
end
end