MATLAB数学建模:智能优化算法-人工鱼群算法

MATLAB 数学建模: 人工鱼群算法

1. 基本原理

人工鱼群算法是一种受鱼群聚集规律而启发的优化算法. 在人工鱼群算法中, 我们假定鱼群的活动行为分为: 觅食行为, 群聚行为, 追随行为和随机行为.

  • 觅食行为, 基于 “鱼倾向于游向食物最多的水域” 这一假设, 等价于在寻找最优解的过程中, 向相对较优的方向行进的迭代原则.

  • 群聚行为, 借鉴了真实鱼群中, 落单的个体总倾向于回到群体的特性. 这一行为受三条子规则所限定:

    1. 分隔规则: 避免和临近伙伴之间过于拥挤
    2. 对准规则: 确保和临近伙伴的方向一致.
    3. 内聚规则: 尽量向临近伙伴的中心移动.
  • 追尾行为, 确保了每一个人工鱼个体均会追逐临近的最活跃个体. 它等价于在优化过程中, 向位于当前点附近的, 极优化点前进的过程.

  • 随机行为, 保证了人工鱼在 “目力所及范围内” 随机移动. 这样有助于在寻找最优解过程中跳出局部最优.


2. 程序设计

我们规定以下变量和符号:

  • n 目标空间维度
  • N 人工鱼数量
  • X 每条人工鱼状态 X = ( x 1 , x 2 , ⋯   , x n ) X = (x_1, x_2, \cdots, x_n) X=(x1,x2,,xn), 各分量为需要寻找最优的变量
  • Y Y = f ( X ) Y = f(X) Y=f(X), 人工鱼所在位置的食物浓度, 即寻优过程中的适应度.
  • d 人工鱼个体间距离, d = ∣ ∣ x i − x j ∣ ∣ d = ||x_i - x_j|| d=∣∣xixj∣∣
  • v 人工鱼感知范围
  • s 人工鱼移动步长
  • δ 拥挤度因子, 反映拥挤程度
  • t 人工鱼每次觅食最大尝试次数

2.1 觅食行为

觅食行为, 指人工鱼总是倾向于沿食物较多的方向游动的行为. 逻辑如下:

  1. 对于每一条人工鱼 X i X_i Xi, 它按照规则
    X j = X i + r a n d ( ) ⋅ v X_j = X_i + rand()\cdot v Xj=Xi+rand()v
    随机选定一个新状态 X j X_j Xj, 并比照新旧两个状态的适应度.

  2. X j X_j Xj 适应度高于 X i X_i Xi, 则该鱼按照规则
    X i ′ = X i + r a n d ( ) ⋅ s ⋅ X j − X i ∣ ∣ X j − X i ∣ ∣ X_i' = X_i + rand()\cdot s\cdot \frac{X_j - X_i}{||X_j - X_i||} Xi=Xi+rand()s∣∣XjXi∣∣XjXi
    X j X_j Xj 方向前进一个步长.

  3. 若反复判断 t t t 次后仍然无法在附近找到优于现有状态 X i X_i Xi 的新状态, 人工鱼将依据规则
    X i ′ = X i + r a n d ( ) ⋅ s X_i' = X_i + rand()\cdot s Xi=Xi+rand()s
    随机移动一个步长.


2.2 群聚行为

真实世界中的鱼群在游弋过程中为了躲避敌害会自然地群聚. 逻辑如下:

  1. 对于每一条人工鱼 X i X_i Xi, 搜索其视野内
    d i j ⩽ v d_{ij}\leqslant v dijv
    的伙伴并统计其数量, 记为 n f n_f nf, 并且确定其周边伙伴的中间位置 X c X_c Xc.
  2. 判断伙伴所处的中心位置状态 Y c n f \frac{Y_c}{n_f} nfYc. 若状态较优且不太拥挤,即
    Y c n f < δ Y i \frac{Y_c}{n_f}<\delta Y_i nfYc<δYi
    则向该中心位置移动一个步长, 否则将执行觅食行为.
function [x_swarm, x_swarm_fitness] = swarm(x,i,N,v,f,delta,t,d,ub,lb,s)
%% Compute fitness rate under the circunstance of SWARMING
        nf_swarm = 0;
        Xc = 0;
        label_swarm = 0;                    % The sign of swarming happened or not
        % Fix the Position of  the center, compute the number of companions
        for j = 1:N
            if norm(x(j,:) - x(i,:)) < v
                nf_swarm = nf_swarm + 1;    % COunt the number of companions
                Xc = Xc + x(j,:);           % Add up the number of Sakanas
            end
        end
        
        Xc = Xc - x(i,:);                   % Delete myself
        nf_swarm = nf_swarm - 1;
        Xc = Xc / nf_swarm;
        
        % Judge the center is narrow or not
        if (f(Xc)/nf_swarm < delta*f(x(i,:))) && (f(Xc) < f(x(i,:)))
            x_swarm = x(i,:) + rand*s.*(Xc - x(i,:)) ./ norm(Xc - x(i,:));
            %Bound processing
            ub_flag = x_swarm > ub;
            lb_flag = x_swarm < lb;
        x_swarm = (x_swarm .* (~(ub_flag + lb_flag))) + ub .* ub_flag + lb .* lb_flag;
        
        x_swarm_fitness = f(x_swarm);
        else
            % PREYING
            label_prey = 0;     % A sign of whether preying will find a better state than current state
            for j = 1:t
                
                %Find a state randomly
                x_prey_rand = x(i,:) + v .* (-1 + 2 .* rand(1,d));
                ub_flag2 = x_prey_rand > ub;
                lb_flag2 = x_prey_rand < lb;
                
                x_prey_rand = (x_prey_rand .* (~(ub_flag2 + lb_flag2))) + ub .* ub_flag2 + lb .* lb_flag2;
                
                %judgement: better, or not?
                
                if f(x(i,:)) > f(x_prey_rand)
                    x_swarm = x(i,:) + rand*s .* (x_prey_rand - x(i,:)) ./ norm(x_prey_rand - x(i,:));
                    ub_flag2 = x_swarm > ub;
                    lb_flag2 = x_swarm < lb;
                    x_swarm = (x_swarm .* (~(ub_flag2 + lb_flag2))) + ub .* ub_flag2 + lb .* lb_flag2;
                    x_swarm_fitness = f(x_swarm);
                    label_prey = 1;
                    break;
                end
            end
            
            % Acting randomly
            if label_prey == 0
                x_swarm = x(i,:) + s * (-1 + 2*rand(1,d));
                ub_flag2 = x_swarm > ub;
                lb_flag2 = x_swarm < lb;
                x_swarm = (x_swarm .* (~(ub_flag2 + lb_flag2))) + ub .* ub_flag2 + lb .* lb_flag2;
                x_swarm_fitness = f(x_swarm);
            end
        end
end


2.3 追尾行为

执行追尾过程时, 人工鱼将向其视野内适应度最高的个体移动. 逻辑如下:

  1. X i X_i Xi 搜索其视野内适应度最高的个体, 记为 X j X_j Xj, 同时对目标个体 X j X_j Xj 视野内所有个体的数量计数 n f n_f nf.
  2. 判断目标个体位置状态 Y j n f \frac{Y_j}{n_f} nfYj. 若该位置状态较优且不太拥挤, 则 X i X_i Xi 向目标 X j X_j Xj 移动一个步长, 否则执行觅食行为.
function [x_follow, x_follow_fitness] = follow(x,i,N,v,f,delta,t,d,ub,lb,s)
        fitness_follow = inf;
        label_follow = 0;           % A Sign marking following has happened or not
        % Search the *best* individual in sight
        for j = 1:N
            if (norm(x(j,:) - x(i,:)) < v) && (f(x(j,:)) < fitness_follow)
                best_pos = x(j,:);
                fitness_follow = f(x(j,:));
            end
        end
        
        %Search The Number Of Companions In Sight
        nf_follow = 0;
        for j = 1:N
            if norm(x(j,:) - best_pos) < v
                nf_follow = nf_follow + 1;
            end
        end
        nf_follow = nf_follow - 1;      % Delete myself
        % Judge: The Center Is Narrow or not?
        if (fitness_follow/nf_follow)<delta * f(x(i,:)) && (fitness_follow < f(x(i,:)))
            x_follow = x(i,:) + rand *s .* (best_pos - x(i,:)) ./ norm(best_pos - x(i,:));
            %Boundry Processing
            ub_flag2 = x_follow > ub;
            lb_flag2 = x_follow < lb;
            x_follow = (x_follow .* (~(ub_flag2 + lb_flag2))) + ub .* ub_flag2 + lb .* lb_flag2;
            label_follow = 1;
            x_follow_fitness = f(x_follow);
        else
            % PREYING
            label_prey = 0;     % A sign of whether preying will find a better state than current state
            for j = 1:t
                
                %Find a state randomly
                x_prey_rand = x(i,:) + v .* (-1 + 2 .* rand(1,d));
                ub_flag2 = x_prey_rand > ub;
                lb_flag2 = x_prey_rand < lb;
                x_prey_rand = (x_prey_rand .* (~(ub_flag2 + lb_flag2))) + ub .* ub_flag2 + lb .* lb_flag2;
                
                %judgement: better, or not?
                
                if f(x(i,:)) > f(x_prey_rand)
                    x_follow = x(i,:) + rand*s .* (x_prey_rand - x(i,:)) ./ norm(x_prey_rand - x(i,:));
                    ub_flag2 = x_follow > ub;
                    lb_flag2 = x_follow < lb;
                    x_follow = (x_follow .* (~(ub_flag2 + lb_flag2))) + ub .* ub_flag2 + lb .* lb_flag2;
                    x_follow_fitness = f(x_follow);
                    label_prey = 1;
                    break;
                end
            end
            
            %random behaviour
            
            if label_prey == 0
                x_follow = x(i,:) + s .* (-1 + 2*rand(1,d));
                ub_flag2 = x_follow > ub;
                lb_flag2 = x_follow < lb;
                x_follow = (x_follow .* (~(ub_flag2 + lb_flag2))) + ub .* ub_flag2 + lb .* lb_flag2;
                x_follow_fitness = f(x_follow);
            end
end



2.4 随机行为

在上文所提到的 “觅食行为” 的最后一种判断情况中, 人工鱼将会执行的行为就是随机行为.


3. 代码实现

附主函数代码如下:

clc; clear all;


%% Define variables
v = 25;                     %Perception Distance
s = 3;                      %Maximum Step Size
N = 30;                     %The Number Of Artificial Sakana
d = 10;                     %Current Dimension
t = 50;                     %Maximum Iteration Time
delta = 27;                 %Factor of Congestion

%% Construct a function for testing
f = @(x) sum(3*x.^4);
ub = 100;                   %Upper Limit Of Boundrary
lb = -100;                  %Lower Limit Of Boundrary

df = [];                    %Store Target Function value of 50 states
Iteration = 1;              %Initialize Iteration Rate
Max_iteration = 500;        %Maximum Iteration Rate

%% Initialize Artificial Sakana Group

x = lb + rand(N,d).*(ub - lb);


%% Compute fitness rate of 10 initial state
for i = 1:N
    fitness_sakana(i) = f(x(i,:));
end

%% Define Best Fitness of Initial State
[best_fitness,I] = min(fitness_sakana);
best_x = x(I);                              %Best Artificial Sakana At Initial State


while Iteration <= Max_iteration
    for i = 1:N
        %%Swarm
        [x_swarm, x_swarm_fitness] = swarm(x,i,N,v,f,delta,t,d,ub,lb,s);
        
        %%Follow
        [x_follow, x_follow_fitness] = follow(x,i,N,v,f,delta,t,d,ub,lb,s);
        
        %%Judgement
        if x_follow_fitness < x_swarm_fitness
            x(i,:) = x_follow;
        else
            x(i,:) = x_swarm;
        end
    end
    
    %% Update Information In Time
    for i = 1:N
        if (f(x(i,:)) < best_fitness)
            best_fitness = f(x(i,:));
            best_x = x(i,:);
        end
    end
    Convergence_curve(Iteration) = best_fitness;
    Iteration = Iteration + 1;
    %% Display Iteration Time And Current Best Fit Rate
    if mod(Iteration, 25) == 0
        display(['Iteration times: ',num2str(Iteration),'BestFitRate: ',num2str(best_fitness)]);
        display(['BestArtificialSakana: ', num2str(best_x)]);
    end
end

%% Print
figure('Position', [284 214 660 290])
subplot(1,2,1);
x = -100:1:100;
y = x;
L = length(x);
for i = 1:L
    for j = 1:L
        F(i,j) = (3*x(i) .^4) + (3*y(j) .^4);
    end
end
surfc(x,y,F,'LineStyle', 'none');
title('Test Function')
xlabel('x_1');
ylabel('y_1');
zlabel(['sum','(x_1,x_2)'])
grid on

subplot(1,2,2);
semilogy(Convergence_curve, 'Color','r')
title('Convergence Curve')
xlabel('Iteration');
ylabel('Best Fitness');
axis tight
grid on
box on

Output

  • 11
    点赞
  • 86
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值