
Continuamos estudando os métodos de otimização multidimensional, e o próximo da fila é o método de enxame de partículas, que busca um mínimo global.
Teoria
O algoritmo é bastante simples:

A posição de cada partícula em um determinado momento é calculada pela fórmula:
Onde - coordenada da melhor solução para uma partícula específica, - a coordenada da melhor solução para todas as partículas para esta época, e - fatores de ponderação (selecionados para um modelo específico), É o coeficiente de inércia, pode ser feito dependente do número de uma era, então as velocidades das partículas mudam suavemente.
Funções de teste
Como é muito bom observar o trabalho do método, teremos mais funções de teste:
Escondidoparabol(x) = sum(u->u*u, x)
E, de fato, o próprio MRC:
function mdpso(; nparts = 50, ndimes = 2, ages = 50,
Nos desenhos, porém, o cálculo leva mais tempo, mas é mais bonito:
using Plots pyplot() function ploter(l, u, xy, z, n_age ) contour(Xs, Ys, Zs, fill = true);

mdpso(C1 = [1.2 1.2], C2 = [1.1 1.1], Ac = [0.08 0.08], lower = [-4 -4], upper = [4 4], ages = 30)

fun = ekly mdpso(C1 = [1.7 1.7], C2 = [1.7 1.7], Ac = [0.07 0.07], lower = [-5 -5], upper = [5 5], ages = 15)


fun = himmelblau mdpso(C1 = [1.1 1.1], C2 = [1.0 1.0], Ac = [0.09 0.09], lower = [-5 -5], upper = [5 5], ages = 20, parts = 50)


fun = holdertable mdpso(C1 = [1.1 1.1], C2 = [1.0 1.0], Ac = [0.09 0.09], lower = [-10 -10], upper = [10 10], ages = 20, parts = 50)


fun = levy13 mdpso(C1 = [1.1 1.1], C2 = [1.0 1.0], Ac = [0.09 0.09], lower = [-10 -10], upper = [10 10], ages = 20, parts = 50)


fun = shaffer4 mdpso(C1 = [1.1 1.1], C2 = [1.0 1.0], Ac = [0.09 0.09], lower = [-100 -100], upper = [100 100], ages = 20, parts = 50)


O que realmente deprime é mexer com parâmetros e um elemento de aleatoriedade: se não uma partícula voa perto do mínimo global, então tudo isso pode cair no local:
fun = rastrigin mdpso(mdpso(C1 = [0.1 0.1], C2 = [1 1], Ac = [0.08 0.08], lover = low, upper = up, ages = 30))


Sim e velho não muito o bom Rosenbrock ainda não permite se compreender:
fun = rosenbrok mdpso(C1 = [1.7 1.7], C2 = [1.5 1.5], Ac = [0.15 0.15], lover = low, upper = up, ages = 20, nparts = 50) ... Age № 20 xbest: 0.37796421341886866 0.12799160066705667 Fmin: 0.409026370833564


Mas, como eu disse anteriormente, você pode usar o FDM para procurar uma boa aproximação ao mínimo global e especificar, por exemplo, Nelder-Mead:
Método simplex vecl(x) = sqrt( sum(u -> u*u, x) ) function sortcoord(Mx) N = size(Mx,2) f = [fun(Mx[:,i]) for i in 1:N]
ofNelderMid(fit = [0.37796 0.127992]) ... 92 0.00022610400555036366 [1.0, 1.0] 93 0.00015987967588703512 [1.0, 1.0] 94 0.00011305200343052599 [1.0, 1.0] 2-element Array{Float64,1}: 0.9999999996645973 0.9999999995466575
Para o MFC clássico, nem tudo é claro com o critério de parada: o melhor ponto pode manter a posição de várias épocas, as distâncias entre algumas partículas também não podem mudar por muito tempo. Portanto, um limite para o número de eras é usado. Para aumentar as chances de encontrar um mínimo global, é necessário aumentar o número de partículas e épocas, o que é muito caro em termos de memória e, além disso, de tempo (sem brincadeira, 50 chamadas da função objetivo para cada dimensão em cada iteração).
Moral
- Se você não quiser ou não puder usar métodos complexos e modernos, poderá usar composições de métodos mais simples
- Muitas vezes, para um problema, existe um método estreitamente afiado (por exemplo, para funções de ravina)
- É aconselhável ter vários MOs diferentes à mão para uma comparação consistente.
- Nem sempre é possível colocar sua tarefa no método e obter a resposta certa imediatamente - você deve dedicar algum tempo pesquisando, variando os parâmetros; se não conseguir visualizar o alívio, deve pelo menos imprimir cálculos intermediários para rastrear a convergência.
Por hoje é tudo, obrigado por sua atenção e desejo a todos uma boa otimização!