13 Estratégias de Mutação para Aprimorar Algoritmos de Otimização: Guia Prático com Harris Hawk Optimization

Introdução

Algoritmos de otimização por enxame frequentemente sofrem com problemas de convergência prematura, facilidade em ficar preso em ótimos locais e baixa precisão de convergência quando aplicados a problemas de grande escala. A aplicação de estratégias de mutação adequadas pode mitigar significativamente essas limitações.

Este artigo apresenta uma coleção de 13 estratégias de mutação comumente utilizadas na literatura, com implementações em MATLAB que podem ser aplicadas a qualquer algoritmo de otimização meta-heurística. Todas as estratégias serão demonstradas utilizando o algoritmo Harris Hawk Optimization (HHO) como algoritmo base.

Lista das 13 Estratégias de Mutação

  1. Mutação Gaussiana
  2. Mutação Gaussiana Elite
  3. Mutação de Cauchy
  4. Mutação de Cauchy com Distribuição Inversa Acumulada
  5. Mutação com Perturbação t-Distribuída
  6. Mutação com Perturbação t-Distribuída Adaptativa
  7. Mutação de Nuvem Normal
  8. Mutação Periódica
  9. Mutação Diferencial Elite DE/best/1
  10. Mutação Diferencial Aleatório-para-Elite DE/rand-to-best/1
  11. Mutação Diferencial Aleatória DE/rand/2
  12. Mutação Diferencial Elite DE/best/2
  13. Mutação Não-Uniforme

Implementação das Estratégias

1. Mutação Gaussiana

A mutação gaussiana adiciona ruído seguindo uma distribuição normal ao indivíduo selecionado, permitindo exploração controlada do espaço de busca.

function individuo = mutacao_gaussiana(individuo, dim, limite_inferior, limite_superior)
    sigma = 0.1 * (limite_superior - limite_inferior);
    ruido = sigma * randn(1, dim);
    individuo = individuo + ruido;
    individuo = max(min(individuo, limite_superior), limite_inferior);
end

2. Mutação Gaussiana Elite

Esta versão utiliza o melhor indivíduo da população para guiar a mutação, combinando informação elitista com perturbação gaussiana.

function individuo = mutacao_gaussiana_elite(individuo, elite, dim, limite_inferior, limite_superior)
    fator_elite = 0.5;
    sigma = 0.15 * (limite_superior - limite_inferior);
    ruido = sigma * randn(1, dim);
    individuo = individuo + fator_elite * (elite - individuo) + ruido;
    individuo = max(min(individuo, limite_superior), limite_inferior);
end

3. Mutação de Cauchy

A distribuição de Cauchy possui caudas mais pesadas que a distribuição normal, permitindo saltos maiores no espaço de busca.

function individuo = mutacao_cauchy(individuo, dim, limite_inferior, limite_superior)
    escala = 0.2 * (limite_superior - limite_inferior);
    ruido = escala * tcauchy(1, dim);
    individuo = individuo + ruido;
    individuo = max(min(individuo, limite_superior), limite_inferior);
end

function resultado = tcauchy(n, dim)
    resultado = zeros(1, dim);
    for i = 1:dim
        resultado(i) = tan(pi * (rand() - 0.5));
    end
end

4. Mutação de Cauchy Inversa Acumulada

Utiliza a função inversa da distribuição acumulada de Cauchy para gerar perturbações com características distintas.

function individuo = mutacao_cauchy_inversa(individuo, dim, limite_inferior, limite_superior)
    escala = 0.25 * (limite_superior - limite_inferior);
    ruido = escala * (tan(pi * rand(1, dim) - 0.5 * ones(1, dim)));
    individuo = individuo + ruido;
    individuo = max(min(individuo, limite_superior), limite_inferior);
end

5. Mutação com Perturbação t-Distribuída

A distribuição t de Student oferece flexibilidade entre gaussian e cauchy, controlada pelo parâmetro graus de liberdade.

function individuo = mutacao_t_student(individuo, dim, limite_inferior, limite_superior)
    graus_liberdade = 3;
    escala = 0.2 * (limite_superior - limite_inferior);
    ruido = escala * trnd(graus_liberdade, 1, dim);
    individuo = individuo + ruido;
    individuo = max(min(individuo, limite_superior), limite_inferior);
end

6. Mutação com Perturbação t-Distribuída Adaptativa

Os graus de liberdade são ajustados dinamicamente durante a execução, permitindo transição de exploração para explotação.

function individuo = mutacao_t_adaptativa(individuo, iteracao, max_iteracao, dim, limite_inferior, limite_superior)
    progress = iteracao / max_iteracao;
    graus_liberdade = 1 + 10 * progress;
    escala = 0.3 * (1 - progress) * (limite_superior - limite_inferior);
    ruido = escala * trnd(graus_liberdade, 1, dim);
    individuo = individuo + ruido;
    individuo = max(min(individuo, limite_superior), limite_inferior);
end

7. Mutação de Nuvem Normal3>

Utiliza o modelo de nuvem normal para gerar perturbações com incerteza linguística, combinandoexpectativa e entropia.

function individuo = mutacao_nuvem_normal(individuo, dim, limite_inferior, limite_superior)
    entropia = 0.15 * (limite_superior - limite_inferior);
    expectativa = randn(1, dim) * entropia;
    super_entropia = abs(randn(1, dim));
    hi = entropia / super_entropia;
    ruido = hi .* randn(1, dim) + expectativa;
    individuo = individuo + ruido;
    individuo = max(min(individuo, limite_superior), limite_inferior);
end

8. Mutação Periódica

Introduz periodicidade na mutação usando funções trigonométricas, criando padrões oscilatórios de exploração.

function individuo = mutacao_periodica(individuo, iteracao, dim, limite_inferior, limite_superior)
    frequencia = 0.05;
    amplitude = 0.2 * (limite_superior - limite_inferior);
    fase = 2 * pi * iteracao * frequencia;
    ruido = amplitude * sin(fase + rand(1, dim) * pi);
    individuo = individuo + ruido;
    individuo = max(min(individuo, limite_superior), limite_inferior);
end

9. Mutação Diferencial DE/best/1

Escolhe o melhor indivíduo e dois indivíduos aleatórios para criar vetor de mutação direcionado.

function vetor_mutante = mutacao_de_best1(populacao, indices, melhor_indice, dim)
    i1 = indices(1);
    i2 = indices(2);
    F = 0.8;
    vetor_mutante = populacao(melhor_indice, :) + F * (populacao(i1, :) - populacao(i2, :));
end

10. Mutação Diferencial DE/rand-to-best/1

Combina aleatoriedade com informação do melhor indivíduo, balanceando exploração e explotação.

function vetor_mutante = mutacao_de_rand_best1(populacao, indices, melhor_indice, dim)
    i1 = indices(1);
    i2 = indices(2);
    F = 0.7;
    lambda = 0.5;
    vetor_mutante = populacao(i1, :) + lambda * (populacao(melhor_indice, :) - populacao(i1, :)) + F * (populacao(i2, :) - populacao(melhor_indice, :));
end

11. Mutação Diferencial DE/rand/2

Utiliza quatro indivíduos aleatórios, oferecendo maior diversidade mas menor convergência direcionada.

function vetor_mutante = mutacao_de_rand2(populacao, indices, dim)
    i1 = indices(1);
    i2 = indices(2);
    i3 = indices(3);
    i4 = indices(4);
    F = 0.6;
    vetor_mutante = populacao(i1, :) + F * (populacao(i2, :) - populacao(i3, :)) + F * (populacao(i4, :) - populacao(i2, :));
end

12. Mutação Diferencial DE/best/2

Usa o melhor indivíduo com dois pares de diferenças, oferecendo convergência mais agressiva.

function vetor_mutante = mutacao_de_best2(populacao, indices, melhor_indice, dim)
    i1 = indices(1);
    i2 = indices(2);
    i3 = indices(3);
    i4 = indices(4);
    F = 0.5;
    vetor_mutante = populacao(melhor_indice, :) + F * (populacao(i1, :) - populacao(i2, :) + populacao(i3, :) - populacao(i4, :));
end

13. Mutação Não-Uniforme

A magnitude da mutação diminui com o tempo, permitindo exploração global inicial e explotação local posterior.

function individuo = mutacao_nao_uniforme(individuo, iteracao, max_iteracao, dim, limite_inferior, limite_superior)
    taxa_encolhimento = 0.5;
    for j = 1:dim
        if rand() < 0.1
            delta = (limite_superior(j) - limite_inferior(j)) * (1 - rand() ^ (1 - iteracao / max_iteracao) ^ taxa_encolhimento);
            direcao = sign(rand() - 0.5);
            individuo(j) = individuo(j) + direcao * delta;
        end
    end
    individuo = max(min(individuo, limite_superior), limite_inferior);
end

Exemplo de Aplicação com HHO

A seguir, apresentamos um exemplo simplificado de como aplicar as estratégias de mutação ao algoritmo Harris Hawk Optimization:

function [melhor_solucao, melhor_fitness] = hho_com_mutacao(fobj, dim, lim_inf, lim_sup, populacao_tamanho, iteracoes_max, tipo_mutacao)
    % Inicialização da população
    populacao = lim_inf + (lim_sup - lim_inf) * rand(populacao_tamanho, dim);
    fitness = zeros(populacao_tamanho, 1);
    
    for i = 1:populacao_tamanho
        fitness(i) = fobj(populacao(i, :));
    end
    
    [melhor_fitness, indice_melhor] = min(fitness);
    melhor_solucao = populacao(indice_melhor, :);
    
    for iter = 1:iteracoes_max
        energia_exploracao = 2 * (1 - iter / iteracoes_max);
        
        for i = 1:populacao_tamanho
            for j = 1:dim
                r1 = rand();
                r2 = rand();
                r3 = rand();
                
                if energia_exploracao >= 1
                    X_aleatorio = populacao(floor(rand() * populacao_tamanho) + 1, :);
                    diferenca = abs(2 * r2 - X_aleatorio(j));
                    populacao(i, j) = X_aleatorio(j) - diferenca * energia_exploracao;
                else
                    if r3 >= 0.5
                        populacao(i, j) = melhor_solucao(j) - energia_exploracao * abs(r1 * melhor_solucao(j) - populacao(i, j));
                    else
                        populacao(i, j) = melhor_solucao(j) - energia_exploracao * abs(r1 * melhor_solucao(j) - populacao(i, j));
                    end
                end
            end
            
            % Aplicar estratégia de mutação selecionada
            populacao(i, :) = aplicar_mutacao(populacao(i, :), melhor_solucao, iter, iteracoes_max, dim, lim_inf, lim_sup, tipo_mutacao);
            
            fitness_atual = fobj(populacao(i, :));
            
            if fitness_atual < fitness(i)
                fitness(i) = fitness_atual;
                if fitness_atual < melhor_fitness
                    melhor_fitness = fitness_atual;
                    melhor_solucao = populacao(i, :);
                end
            end
        end
    end
end

function individuo = aplicar_mutacao(individuo, elite, iter, max_iter, dim, lim_inf, lim_sup, tipo)
    switch tipo
        case 1
            individuo = mutacao_gaussiana(individuo, dim, lim_inf, lim_sup);
        case 2
            individuo = mutacao_gaussiana_elite(individuo, elite, dim, lim_inf, lim_sup);
        case 3
            individuo = mutacao_cauchy(individuo, dim, lim_inf, lim_sup);
        case 4
            individuo = mutacao_cauchy_inversa(individuo, dim, lim_inf, lim_sup);
        case 5
            individuo = mutacao_t_student(individuo, dim, lim_inf, lim_sup);
        case 6
            individuo = mutacao_t_adaptativa(individuo, iter, max_iter, dim, lim_inf, lim_sup);
        case 7
            individuo = mutacao_nuvem_normal(individuo, dim, lim_inf, lim_sup);
        case 8
            individuo = mutacao_periodica(individuo, iter, dim, lim_inf, lim_sup);
        case 9
            indices = randperm(dim, 2);
            individuo = mutacao_de_best1([individuo; elite], indices, 2, dim);
        case 10
            indices = randperm(dim, 2);
            individuo = mutacao_de_rand_best1([individuo; elite], indices, 2, dim);
        case 11
            indices = randperm(dim, 4);
            individuo = mutacao_de_rand2([individuo; elite; elite; elite], indices, dim);
        case 12
            indices = randperm(dim, 4);
            individuo = mutacao_de_best2([individuo; elite; elite; elite], indices, 2, dim);
        case 13
            individuo = mutacao_nao_uniforme(individuo, iter, max_iter, dim, lim_inf, lim_sup);
    end
end

Configurações de Teste

Para validação experimental, utilize os seguintes parâmetros:

  • Número máximo de iterações: 500
  • Tamanho da população: 50
  • Funções de teste: conjunto CEC2017
  • Número de execuções: 2 por algoritmo

Conclusão

As treze estratégias de mutação apresentadas oferecem diferentes mecanismos para melhorar o desempenho de algoritmos de otimização. A escolha da estratégia adequada depende das características específicas do problema, como a presença de múltiplos ótimos locais, a dimensionalidade do espaço de busca e os requisitos de precisão. Recomenda-se realizar experimentos comparativos para identificar a estratégia mais eficiente para cada aplicação específica.

Tags: otimizacao-metaheuristica algoritmo-harris-hawk estrategias-mutacao engenharia-de-algoritmos MATLAB

Publicado em 7-19 16:15