一片水域,如果某个地方的鱼类数目最多,那么这个地方一般来说就是水域内富含营养物质最多的地方,依据这一特点来模仿鱼群的觅食、聚群、追尾、随机行为,以实现全局寻优的目的。
人工鱼在其视野内随机选择一个状态,分别计算它们的目标函数值进行比较,如果发现比当前值优,则向优化的方向移动一步;否则,继续在其视野内随机选择状态,判断是否满足前进条件;这样反复尝试n次(为设定值)后,如果仍不满足前进条件,则随机移动一步。
大量或少量的鱼都能聚集成群,这是它们在进化过程中形成的一种生存方式,可以进行集体觅食和躲避敌害。
抽象成规则:
分割规则,尽量避免与邻近伙伴过于拥挤;
对准规则,尽量与邻接伙伴的平均方向一致;
内聚规则,尽量朝邻近伙伴的重心移动。
人工鱼搜索其视野内的伙伴数目及中心位置,若单位食物密度比现在大,表明伙伴中心有较多的食物(位置状态较优)且不太拥挤,则朝伙伴的中心位置移动一步,否则执行觅食行为。
鱼向其可视区域内的最优方向移动的一种行为。
人工鱼搜索其视野内所有伙伴中的函数最优伙伴。如果,表明最优伙伴X j X_jX j 具有较高的食物浓度并且其周围不太拥挤,则朝伙伴的方向前进;否则执行觅食行为。
随机行为指人工鱼在视野内随机移动,当发现食物时,会向食物逐渐增多的方向快速移动。随机行为的实现较为简单,就是向视野中随机选择一个状态的方向移动,加一个随机因子,懂得都懂。
假设X是一条鱼所处的位置,这个圆为这条鱼的视野范围,xn1.xn2为另外两条鱼,Xv为这条鱼再某时刻看到的位置,然后就判断Xv点的食物浓度是否比原位置高,如果高就往这个方向去。
离散值 连续值
求以上这个函数,其中 s.t. x ∈ [ − 10 , 10 ] x∈[-10,10]x∈[−10,10] y ∈ [ − 10 , 10 ] y∈[-10,10]y∈[−10,10]
X=-10:0.1:10;
Y=-10:0.1:10;X=-10:0.1:10;
Y=-10:0.1:10;
[XX,YY]=meshgrid(X,Y);
Z=sin(XX).*sin(YY)./(XX.*YY);
figure
subplot(1,2,1)
mesh(XX,YY,Z);title('Meshplot');
subplot(1,2,2)
contour(XX,YY,Z);title('Meshplot');
[XX,YY]=meshgrid(X,Y);
Z=sin(XX).*sin(YY)./(XX.*YY);
figure
subplot(1,2,1)
mesh(XX,YY,Z);title('Meshplot');
subplot(1,2,2)
contour(XX,YY,Z);title('Meshplot');
#include
#include
#include
#include
using namespace std;
double Xmax = 10, Xmin = -10;//变量的可行域
std::default_random_engine random((unsigned int)time(NULL));
std::uniform_real_distribution u(Xmin, Xmax); //随机数分布对象
std::uniform_real_distribution r(-1, 1); //随机数分布对象
struct AF
{
public:
int dimension;//个体变量维数
double *X;
void Init(int Dim)//初始化函数
{
dimension = Dim;
X = new double[dimension];
for (int j = 0; j < dimension; j++)
*(X+j) = u(random);
}
double fitfunctionvalue()//个体适应值计算函数
{
double f = sin(*X)*sin(*(X + 1)) / ((*X) * (*(X + 1)));
return f;
}
};
struct YUQUN
{
public:
int N;//种群规模
int Dimension;//维数
double step = 0;
double visual = 0;
double try_number = 0;
double delta = 0;
AF *af;
AF Bestfish;
void Init(int num, int Dim, double Step, double Visual, double Try_number, double Delta)//初始化函数
{
N = num;
Dimension = Dim;
step = Step;
visual = Visual;
try_number = Try_number;
delta = Delta;
af = new AF[num];
for (int i = 0; i < N; i++)
(af + i)->Init(Dimension);
Bestfish.Init(Dimension);
/*double bestfitvalue = Bestfish.fitfunctionvalue();
for(int i=0;ifitfunctionvalue() > bestfitvalue)
{
for (int j = 0; j < Dimension; j++)
Bestfish.X[j] = (af + i)->X[j];
}*/
}
double Distance(AF af1, AF af2)//计算两条鱼距离的函数
{
double dist = 0;
for (int i = 0; i < Dimension; i++)
dist += pow(af1.X[i] - af2.X[i], 2.0);
dist = sqrt(dist / float(Dimension));
return dist;
}
void prey(int id)//觅食行为
{
AF AFNew;
AFNew.Init(Dimension);
for (int i = 0; i < try_number; i++)
{
for (int j = 0; j < Dimension; j++)
AFNew.X[j] = (af+id)->X[j] + r(random) * visual;
double Yi = 0, Yj = 0;
Yi = (af + id)->fitfunctionvalue();
Yj = AFNew.fitfunctionvalue();
if (Yi < Yj)
{
for (int j = 0; j < Dimension; j++)
(af + id)->X[j] = (af + id)->X[j] + r(random)*step*(AFNew.X[j] - (af + id)->X[j]) / Distance(AFNew, *(af+id));
}
else
{
for (int j = 0; j < Dimension; j++)
(af + id)->X[j] = (af + id)->X[j] + r(random)*step;
}
}
}
void swarm(int id)//聚群行为
{
AF AFXc;
AFXc.Init(Dimension);
for (int j = 0; j < Dimension; j++) AFXc.X[j] = 0;
double nf = 0;
for (int i = 0; i < N; i++)
if ((Distance(*(af + id), *(af + i)) < visual) && (Distance(*(af+id), *(af + i)) != 0))
{
nf++;
for (int j = 0; j < Dimension; j++)
AFXc.X[j] += (af + i)->X[j];
}
for (int j = 0; j < Dimension; j++)
AFXc.X[j] = AFXc.X[j] / nf;//计算邻域伙伴的中心位置
double Yc= AFXc.fitfunctionvalue(), Yi=(af+id)->fitfunctionvalue();
if (Yc / nf > delta*Yi)
{
for (int j = 0; j < Dimension; j++)
(af + id)->X[j] = (af + id)->X[j] + r(random)*step*(AFXc.X[j] - (af + id)->X[j]) / Distance(AFXc, *(af + id));
}
else
prey(id);
}
void follow(int id)//追尾行为
{
double Ymax = -INFINITY;
AF AFXmax;
AFXmax.Init(Dimension);
for (int j = 0; j < Dimension; j++) AFXmax.X[j] = 0;
for (int i = 0; i < N; i++)
{
double dij = Distance(*(af+id), *(af+i)), Yj = (af+i)->fitfunctionvalue();
if (dij != 0 && dijYmax)
{
Ymax = Yj;
for (int j = 0; j < Dimension; j++)
AFXmax.X[j] = (af+i)->X[j];
}
}
double nf = 0;
for (int i = 0; i < N; i++)
{
double dmaxj = Distance(AFXmax,*(af+i));
if (dmaxj != 0 && dmaxj < visual)
nf++;
}
double Yi = (af + id)->fitfunctionvalue();
if (Ymax / nf > delta *Yi)
{
for (int j = 0; j < Dimension; j++)
(af+id)->X[j] = (af + id)->X[j] + r(random)*step*(AFXmax.X[j] - (af+id)->X[j]) / Distance(AFXmax, *(af+id));
}
else
prey(id);
}
void evaluate(int id)
{
if ((af + id)->fitfunctionvalue() > Bestfish.fitfunctionvalue())
{
for (int j = 0; j < Dimension; j++)
Bestfish.X[j] = (af + id)->X[j];
}
}
void run(int itetime)//运行函数
{
for (int k = 0; k < itetime; k++)
{
for (int i = 0; i < N; i++)
{
prey(i);
swarm(i);
follow(i);
evaluate(i);
}
std::cout << "第" << k + 1 << "次迭代最优位置为Bestfish:";
for (int j = 0; jX[j] << " ";
std::cout << endl;
}
}
void doAFAS(int num, int Dim, double Step, double Visual, double Try_number, double Delta,int Itetime)
{
Init(num, Dim, Step, Visual, Try_number, Delta);
shuchu();
run(Itetime);
}
};
int main()
{
YUQUN yq;
while (true)
{
int num=0;
std::cout << "请输入迭代的次数:";
cin >> num;
if (num == 0)break;
else yq.doAFAS(10, 2, 0.3, 2.5, 5, 0.618, num);
}
system("pause");
return 0;
}
AF算法MATLAB实现
%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,:))ub;
lb_flag=x_swarmub;
lb_flag2=x_prey_randf(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_swarmub;
lb_flag2=x_swarmub;
lb_flag2=x_followub;
lb_flag2=x_prey_randf(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_followub;
lb_flag2=x_follow