假设有一个收集轨道,上面有5个采集堆,这5个采集堆分别被看作一个4*20的矩阵(下面只有4*10),每个模块(比如:A31和A32的元素含量不同),为了达到采集物品数量和元素含量的要求(比如:需采集5吨和某元素单位质量在65与62之间),求出在每个4*20的矩阵中哪个模块被拿出可以达到要求并找出最优化的轨道?(在拿出模块的时候要考虑只有先拿出上面的,才可以采集下面的)
已知数据:
1.每个采集堆的元素含量(在excel表格的 sheet 1)
2.每个采集堆里面模块的坐标,长宽高(米为单位)(在excel表格的 sheet 1)
3.元素含量和采集物品数量的要求 (在excel 表格的 sheet 2), 分别有五种不同含量的最大值和最小值, 还有采集数量的要求,以及误差。
4.在轨道左侧的两个采集堆分别是C型号和A型号的,两个采集堆只见距离30m; 轨道右侧的三个采集堆按照顺序分别是B型号,B型号和C型号,同样每个采集堆之间相距20m。5.采集堆形状附在附录1
%根据这个假设,我们设计的思路为当每次运动到一堆的时候,首先在这一堆物品上进行采集,由于
%每堆物品之间的间距远大于每堆内部的各个模块之间的间隔,所以在实际中也不可能在两个不同的
%堆之间来回切换的抓取模块,这也符合我们上面的假设。
%根据上面的假设,我们抓取的顺序为B堆,C堆,A堆,A堆,B堆。
%这里,我们所使用的算法是局部PSO优化,然后再整体PSO优化的算法,即首先通过再每一堆的采集
%的时候进行PSO优化,并使的各个元素含量满足约束的条件下,得到路径最短的采集轨迹,然后通过
%后面三堆重复相同的优化算法,最后第五堆的时候,在做相同的优化前提下,同时检测总量是否满足
%条件,如果不满足进入下一次大迭代循环,然后重复上面的操作,最后得到满足条件的总的采集轨迹。
clc;
clear;
close all;
warning off;
pack;
addpath 'func\'
%**********************************************************************************
%步骤一:调用数据
%步骤一:调用数据
Dat = xlsread('Dat\datas.xlsx');
%分成ABC三组
A_set = Dat( 1:40 ,:);
B_set = Dat(41:80 ,:);
C_set = Dat(81:120,:);
%A相关数据
%坐标
A_POS = A_set(:,1:3);
%元素含量
A_FAC = A_set(:,4:8);
%体积长宽高
A_VUM = A_set(:,9:11);
%B相关数据
%坐标
B_POS = B_set(:,1:3);
%元素含量
B_FAC = B_set(:,4:8);
%体积长宽高
B_VUM = B_set(:,9:11);
%C相关数据
%坐标
C_POS = C_set(:,1:3);
%元素含量
C_FAC = C_set(:,4:8);
%体积长宽高
C_VUM = C_set(:,9:11);
%**************************************************************************
%**************************************************************************
%**********************************************************************************
%步骤二:参数初始化
%步骤二:参数初始化
%约束参数
%59999 ~ 60001
Mass_all = 60000;
Mass_err = 1;
%元素1
Mass1_max= 65;
Mass1_min= 62;
%元素2
Mass2_max= 6;
Mass2_min= 0;
%元素3
Mass3_max= 4;
Mass3_min= 0;
%元素4
Mass4_max= 0.077;
Mass4_min= 0;
%元素5
Mass5_max= 0.1;
Mass5_min= 0;
%优化算法参数
%优化算法参数
%迭代次数
Iteration_all = 1;
Iteration_sub = 10000;
%粒子数目
Num_x = 200;
%密度
P = 2.1;
%计算各个模块的质量,单位t
%注意,本课题一个堆中有个四个形状的模块,即三角形,三种梯形,所以我们根据长宽高以及对应的形状计算体积,从而计算质量
A_Vulome = func_cal_volume(A_VUM);
B_Vulome = func_cal_volume(B_VUM);
C_Vulome = func_cal_volume(C_VUM);
%计算每个采集堆的各个模块的质量
A_mass = P*A_Vulome;
B_mass = P*B_Vulome;
C_mass = P*C_Vulome;
%以下根据实际轨迹上的堆的分布来设置
maxs_sets = [B_mass;C_mass;A_mass;A_mass;B_mass];
FAC_sets = [B_FAC;C_FAC;A_FAC;A_FAC;B_FAC];
%**************************************************************************
%**************************************************************************
%**********************************************************************************
%步骤三:开始优化运算
%步骤三:开始优化运算
X_pos{1} = B_POS(:,1);
Y_pos{1} = B_POS(:,2);
Z_pos{1} = B_POS(:,3);
X_pos{2} = C_POS(:,1);
Y_pos{2} = C_POS(:,2);
Z_pos{2} = C_POS(:,3);
X_pos{3} = A_POS(:,1);
Y_pos{3} = A_POS(:,2);
Z_pos{3} = A_POS(:,3);
X_pos{4} = A_POS(:,1);
Y_pos{4} = A_POS(:,2);
Z_pos{4} = A_POS(:,3);
X_pos{5} = B_POS(:,1);
Y_pos{5} = B_POS(:,2);
Z_pos{5} = B_POS(:,3);
%先通过PSO优化需求模型
for Num_pso = 4:40%这里没有必要设置太大,设置大了需求量肯定会超过60000,因此,这个值得大小根据需求量来确定,大概范围即可
Num_pso
x = zeros(Num_x,Num_pso);
i = 0;
%产生能够满足采集规则的随机粒子数据
for jj = 1:Num_x
%产生随机数的时候,必须是先采集第一层,然后才采集第二层,依次类推
%第1层
index1 = [1:10,41:50,81:90,121:130,161:170];
%第2层
index2 = [1:10,41:50,81:90,121:130,161:170]+10;
%第3层
index3 = [1:10,41:50,81:90,121:130,161:170]+20;
%第4层
index4 = [1:10,41:50,81:90,121:130,161:170]+30;
%根据采集规则产生随机数
%根据采集规则产生随机数
%根据采集规则产生随机数
index = [index1;index2;index3;index4];
i = 0;
while i < Num_pso
i = i + 1;
if i> 1
for j = 1:50;
index(IS(j),ind(1)) = 9999;
end
end
for j = 1:50;
[VS,IS(j)] = min(index(:,j));
tmps(1,j) = index(IS(j),j);
end
ind = randperm(40);
a(i) = tmps(ind(1));
if a(i) == 9999
i = i-1;
end
end
x(jj,:) = a;
end
n = Num_pso;
F = fitness_mass(x,maxs_sets,Mass_all);
Fitness_tmps1 = F(1);
Fitness_tmps2 = 1;
for i=1:Num_x
if Fitness_tmps1 >= F(i)
Fitness_tmps1 = F(i);
Fitness_tmps2 = i;
end
end
xuhao = Fitness_tmps2;
Tour_pbest = x; %当前个体最优
Tour_gbest = x(xuhao,:) ; %当前全局最优路径
Pb = inf*ones(1,Num_x); %个体最优记录
Gb = F(Fitness_tmps2); %群体最优记录
xnew1 = x;
N = 1;
while N <= Iteration_sub
%计算适应度
F = fitness_mass(x,maxs_sets,Mass_all);
for i=1:Num_x
if F(i)<Pb(i)
%将当前值赋给新的最佳值
Pb(i)=F(i);
Tour_pbest(i,:)=x(i,:);
end
if F(i)<Gb
Gb=F(i);
Tour_gbest=x(i,:);
end
end
Fitness_tmps1 = Pb(1);
Fitness_tmps2 = 1;
for i=1:Num_x
if Fitness_tmps1>=Pb(i)
Fitness_tmps1=Pb(i);
Fitness_tmps2=i;
end
end
nummin = Fitness_tmps2;
%当前群体最优需求量差
Gb(N) = Pb(nummin);
for i=1:Num_x
%与个体最优进行交叉
c1 = round(rand*(n-2))+1;
c2 = round(rand*(n-2))+1;
while c1==c2
c1 = round(rand*(n-2))+1;
c2 = round(rand*(n-2))+1;
end
chb1 = min(c1,c2);
chb2 = max(c1,c2);
cros = Tour_pbest(i,chb1:chb2);
%交叉区域元素个数
ncros= size(cros,2);
%删除与交叉区域相同元素
for j=1:ncros
for k=1:n
if xnew1(i,k)==cros(j)
xnew1(i,k)=0;
for t=1:n-k
temp=xnew1(i,k+t-1);
xnew1(i,k+t-1)=xnew1(i,k+t);
xnew1(i,k+t)=temp;
end
end
end
end
xnew = xnew1;
%插入交叉区域
for j=1:ncros
xnew1(i,n-ncros+j) = cros(j);
end
%判断产生需求量差是否变小
masses=0;
masses = sum(maxs_sets(xnew1(i,:)));
if F(i)>masses
x(i,:) = xnew1(i,:);
end
%与全体最优进行交叉
c1 = round(rand*(n-2))+1;
c2 = round(rand*(n-2))+1;
while c1==c2
c1=round(rand*(n-2))+1;
c2=round(rand*(n-2))+1;
end
chb1 = min(c1,c2);
chb2 = max(c1,c2);
%交叉区域矩阵
cros = Tour_gbest(chb1:chb2);
%交叉区域元素个数
ncros= size(cros,2);
%删除与交叉区域相同元素
for j=1:ncros
for k=1:n
if xnew1(i,k)==cros(j)
xnew1(i,k)=0;
for t=1:n-k
temp=xnew1(i,k+t-1);
xnew1(i,k+t-1)=xnew1(i,k+t);
xnew1(i,k+t)=temp;
end
end
end
end
xnew = xnew1;
%插入交叉区域
for j=1:ncros
xnew1(i,n-ncros+j) = cros(j);
end
%判断产生需求量差是否变小
masses=0;
masses = sum(maxs_sets(xnew1(i,:)));
if F(i)>masses
x(i,:)=xnew1(i,:);
end
%进行变异操作
c1 = round(rand*(n-1))+1;
c2 = round(rand*(n-1))+1;
temp = xnew1(i,c1);
xnew1(i,c1) = xnew1(i,c2);
xnew1(i,c2) = temp;
%判断产生需求量差是否变小
masses=0;
masses = sum(maxs_sets(xnew1(i,:)));
if F(i)>masses
x(i,:)=xnew1(i,:);
end
end
Fitness_tmps1=F(1);
Fitness_tmps2=1;
for i=1:Num_x
if Fitness_tmps1>=F(i)
Fitness_tmps1=F(i);
Fitness_tmps2=i;
end
end
xuhao = Fitness_tmps2;
L_best(N) = min(F);
%当前全局最优需求量
Tour_gbest = x(xuhao,:);
N = N + 1;
end
%判断含量是否满足要求
for ii = 1:5
Fac_tmps(ii) = sum(FAC_sets(Tour_gbest,ii)'.*maxs_sets(Tour_gbest))/sum(maxs_sets(Tour_gbest));
end
if (Fac_tmps(1) >= Mass1_min & Fac_tmps(1) <= Mass1_max) &...
(Fac_tmps(2) >= Mass2_min & Fac_tmps(2) <= Mass2_max) &...
(Fac_tmps(3) >= Mass3_min & Fac_tmps(3) <= Mass3_max) &...
(Fac_tmps(4) >= Mass4_min & Fac_tmps(4) <= Mass4_max) &...
(Fac_tmps(5) >= Mass5_min & Fac_tmps(5) <= Mass5_max)
flag(Num_pso-3) = 1;
else
flag(Num_pso-3) = 0;
end
Mass_fig(Num_pso-3) = min(L_best);
Mass_Index{Num_pso-3}= Tour_gbest ;
end
figure;
plot(Mass_fig,'b-o');
xlabel('采集模块个数');
ylabel('需求量计算值和标准需求量的差值关系图');
save temp\result1.mat Mass_fig Mass_Index flag
最后得到的优化记过,即满足条件下的最短轨迹长度
A-06-10