1. 特点
-
禁忌准则:禁忌表和禁忌对象的设置,使算法避免迂回搜索
-
藐视准则(特赦准则):对禁忌策略的放松
-
新解为优良解的概率高:局部搜索能力强
-
优于best so far的解
-
非禁忌的最优解(可以接受劣质解,全局搜索能力强)
-
2. 基本参数
-
L :禁忌长度,指禁忌对象在不考虑特赦准则的情况下不允许被选取的最大次数
-
taboo :禁忌表,组织搜索过程中出现循环和避免陷入局部最优(数据结构:FIFO队列)
-
near_num:邻域解的个数
-
iter_max: 最大迭代次数
-
w :自适应权重系数,产生邻域解时使用
3. 基本流程
-
初始化参数,产生初始化解,置空禁忌表
-
while(终止条件)
-
由当前解产生near_num个邻域解
-
选出最优的邻域解作为候选解
-
if (藐视准则,候选解优于最优解)
-
更新最优解
-
更新新的当前解
-
更新禁忌表
-
-
else
-
if(候选解在禁忌表)
-
用当前解重新产生邻域解
-
-
else 候选解不在紧急表中
-
找到非禁忌对象的最佳解
-
更新新的当前解更新禁忌表
-
-
end
-
-
-
end
4. 改进方向
-
TS对于初始解具有较强的依赖性。
可以与遗传算法、模拟退火算法等优化算法结合,产生较好的初始解。
-
迭代搜索过程是串行的。
-
对TS本身的操作、参数选取进行改进,对算法初始化、参数设置等方面实施并行策略。
-
与遗传算法、神经网络以及基于问题信息的局部搜索相结合。
-
-
在集中性与多样性并重的情况下,多样性不足。
-
对算法进行重新随机初始化。
-
根据频率信息对一些已知对象进行惩罚。
-
5. 随机产生初始值的TS
%% 随机产生初始值的TS
clear;
close all;
clc;
x_max = 5;
x_min = -5;
y_max = 5;
y_min = -5;
w = 1; % 自适应权重系数
L = randi([5,11]); % 禁忌表长度
near_num = 5; % 邻域解(neighborhood solution)的个数
iter_max = 200; % 最大迭代次数
taboo = []; % 禁忌表
% 定义存储数组
cur_x = zeros(iter_max,1); % 当前位置数组
cur_y = zeros(iter_max,1);
cur_func = zeros(iter_max,1);
%% 1.随机产生初始解
x0 = rand * (x_max - x_min) + x_min;
y0 = rand * (y_max - y_min) + y_min;
best_x = x0; % 记录最优解位置
best_y = y0;
cur_x(1) = x0; % 记录当前解位置
cur_y(1) = y0;
cur_func(1) = func(cur_x(1),cur_y(1)); % 当前解
best = func(best_x,best_y); % 最优解
i = 1;
while i < iter_max
%% 2.由当前解产生邻域解
w = 0.998 * w;
for j =1:near_num
% 产生一个邻域解
near_x(j) = cur_x(i)+(2*rand-1)*(x_max-x_min)*w;
near_y(j) = cur_y(i)+(2*rand-1)*(y_max-y_min)*w;
% 边界处理(边界吸收)
if near_x(j) < x_min
near_x(j) = x_min;
end
if near_x(j) > x_max
near_x(j) = x_max;
end
if near_y(j) < y_min
near_y(j) = y_min;
end
if near_y(j) > y_max
near_y(j) = y_max;
end
% 计算邻域解点处的函数值
near_func(j) = func(near_x(j),near_y(j));
end
%% 3.将最优邻域解作为候选解
%temp = find(near_func == max(near_func)); %找到最优邻域解的位置
temp = 1;
for k =2:near_num
if near_func(k) < near_func(temp)
temp = k;
end
end
candidate_x(i) = near_x(temp);
candidate_y(i) = near_y(temp);
candidate_func(i) = near_func(temp);
%% 4.判断是否满足藐视准则
deta_cc = candidate_func(i) - cur_func(i); %% 候选解与当前解的评价函数差
deta_cb = candidate_func(i) - best; % 候选解与最优解的评价函数差
if deta_cc >= 0 % 候选解>=当前解,更新下一个当前解
cur_x(i+1) = candidate_x(i);
cur_y(i+1) = candidate_y(i);
cur_func(i+1) = candidate_func(i);
% 更新禁忌表
taboo = [taboo;[cur_x(i+1),cur_y(i+1)]];
if size(taboo,1) > L
taboo(1,:) = [];
end
i = i + 1;
else
if deta_cb < 0 % 候选解<最优解,更新下一个当前解、最优解
cur_x(i+1) = candidate_x(i);
cur_y(i+1) = candidate_y(i);
cur_func(i+1) = candidate_func(i);
best = candidate_func(i); % 更新最优解
best_x = candidate_x(i);
best_y = candidate_y(i);
% 更新禁忌表
taboo = [taboo;[cur_x(i+1),cur_y(i+1)]];
if size(taboo,1) > L
taboo(1,:) = [];
end
i = i + 1;
else
[M,N] = size(taboo); %判断是否在禁忌表中
r = 0;
for m = 1:M
if candidate_x(i) == taboo(m,1) && candidate_y(i) == taboo(m,2)
r = 1;
end
end
if r == 0 % 不在禁忌表中,更新下一次当前解,反之用当前解重新产生邻域
cur_x(i+1) = candidate_x(i);
cur_y(i+1) = candidate_y(i);
cur_func(i+1) = candidate_func(i);
% 更新禁忌表
taboo = [taboo;[cur_x(i+1),cur_y(i+1)]];
if size(taboo,1) > L
taboo(1,:) = [];
end
i = i + 1;
end
end
end
trace(i) = best;
end
figure
disp('最小值在点:');
best_x
best_y
disp( '最小值为:');
best
plot(trace)
hold on;
legend_str = {'随机初始解TS','BSAPSO产生初始解TS'};
xlabel('迭代次数')
ylabel('适应度值')
title('适应度进化曲线')
function results = func(x,y)
results = 5 * cos(x * y)+ x * y + y * y * y;
end
6. BSAPSO产生初始值的TS
%% BSAPSO算法产生初始值的TS
x_max = 5;
x_min = -5;
y_max = 5;
y_min = -5;
w = 1; % 自适应权重系数
L = randi([5,11]); % 禁忌表长度
near_num = 5; % 邻域解(neighborhood solution)的个数
iter_max = 200; % 最大迭代次数
taboo = []; % 禁忌表
% 定义存储数组
cur_x = zeros(iter_max,1); % 当前位置数组
cur_y = zeros(iter_max,1);
cur_func = zeros(iter_max,1);
% BSAPSO 参数
m = 30; %粒子数量
d = 2; %粒子维度
ac1 = 2.0; % 自身认知函数初始值
ac2 = 0.5;
sa_k = 0.98; %衰减因子
iwe = 3; % 惯性权重调整步数
w_max = 0.8;
w_min = 0.4;
v_max = 1;
v_min = -1;
t_star = 100;
t_end = 0.01;
%% 1.BSAPSO产生初始解
%%% 1、初始化
x = rand(m,1) * (x_max - x_min) + x_min;
y = rand(m,1) * (y_max - y_min) + y_min;
v_x = rand(m,1) * (v_max - v_min) + v_min;
v_y = rand(m,1) * (v_max - v_min) + v_min;
%%% 初始化个体最优位置,最优值
p_x = x; %每个粒子的个体最优解的位置
p_y = y;
pbest = ones(m,1);
for i =1:m
pbest(i) = func(x(i),y(i));
end
%%% 初始化全局最优位置,最优值
gbest = inf;
for i=1:m
if(pbest(i) < gbest)
g_x = p_x(i);
g_y = p_y(i);
gbest = pbest(i);
end
end
t_cur = t_star;
c1 = 1.5;
c2 = 1.5;
for i = 1:iter_max
for j = 1:m
%%% 2、计算每个粒子的个体最优值
if i * 2 < iter_max % 迭代前期采取标准的学习因子更新速度
if (func(x(j),y(j)) < pbest(j))
p_x(j) = x(j); %更新个体最优解位置
p_y(j) = y(j);
pbest(j) = func(x(j),y(j)); %更新个体最优解
end
else
deta_p = func(x(j),y(j)) - pbest(j);
if (deta_p < 0)
p_x(j) = x(j); %更新个体最优解位置
p_y(j) = y(j);
pbest(j) = func(x(j),y(j)); %更新个体最优解
else %(Metropolis算法)
p1 = exp(-1 * deta_p / t_cur);
r = 0;
for ii = 1:10
r = max(r,rand);
end
if p1 > r % 接受较差的值
p_x(j) = x(j); %更新个体最优解位置
p_y(j) = y(j);
pbest(j) = func(x(j),y(j)); %更新个体最优解
c1 = ac1 * exp(-t_cur/t_star)*rand;
%c2 = ac2 * (1+exp(-t_cur/t_star))*rand;
end
end
end
%%% 3、计算整个群体的全局最优值
if (pbest(j) < gbest)
gbest0 = gbest;
g_x = p_x(j);
g_y = p_y(j);
gbest = pbest(j);
end
%%% 4、对粒子的速度、位置进行进化
%w = w_max + (w_max - w_min) *(i-1)/(iwe-1);
w = w_max - (w_max - w_min) * i / iter_max;
v_x(j) = w*v_x(j)+c1 * rand*(p_x(j)-x(j))+c2 * rand*(g_x-x(j));
v_y(j) = w*v_y(j)+c1 * rand*(p_y(j)-y(j))+c2 * rand*(g_y-y(j));
x(j) = x(j) + v_x(j);
y(j) = y(j) + v_y(j);
%%% 5、进行边界处理
if (v_x(j) > v_max | v_x(j) < v_min)
v_x(j) = rand * (v_max - v_min) + v_min;
end
if (v_y(j) > v_max | v_y(j) < v_min)
v_y(j) = rand * (v_max - v_min) + v_min;
end
if (x(j) > x_max | x(j) < x_min)
x(j) = rand * (x_max - x_min) + x_min;
end
if (y(j) > y_max | y(j) < y_min)
y(j) = rand * (y_max - y_min) + y_min;
end
end
t_cur = sa_k * t_cur;
end
x0 = g_x;
y0 = g_y;
best_x = x0; % 记录最优解位置
best_y = y0;
cur_x(1) = x0; % 记录当前解位置
cur_y(1) = y0;
cur_func(1) = func(cur_x(1),cur_y(1)); % 当前解
best = func(best_x,best_y); % 最优解
i = 1;
while i < iter_max
%% 2.由当前解产生邻域解
w = w * 0.998;
for j =1:near_num
% 产生一个邻域解
near_x(j) = cur_x(i)+(2*rand-1)*(x_max-x_min)*w;
near_y(j) = cur_y(i)+(2*rand-1)*(y_max-y_min)*w;
% 边界处理(边界吸收)
if near_x(j) < x_min
near_x(j) = x_min;
end
if near_x(j) > x_max
near_x(j) = x_max;
end
if near_y(j) < y_min
near_y(j) = y_min;
end
if near_y(j) > y_max
near_y(j) = y_max;
end
% 计算邻域解点处的函数值
near_func(j) = func(near_x(j),near_y(j));
end
%% 3.将最优邻域解作为候选解
%temp = find(near_func == max(near_func)); %找到最优邻域解的位置
temp = 1;
for k =2:near_num
if near_func(k) < near_func(temp)
temp = k;
end
end
candidate_x(i) = near_x(temp);
candidate_y(i) = near_y(temp);
candidate_func(i) = near_func(temp);
%% 4.判断是否满足藐视准则
deta_cc = candidate_func(i) - cur_func(i); %% 候选解与当前解的评价函数差
deta_cb = candidate_func(i) - best; % 候选解与最优解的评价函数差
if deta_cc >= 0 % 候选解>=当前解,更新下一个当前解
cur_x(i+1) = candidate_x(i);
cur_y(i+1) = candidate_y(i);
cur_func(i+1) = candidate_func(i);
% 更新禁忌表
taboo = [taboo;[cur_x(i+1),cur_y(i+1)]];
if size(taboo,1) > L
taboo(1,:) = [];
end
i = i + 1;
else
if deta_cb < 0 % 候选解<最优解,更新下一个当前解、最优解
cur_x(i+1) = candidate_x(i);
cur_y(i+1) = candidate_y(i);
cur_func(i+1) = candidate_func(i);
best = candidate_func(i); % 更新最优解
best_x = candidate_x(i);
best_y = candidate_y(i);
% 更新禁忌表
taboo = [taboo;[cur_x(i+1),cur_y(i+1)]];
if size(taboo,1) > L
taboo(1,:) = [];
end
i = i + 1;
else
[M,N] = size(taboo); %判断是否在禁忌表中
r = 0;
for m = 1:M
if candidate_x(i) == taboo(m,1) && candidate_y(i) == taboo(m,2)
r = 1;
end
end
if r == 0 % 不在禁忌表中,更新下一次当前解,反之用当前解重新产生邻域
cur_x(i+1) = candidate_x(i);
cur_y(i+1) = candidate_y(i);
cur_func(i+1) = candidate_func(i);
% 更新禁忌表
taboo = [taboo;[cur_x(i+1),cur_y(i+1)]];
if size(taboo,1) > L
taboo(1,:) = [];
end
i = i + 1;
end
end
end
trace(i) = best;
end
disp('最小值在点:');
best_x
best_y
disp( '最小值为:');
best
plot(trace)
legend(legend_str)
xlabel('迭代次数')
ylabel('适应度值')
title('适应度进化曲线')
function results = func(x,y)
results = 5 * cos(x * y)+ x * y + y * y * y;
end