路径规划中使用遗传算法
种群初始化过程:产生不同的编码路径(如上图所示路径编码:(0,6,7,13,19,24))来模拟种群
(1)每行选择一个栅格
(2)判断相邻栅格是否连续
通过判断栅格之间x与y坐标最大值为1即为连续,表示两栅格是相邻或是对角。
x坐标总数取整加一,y坐标总数取余加一,加1是因为matlab下标都是从1开始的。
(3)不连续时反复进行插入新栅格操作,直到连续,如果取到有障碍的栅格,从他的四周寻找栅格。
如图中若取6: (2, 2);13: (4, 3),套用上述公式向下取整得到(3, 2)点。
选择策略
路径表示:
适应度1表示路径的长度,越大越好,取路径的倒数
适应度2表示路径的顺滑性,以相邻的三个点会组成一个三角形,这个角可以通过余弦定理来计算,角度越大适应度越高
总体的适应度,需要对两个适应度取权重,权重可通过实验来获得。
通过得到的适应度可以计算出可以保留的概率,通过轮盘赌法,适应度越高,概率越高的优质个体选中的可能性就越高。
pi=fiti/i=1endfiti
交叉策略
以下图为例,交换交叉点前后的路径形成新的路径,从而达到更丰富的个体
变异策略
(1)随机选择路径中的两个栅格
(2)采用种群初始化中的方法在两个栅格间产生更好的新路径
案例实操
对起点[0,0],终点 [20, 20]在边长范围为[0,20]的正方形进行路径规划,其中设置了一些墙体作为障碍物。
【主函数实验代码】
% 基于遗传算法的栅格法路径规划
clc;
clear;
% 输入数据,即栅格地图,注意实际地图和数据列是反着画的
G= [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
0 0 1 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0;
0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0;
0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0;
0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
0 1 1 1 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0;
0 0 0 0 0 0 1 1 1 0 1 0 1 1 0 0 0 0 0 0;
0 1 1 1 0 0 0 0 0 0 1 0 1 1 0 0 0 0 0 0;
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
0 0 0 0 0 0 0 1 1 0 1 1 1 1 0 0 0 0 0 0;
0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0;
0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 1 1 1 1 0;
0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0;
0 0 1 1 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 0;
0 0 1 1 0 0 1 1 1 0 1 0 0 0 0 0 0 0 0 0;
0 0 0 0 0 0 1 1 1 0 1 0 0 0 0 0 0 1 1 0;
0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 1 0;
0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0;
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0];
%G = [0 0 0 1 0;
% 0 0 0 0 0;
% 0 0 1 0 0;
% 1 0 1 0 0;
% 0 0 0 0 0;];
p_start = 0; % 起始序号,起点
p_end = 399; % 终止序号,终点
NP = 200; % 种群数量
max_gen = 50; % 最大进化代数,选择交叉变异最多执行50次
pc = 0.8; % 交叉概率
pm = 0.2; % 变异概率
%init_path = [];
z = 1;
new_pop1 = {}; % 元包类型,用于保存路径,类似(0, 6, 7, 13, 19, 24)的编码
[y, x] = size(G);% 求地图尺寸,x,y占了多少格
% mod取模操作,起点所在列(从左到右编号1.2.3...)
xs = mod(p_start, x) + 1;
% fix向下取整,起点所在行(从上到下编号行1.2.3...)
ys = fix(p_start / x) + 1;
% 终点所在列、行
xe = mod(p_end, x) + 1;
ye = fix(p_end / x) + 1;
% 种群初始化step1,必经节点,从起始点所在行开始往上,在每行中挑选一个自由栅格,构成必经节点
pass_num = ye - ys + 1;
pop = zeros(NP, pass_num);
for i = 1 : NP
pop(i, 1) = p_start;% 把起点到第一个个体里面
j = 1;
% 除去起点和终点
for yk = ys+1 : ye-1
j = j + 1;
% 每一行的可行点放到can
can = [];
for xk = 1 : x
% 栅格序号
no = (xk - 1) + (yk - 1) * x;
if G(yk, xk) == 0
% 把点加入can矩阵中
can = [can no];
end
end
can_num = length(can);
% 产生随机整数
index = randi(can_num);
% 为每一行加一个可行点
pop(i, j) = can(index);
end
pop(i, end) = p_end;
%pop
% 路径连续化,种群初始化step2将上述必经节点联结成无间断路径
single_new_pop = generate_continuous_path(pop(i, :), G, x);
%init_path = [init_path, single_new_pop];
if ~isempty(single_new_pop)
new_pop1(z, 1) = {single_new_pop};
z = z + 1;
end
end
%保留数据画图用mean_path_value 为平均路径长度与min_path_value 最优路径长度
mean_path_value = zeros(1, max_gen);
min_path_value = zeros(1, max_gen);
% 循环迭代操作
for i = 1 : max_gen
% 计算适应度值
% 计算路径长度
path_value = cal_path_value(new_pop1, x)
% 计算路径平滑度
path_smooth = cal_path_smooth(new_pop1, x)
fit_value = 1 .* path_value .^ -1 + 1 .* path_smooth .^ -1;%应度值是对求得的两个适应度去倒数,目前两个权重都取得1,可进行修改
mean_path_value(1, i) = mean(path_value);%画图,找平均与最
[~, m] = max(fit_value);
min_path_value(1, i) = path_value(1, m);
% 选择操作
new_pop2 = selection(new_pop1, fit_value);
% 交叉操作
new_pop2 = crossover(new_pop2, pc);
% 变异操作
new_pop2 = mutation(new_pop2, pm, G, x);
% 更新种群
new_pop1 = new_pop2;
end
% 画每次迭代平均路径长度和最优路径长度图
figure(1)
plot(1:max_gen, mean_path_value, 'r')
hold on;
plot(1:max_gen, min_path_value, 'b')
legend('平均路径长度', '最优路径长度');
min_path_value(1, end)
% 在地图上画路径
[~, min_index] = max(fit_value);
min_path = new_pop1{min_index, 1};
figure(2)
hold on;
title('遗传算法无人机运动轨迹');
xlabel('坐标x');
ylabel('坐标y');
DrawMap(G);
[~, min_path_num] = size(min_path);
for i = 1:min_path_num
% 路径点所在列(从左到右编号1.2.3...)
x_min_path(1, i) = mod(min_path(1, i), x) + 1;
% 路径点所在行(从上到下编号行1.2.3...)
y_min_path(1, i) = fix(min_path(1, i) / x) + 1;
end
hold on;
plot(x_min_path, y_min_path, 'r')
【运行结果】
【注】算法基础性内容详见