人工鱼群算法Matlab实现

人工鱼群算法Matlab实现

1 基本思想

  人工鱼群算法是一种基于模拟鱼群行为的优化算法,是由李晓磊等在2002年提出的一种新型的寻优算法。在一片水域中,鱼生存的数目最多的地方就是本水域中富含营养物质最多的地方,依据这一特点来模仿鱼群的觅食等行为,从而实现全局寻优,这就是鱼群算法的基本思想。
  在鱼类的活动中,可以分为觅食行为、聚群行为、追尾行为和随机行为这四种行为,如何利用简单有效的方式来构造实现这些行为将是算法实施的主要问题。
  觅食行为主要就是循着食物多的方向游动的一种行为,在寻优中则是向较优方向进行的迭代方式,如鱼群模式中的视觉概念;
  在聚群行为中,借鉴的思想对每条人工鱼规定了这样两个规则:
    1)尽量向邻近伙伴的中心移动;
    2)避免过分拥挤,这样就能基本实现人工鱼的聚群能力;
  追尾行为就是一种向临近的最活跃者追逐的行为,在寻优算法中可以理解为是向附近的最优化伙伴前进的过程;
  随机行为就是人工鱼在其视野内随机移动的行为,在寻优算法中这种行为有助于解跳出局部最优。

2 算法剖析

  假设在一个n维的目标搜索空间中,有N条组成一个群体的人工鱼,每天人工鱼个体的状态可表示为向量 X = ( x 1 , x 2 , … , x n ) X=(x_1,x_2,…,x_n) X=x1,x2,,xn,其中 x i ( i = 1 , … … n ) x_i(i=1,……n) xii=1,n为欲寻优的变量:人工鱼当前所在位置的食物浓度表示为 Y = f ( X ) Y=f(X) Y=f(X),其中 f ( ) f() f()为目标函数;人工鱼个体间距离表示为 d = ∣ ∣ x i − x j ∣ ∣ d=||x_i-x_j|| d=xixj(这是二范数); v i s u a l visual visual表示人工鱼的感知范围, s t e p step step为人工鱼移动步长, δ δ δ为拥挤度因子; t r y n u m b e r trynumber trynumber表示人工鱼每次觅食最大试探次数。

2.1 觅食行为

  指鱼循着食物多的方向游动的一种行为,人工鱼 X i X_i Xi在其视野内随机选择一个状态 X j X_j Xj,分别计算它们的目标函数值进行比较,如果发现 Y j Y_j Yj Y i Y_i Yi优( Y j Y_j Yj Y i Y_i Yi分别为 X j X_j Xj X i X_i Xi的适应度值),则Xi向Xj的方向移动一步;否则, X i X_i Xi继续在其视野内选择状态 X j X_j Xj,判断是否满足前进条件,反复尝试 t r y n u m b e r trynumber trynumber次后,仍没有满足前进条件,则随机移动一步使 X i X_i Xi到达一个新的状态。表达式如下:
X j = X i + r a n d ( ) ∗ v i s u a l (1) X_j=X_i+rand()*visual \tag{1} Xj=Xi+rand()visual(1)                 
X n e x t = X i + r a n d ( ) ∗ s t e p ∗ X j − X i ∣ ∣ X j − X i ∣ ∣ (2) X_{next}=X_i+rand()*step*\frac{X_j-X_i}{\left | \left | X_j-X_i \right | \right |}\tag{2} Xnext=Xi+rand()stepXjXiXjXi(2)
X n e x t = X i + r a n d ( ) ∗ s t e p (3) X_{next}=X_i+rand()*step \tag{3} Xnext=Xi+rand()step(3)                
  其中rand()是介于0和1之间的随机数。

人工鱼的视觉描述
人 工 鱼 的 视 觉 描 述 人工鱼的视觉描述
  框架图如下所示:
在这里插入图片描述
伪代码段如下:

for i = 1:N
	for j = 1:Try_number
        Xj=x(i)+Visual.*rand();%人工鱼Xi按式(1)在其视野内随机选择一个状态Xj
        if f(Xj)<f(x(i))	   %比较Xj和Xi的适应度
            X_next= x(i)+rand()*step*(Xj-x(i))/norm(Xj-x(i)); %人工鱼Xi按式(2)朝着Xj方向移动一步,norm()函数表示二范数 
            break;
        else
        	X_next=x(i)+step*rand();
        end
    end
end
2.2 聚群行为

  鱼在游动过程中为了保证自身的生存和躲避危害会自然地聚集成群 。人工鱼 X i X_i Xi搜索其视野内( d i j < v i s u a l d_{ij}<visual dij<visual)的伙伴数目 n f n_f nf及中心位置 X c X_c Xc,若 Y c / n f < δ Y i Y_c/n_f< δY_i Yc/nf<δYi(求极小值时使用小于号,在求极大值时则相反; Y c Y_c Yc Y i Y_i Yi分别为 X c X_c Xc X i X_i Xi的适应度值),表明伙伴中心位置状态较优且不太拥挤,则 X i X_i Xi朝伙伴的中心位置移动一步,否则执行觅食行为;
  框架图如下所示:
在这里插入图片描述
伪代码段如下:

nf=0;X_inside=0;
for i = 1:N
    for j = 1:N   
        if norm(x(j)-x(i))<Visual 		% 求人工鱼Xi与其他人工鱼之间的距离
            nf = nf+1;                  %统计在视野范围内的鱼数量   
            X_inside= X_inside+x(j);    %将视野范围内的鱼进行累加
        end
         X_inside=X_inside-x(i);  		%需要去除Xi本身;因为在 一开始计算时,i=j,把中心的鱼也进行了一次计算
         nf=nf-1;   
         Xc = X_inside/nf; 				%此时Xc表示Xi感知范围其他伙伴的中心位置; 
         if  f(Xc)/nf < δ*f(x(i))
            x_next=x(i)+rand*Step*(Xc-x(i))/norm(Xc-x(i)); 
         else
             进行觅食行动
         end
    end
end
2.3 追尾行为

  指鱼向其视野区域内的最优方向移动的一种行为。人工鱼 X i X_i Xi搜索其视野内( d i j < v i s u a l d_{ij}<visual dij<visual)适应度最高的个体 X j X_j Xj,其适应度值为 Y j Y_j Yj,并探索人工鱼 X j X_j Xj视野内的伙伴数目 n f n_f nf,若 Y j / n f < δ Y i Y_j/n_f< δY_i Yj/nf<δYi,表明 X j X_j Xj状态较优且不太拥挤,则 X i X_i Xi X j X_j Xj位置移动一步,否则执行觅食行为;
  框架图如下所示:
在这里插入图片描述
伪代码段如下:

Y_max=inf;nf=0;
for i = 1:N    
    %搜索人工鱼Xi视野范围内的最高适应度个体Xj
    for j = 1:N     
        if norm(x(j)-x(i))<Visual && f(x(j))<Y_max		% 求人工鱼Xi与其他人工鱼之间的距离
            X_max=x(j);        
            Y_max=f(x(j));
        end
    end
    %搜索人工鱼Xj视野范围内的伙伴数量
    for j = 1:N        
        if(norm(x(j)-X_max)<Visual)       
            nf=nf+1;
        end
    end
    nf=nf-1;%去掉他本身
    if Y_max/nf<delta*f(x(i))
        x_next= x(i,:)+rand*Step.*(temp_maxX-x(i,:))./norm(temp_maxX-x(i,:));
    else
        进行觅食行为;
    end
end
2.4 算法总述

  综上所述,算法在运算过程中,会同时进行聚群和追尾行为。而觅食行为属于这两种行为中发现聚群对象或者追尾对象附近拥挤度过大时,人工鱼选择的行为方式,若在觅食过程中,未发现比自身适应度高的人工鱼,则按步长step随机移动。最后对聚群行为和追尾行为得到的适应度值进行比较,选择优秀的人工鱼作为下一代的个体。其总框架图如下:
在这里插入图片描述

3 分析拥挤度因子 δ δ δ

3.1 拥挤度因子的取值

  在求极小值问题中: δ = α n m a x , α ∈ ( 0 , 1 ] δ=αn_{max}, α∈(0,1] δ=αnmax,α(0,1]
  在求极大值问题中: δ = 1 α n m a x , α ∈ ( 0 , 1 ] δ=\frac{1}{αn_{max}},α∈(0,1] δ=αnmax1,α(0,1]
  其中 α α α为极值接近水平, n m a x n_{max} nmax为期望在该邻域内聚集的最大人工鱼数目。

3.2 拥挤度因子的作用机理

  对追尾行为的描述
在这里插入图片描述
  图中af0为人工鱼af1-5在各自视野内的最优人工鱼,其实物浓度为 Y j Y_j Yj,C1为以af0为圆心,以视野范围为半径的圆,即能探知af0的最远距离,人工鱼越靠近af0,状态越优。
  求极大值情况下:当 δ n f ≤ 1 δn_f\leq 1 δnf1时,所有人工鱼af1-5都执行追尾行为,向af0游动;
δ = 1 α n m a x δ=\frac{1}{αn_{max}} δ=αnmax1
δ n f = n f α n m a x ≤ 1 δn_f =\frac{n_f}{αn_{max}}\leq 1 δnf=αnmaxnf1
  当 α α α=1的时候,可以明显看出来 n f ≤ n m a x n_f \leq n_{max} nfnmax,即说明人工鱼视野范围内不拥挤。

  当 δ n f > 1 δn_f >1 δnf1时,若C2的食物浓度为 Y j δ n f \frac{Y_j}{δn_f } δnfYj的等浓度食物圈,则C2与C1间的人工鱼af1、af2、af3执行追尾行动,向af0游动,人工鱼af4、af5执行觅食行为。此时δnf 越大执行追尾行动的人工鱼越少,反之越多。

3.2 拥挤度因子的影响

  以极大值为例(极小值的情况正好和极大值相反), δ δ δ越大,表明允许的拥挤程度越小,人工鱼摆脱局部最优的能力越强;但是收敛的速度会有所减缓,这主要因为人工鱼在逼近极值的同时,会因避免过分拥挤而随机走开或者受其它人工鱼的排斥作用,不能精确逼近极值点。可见, δ δ δ的引入避免了人工鱼过度拥挤而陷入局部极值,另一方面,该参数会使得位于极值点附近的人工鱼之间存在相互排斥的影响,而难以向极值点精确逼近,所以,对于某些局部极值不是很严重的具体问题,可以忽略拥挤的因素,从而在简化算法的同时也加快了算法的收敛速度和提高结果的精确程度。

4 算法实现

%sum(sin(x)./x) 极小值
clear all; 
close all;
clc;

Visual = 25;   %人工鱼的感知距离
Step = 3;     %人工鱼的移动最大步长
N = 30;         %人工鱼的数量
dim=10;          %人工鱼维度
Try_number = 50;%迭代的最大次数
delta=27;     %拥挤度因子

%测试函数
f=@(x) sum(x.^2);
ub=100;%边界上限
lb=-100;%边界下限

d = [];%存储50个状态下的目标函数值;
Iteration = 1; %
Max_iteration = 500;%迭代次数

%初始化人工鱼种群
x=lb+rand(N,dim).*(ub-lb);


%计算10个初始状态下的适应度值;
for i = 1:N
    fitness_fish(i) = f(x(i,:));   
end
[best_fitness,I] = min(fitness_fish);         % 求出初始状态下的最优适应度;
best_x = x(I,:);             % 最优人工鱼;



while Iteration<=Max_iteration
    for i = 1:N
        %% 聚群行为
        nf_swarm=0;
        Xc=0;
        label_swarm =0;  %群聚行为发生标志
        %确定视野范围内的伙伴数目与中心位置
        for j = 1:N 
            if norm(x(j,:)-x(i,:))<Visual
                nf_swarm = nf_swarm+1;  %统计在感知范围内的鱼数量   
                Xc = Xc+x(j,:);       %将感知范围内的鱼进行累加
            end
        end
        Xc=Xc-x(i,:);   %需要去除本身;因为在 一开始计算时,i=j,把中心的鱼也进行了一次计算
        nf_swarm=nf_swarm-1;
        Xc = Xc/nf_swarm; %此时Xc表示视野范围其他伙伴的中心位置; 
        %判断中心位置是否拥挤
        if  (f(Xc)/nf_swarm < delta*f(x(i,:))) && (f(Xc)<f(x(i,:)))     
            x_swarm=x(i,:)+rand*Step.*(Xc-x(i,:))./norm(Xc-x(i,:)); 
            %边界处理
            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
            %觅食行为
            label_prey =0;    %判断觅食行为是否找到优于当前的状态
            for j = 1:Try_number
                %随机搜索一个状态
                x_prey_rand = x(i,:)+Visual.*(-1+2.*rand(1,dim));
                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;   
                %判断搜索到的状态是否比原来的好
                if f(x(i,:))>f(x_prey_rand)
                    x_swarm = x(i,:)+rand*Step.*(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
            %随机行为
            if label_prey==0
                x_swarm = x(i,:)+Step*(-1+2*rand(1,dim));
                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

        %% 追尾行为
        fitness_follow = inf;  
        label_follow =0;%追尾行为发生标记
        %搜索人工鱼Xi视野范围内的最高适应度个体Xj
        for j = 1:N     
            if (norm(x(j,:)-x(i,:))<Visual) && (f(x(j,:))<fitness_follow)      
                best_pos = x(j,:);      
                fitness_follow = f(x(j,:));     
            end
        end
         %搜索人工鱼Xj视野范围内的伙伴数量
        nf_follow=0;
        for j = 1:N     
            if norm(x(j,:)-best_pos)<Visual   
                nf_follow=nf_follow+1;
            end
        end
        nf_follow=nf_follow-1;%去掉他本身
        %判断人工鱼Xj位置是否拥挤
        if (fitness_follow/nf_follow)<delta*f(x(i,:)) && (fitness_follow<f(x(i,:)))  
            x_follow = x(i,:)+rand*Step.*(best_pos-x(i,:))./norm(best_pos-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;   

            label_follow =1;
            x_follow_fitness=f(x_follow);
        else
            %觅食行为
            label_prey =0;    %判断觅食行为是否找到优于当前的状态
            for j = 1:Try_number
                %随机搜索一个状态
                x_prey_rand = x(i,:)+Visual.*(-1+2.*rand(1,dim));
                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;   
                %判断搜索到的状态是否比原来的好
                if f(x(i,:))>f(x_prey_rand)
                    x_follow = x(i,:)+rand*Step.*(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
            %随机行为
            if label_prey==0
                x_follow = x(i,:)+Step*(-1+2*rand(1,dim));
                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
    
        % 两种行为找最优
        if x_follow_fitness<x_swarm_fitness
            x(i,:)=x_follow;
        else
            x(i,:)=x_swarm;
        end
    end

    %% 更新信息
    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;
    if mod(Iteration,50)==0
        display(['迭代次数:',num2str(Iteration),'最优适应度:',num2str(best_fitness)]);
        display(['最优人工鱼:',num2str(best_x)]);
    end
end

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)=x(i).^2+y(j).^2;
    end
end
surfc(x,y,F,'LineStyle','none');  
title('Test function') 
xlabel('x_1'); 
ylabel('x_2'); 
zlabel(['sum','( x_1 , x_2 )']) 
grid off 

subplot(1,2,2); 
semilogy(Convergence_curve,'Color','b') 
title('Convergence curve') 
xlabel('Iteration'); 
ylabel('Best fitness'); 
axis tight 
grid off 
box on 

结果如下:
在这里插入图片描述

  • 83
    点赞
  • 437
    收藏
    觉得还不错? 一键收藏
  • 20
    评论
人工鱼群算法(Artificial Fish Swarm Algorithm)是一种模拟自然鱼群觅食行为的优化算法,可以用于求解复杂问题的全局最优解。下面是一个简单的人工鱼群算法MATLAB实现示例: ```matlab function [best_solution, best_fitness] = artificialFishSwarmAlgorithm(problem, population_size, max_iterations) % 初始化鱼群 population = initializePopulation(problem, population_size); % 迭代更新鱼群 for iteration = 1:max_iterations % 更新个体行为 for i = 1:population_size population(i).position = updateFishPosition(population(i).position, problem); population(i).fitness = calculateFitness(population(i).position, problem); end % 更新群体行为 population = updateCollectiveBehavior(population, problem); % 获取当前最佳解 [~, index] = min([population.fitness]); best_solution = population(index).position; best_fitness = population(index).fitness; % 输出当前迭代结果 disp(['Iteration: ' num2str(iteration) ', Best Fitness: ' num2str(best_fitness)]); end end function population = initializePopulation(problem, population_size) % 随机生成初始鱼群位置 for i = 1:population_size population(i).position = rand(1, problem.dimension) * (problem.upper_bound - problem.lower_bound) + problem.lower_bound; population(i).fitness = calculateFitness(population(i).position, problem); end end function new_position = updateFishPosition(position, problem) % 随机选择移动方向 step = rand(1, problem.dimension) - 0.5; % 更新位置 new_position = position + step; % 限制位置在搜索空间内 new_position = max(new_position, problem.lower_bound); new_position = min(new_position, problem.upper_bound); end function fitness = calculateFitness(position, problem) % 计算适应度函数值 fitness = problem.objective(position); end function population = updateCollectiveBehavior(population, problem) % 计算鱼群的中心位置 center_position = mean([population.position]); % 更新鱼群行为 for i = 1:length(population) % 向中心位置移动 population(i).position = population(i).position + rand(1, problem.dimension) .* (center_position - population(i).position); % 更新适应度函数值 population(i).fitness = calculateFitness(population(i).position, problem); end end ``` 在上述代码中,`problem`是一个包含问题信息的结构体,包括问题的维度(`dimension`)、搜索空间的上界(`upper_bound`)和下界(`lower_bound`)、目标函数(`objective`)等。`population_size`是鱼群的大小,`max_iterations`是最大迭代次数。 你可以根据具体的问题定义目标函数,并通过修改初始化方法、个体行为更新方法和群体行为更新方法来适应不同的应用场景。希望这个示例对你有所帮助!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值