基于matlab的麻雀算法求解

一麻雀算法讲解

建立麻雀搜索算法的数学模型,主要规则如下所述:

      1.1发现者通常拥有较高的能源储备并且在整个种群中负责搜索到具有丰富食物的区域,为所有的加入者提供觅食的区域和方向。在模型建立中能量储备的高低取决于麻雀个体所对应的适应度值(Fitness Value)的好坏。
     1.2一旦麻雀发现了捕食者,个体开始发出鸣叫作为报警信号。当报警值大于安全值时,发现者会将加入者带到其它安全区域进行觅食。发现者和加入者的身份是动态变化的。只要能够寻找到更好的食物来源,每只麻雀都可以成为发现者,但是发现者和加入者所占整个种群数量的比重是不变的。也就是说,有一只麻雀变成发现者必然有另一只麻雀变成加入者。
     1.3加入者的能量越低,它们在整个种群中所处的觅食位置就越差。一些饥肠辘辘的加入者更有可能飞往其它地方觅食,以获得更多的能量。
     1.4在觅食过程中,加入者总是能够搜索到提供最好食物的发现者,然后从最好的食物中获取食物或者在该发现者周围觅食。与此同时,一些加入者为了增加自己的捕食率可能会不断地监控发现者进而去争夺食物资源。
     1.5当意识到危险时,群体边缘的麻雀会迅速向安全区域移动,以获得更好的位置,位于种群中间的麻雀则会随机走动,以靠近其它麻雀。

二求解结果展示

                                                   14个城市路径求解

三matalb代码展示

%%  基于麻雀算法的tsp问题
%% 1.清空环境变量
clear;
clc;
%% 2.导入数据
% load citys51.mat;          %数据集的变量名为citys
% % %% 3.计算城市间相互距离
% citys=citys51;
load citys_data.mat;   
n=size(citys,1);
D=zeros(n,n);
for i=1:n
    for j=i+1:n
        D(i,j)=sqrt(sum((citys(i,:)-citys(j,:)).^2));
        D(j,i)=D(i,j);
    end
end
%%4 初始化参数
ST=0.8;    %预警阈值
m=500;       %麻雀种群数量
popn=m;
pop=zeros(m,n);
PD_percent=0.2;   
SD_percent=0.2;      
genmax=1000;       %最大迭代次数
gen=1;
fitness=zeros(m,1);             %适应度函数值
Pbest=zeros(m,n);               %个体极值路径
Pbest_fitness=zeros(m,1);       %个体极值
Gbest=zeros(genmax,n);          %群体极值路径
Gbest_fitness=zeros(genmax,1);  %群体极值记录
Length_ave=zeros(genmax,1);     %各代路径的平均长度
%% 5产生随机麻雀种群
% 随机产生麻雀位置
for i=1:m
    pop(i,:)=randperm(n);
end
% 计算适应度函数值
for i=1:m
    for j=1:n-1
        fitness(i)=fitness(i) + D(pop(i,j),pop(i,j+1));
    end
        fitness(i)=fitness(i) + D(pop(i,end),pop(i,1));
end
% 极端值
% Pbest_fitness=fitness;   %进行预分配
% Pbest=pop;
% [Gbest_fitness(1),min_index]=min(fitness);
% Gbest(1,:)=pop(min_index,:);
PDn=round(PD_percent*popn);    %捕食者个数
SDn=round(SD_percent*popn);    %预警者的个数
while   gen<=genmax
   [~,sortindex]=sort(fitness);  %对麻雀的适应度升序排列,为了更好的找到发现者与跟随者
   fitness_new=fitness; 
   pop_new=pop;
   [fmax,worse]=max(fitness);   %找到最差位置
   pop_worst=pop(worse,:);
   [fmin,best]=min(fitness);    %找到最佳的位置
   pop_best=pop(best,:);
   if rand<ST          %根据预警值判断位置变换
        for i=1:PDn
           a=sortindex(i);
           r=exp(-i/(rand*genmax));
           if rand<=r    %距离近,保持不动
             pop_new(a,:)=pop_new(a,:);
           else
             dim=round(0.2*m);
             pop_new(a,:)=position_change_little(pop(a,:),dim);
           end
        end
    else
        for i=1:PDn
            a=sortindex(i);
            dim=round(rand*m);
            pop_new(a,:)=position_change_little(pop(a,:),dim); 
        end
   end
    fitness_new=fobi_compute(pop_new,D);   %得到新的函数值
    [~,best2]=min(fitness_new);  %找到更新后的值
    pop_best2=pop(best2,:);    %找到最好的位置二
   % 跟随者位置更新
    for i=PDn+1:popn
           a=sortindex(i);
       if i>0.5*popn
           pop_new(a,:)=randperm(n);   %十分饥饿,自寻食物
       else
             change1=position_minus_position(pop_best2,pop_new(a,:));  %记录最好位置到当前位置变换 
             change1=constant_times_velocity(rand,change1);
             pop_new(a,:)=position_plus_velocity(pop_new(a,:),change1);        
       end
    end
    
    fitness_new=fobi_compute(pop_new,D);    %得到新的函数值
    eta=10e-8;
    index=randperm(popn,SDn);  %随机分配预警者 
     
    for i=1:SDn  
        a=index(i);
        if   fitness(a)>fmin
             change1=position_minus_position(pop_best,pop_new(a,:));  %记录最好位置到当前位置变换 
             change1=constant_times_velocity(rand,change1);
             pop_new(a,:)=position_plus_velocity(pop_new(a,:),change1);        %向着中心位置靠拢
        else
             dim=1;
             pop_new(a,:)=position_change_little(pop(a,:),dim);  %中心位置内,小变动
        end   
    end
     fitness_new=fobi_compute(pop_new,D);      %当前函数最佳值
     index=find(fitness_new<fitness);  %两者相互比较,找到最小的
     fitness(index,:)=fitness_new(index);
     pop(index,:)=pop_new(index,:);
     [fmin,best]=min(fitness);    %找到最佳的位置
     Convergence_curve(gen)=fmin;
     result=pop(best,:);
     gen=gen+1;
end

Shortest_Route=result;  Shortest_Length=min(Convergence_curve);
figure(1)
plot([citys(Shortest_Route,1);citys(Shortest_Route(1),1)],...
     [citys(Shortest_Route,2);citys(Shortest_Route(1),2)],'o-');
grid on
for i = 1:size(citys,1)
    text(citys(i,1),citys(i,2),['   ' num2str(i)]);
end
text(citys(Shortest_Route(1),1),citys(Shortest_Route(1),2),'       起点');
text(citys(Shortest_Route(end),1),citys(Shortest_Route(end),2),'       终点');
xlabel('城市位置横坐标')
ylabel('城市位置纵坐标')
title(['粒子群算法优化路径(最短距离:' num2str(Shortest_Length) ')'])
figure(2)
plot(Convergence_curve);
disp(['最短距离:' num2str(Shortest_Length)]);
disp(['最短路径:' num2str([Shortest_Route Shortest_Route(1)])]);

function change=position_minus_position(best,pop)
  %记录将pop变成best的交换序列
for i=1:size(best,1)
    for j=1:size(best,2)
        change(i,j)=find(pop(i,:)==best(i,j));
        temp=pop(i,j);
        pop(i,j)=pop(i,change(i,j));
        pop(i,change(i,j))=temp;
    end
end
end

function  change_little=position_change_little(pop,dim)
  %对位置进行晓得变动
  n=size(pop,2);
  for i=1:dim
      a=randperm(n,1);
      b=randperm(n,1);
      tempt=pop(:,a);
      pop(:,a)=pop(:,b);
      pop(:,b)=tempt;  
  end
     change_little=pop;
end

function  fobj=fobi_compute(pop,D)
    m=size(pop,1);  n=size(D);
    fitness=zeros(m,1);     
    for i=1:m
        for j=1:n-1
            fitness(i)=fitness(i) + D(pop(i,j),pop(i,j+1));
        end
            fitness(i)=fitness(i) + D(pop(i,end),pop(i,1));
    end
    fobj=fitness;
end

function change = constant_times_velocity(constant,change)
% 以一定概率保留交换序列
for i=1:size(change,1)
    for j=1:size(change,2)
        if rand>constant
            change(i,j)=0;
        end
    end
end
end

function pop = position_plus_velocity(pop,v)
%利用速度记录的交换序列进行位置修正
for i=1:size(pop,1)
    for j=1:size(pop,2)
        if v(i,j)~=0
            temp=pop(i,j);
            pop(i,j)=pop(i,v(i,j));
            pop(i,v(i,j))=temp;
        end
    end
end
end

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值