重點(diǎn):
- 如何建立模型:問題—》數(shù)學(xué)模型—》代碼實(shí)現(xiàn)许饿。
- 優(yōu)化算法如何處理解空間內(nèi)的無效區(qū)域阳欲。
- 問題模型每一維不是一個(gè)數(shù)值,優(yōu)化算法如何處理米辐。
一. 問題描述
如題胸完,只給出了路徑規(guī)劃的目的,其余條件全靠腦補(bǔ)翘贮。
- 既然有路徑赊窥,那么必然存在起點(diǎn)和終點(diǎn)。
- 既然需要規(guī)劃路徑狸页,那么肯定不是所有位置都能經(jīng)過锨能,或者經(jīng)過速度(代價(jià))不一樣,那么一定會有障礙物芍耘。
- 既然路徑能夠規(guī)劃址遇,那么,地圖一定是明確的斋竞,不會出現(xiàn)有未知的區(qū)域倔约。
那么現(xiàn)在可以總體描述一下問題:在一個(gè)已知的區(qū)域內(nèi),選擇一條最合適的路徑坝初,連通起點(diǎn)到終點(diǎn)浸剩,使付出的代價(jià)最小。
二. 模型建立
根據(jù)問題描述可以確定模型中的幾個(gè)要素:
1. 起點(diǎn)鳄袍,終點(diǎn)
起點(diǎn)和終點(diǎn)為地圖中的兩個(gè)頂點(diǎn)绢要;在地圖中使用綠色區(qū)域表示。
2. 障礙物位置拗小,范圍
障礙物將分為兩種:
a. 可以通過的區(qū)域重罪,圓形,但是通過會有一定代價(jià),距離障礙物中心越近剿配,代價(jià)越大搅幅;在地圖中使用紅色區(qū)域表示。
b. 不可通過的區(qū)域呼胚,矩形盏筐,該區(qū)域任何位置都不允許通過;在地圖中使用灰色區(qū)域表示砸讳。
3. 地圖范圍
為了簡化模型,地圖范圍為一個(gè)矩形區(qū)域界牡,路徑上的所有點(diǎn)必須在該區(qū)域內(nèi)簿寂。
4. 路徑
連接起點(diǎn)至終點(diǎn)的曲線;在地圖中使用藍(lán)色曲線表示宿亡。
模型地圖如下圖所示:
為了能使用優(yōu)化算法對路徑進(jìn)行優(yōu)化常遂,該模型的輸入應(yīng)是路徑,輸出應(yīng)該是一個(gè)數(shù)值挽荠,該數(shù)值將表示輸入的路徑的優(yōu)劣克胳。
為了簡化問題,將路徑上的關(guān)鍵點(diǎn)作為模型的輸入圈匆,關(guān)鍵點(diǎn)之間的路徑為該兩個(gè)關(guān)鍵點(diǎn)的連線,路徑如圖2所示漠另。
一般來說,路徑是越短越好跃赚,故我們求的是該模型的最小值笆搓。
路徑評價(jià)函數(shù) = 路徑長度+通過障礙的代價(jià)。
由于矩形障礙是無法通過的纬傲,在通過矩形障礙時(shí)直接給與一個(gè)無窮大的代價(jià)即可满败,所以我們只需要確定如何計(jì)算進(jìn)過圓形障礙的代價(jià)。
如圖叹括,圓形障礙的半徑為R,關(guān)鍵點(diǎn)A距圓心O的距離AO=r<R,那么路徑通過點(diǎn)A所需的代價(jià)可以使用如下公式計(jì)算:
其中a為該障礙物的代價(jià)系數(shù)算墨,a>0,a的值越大汁雷,其經(jīng)過該障礙的代價(jià)越大净嘀。
f表示該模型的適應(yīng)度函數(shù),d為路徑的長度摔竿,p為路徑通過障礙的代價(jià)面粮。
其中路徑的長度d比較好計(jì)算,順序計(jì)算兩個(gè)點(diǎn)之間的距離再累加即可继低。那么如何計(jì)算路徑通過障礙的代價(jià)呢熬苍?
線段是由無數(shù)個(gè)點(diǎn)組成的,所有無法計(jì)算每個(gè)點(diǎn)的代價(jià)在累加。這時(shí)需要對路徑進(jìn)行采樣柴底,得到數(shù)個(gè)采樣點(diǎn)取計(jì)算其代價(jià)婿脸。
如果不使用采樣點(diǎn)則可能出現(xiàn)路徑穿過障礙物卻沒有代價(jià)。
如圖4柄驻,A和B為關(guān)鍵點(diǎn)狐树,如果只計(jì)算關(guān)鍵點(diǎn),則AB連線即為路徑鸿脓,但實(shí)際上AB穿過了不可以通過的障礙物抑钟,該路徑無效。
對線段采樣的方式很多野哭,這里我選擇使用指定步長來對線段進(jìn)行采樣在塔。如,若AB長為11拨黔,步長為2蛔溃,則將AB等分為6段(11/2后向上取整),其中共有6個(gè)采樣點(diǎn)篱蝇,我們計(jì)算這6個(gè)采樣點(diǎn)和AB兩個(gè)關(guān)鍵點(diǎn)的代價(jià)即可贺待。
步長越小,結(jié)果越接近真實(shí)零截,但是計(jì)算的復(fù)雜程度越高麸塞;步長越大,計(jì)算起來越快瞻润,但是會有一定程度失真喘垂。
如上圖5,由于步長較大绍撞,線段中有3個(gè)采樣點(diǎn)正勒,路徑依然穿越了障礙區(qū)域酗洒,卻沒有計(jì)算代價(jià)扶关,實(shí)際上,由于路徑AB穿過了不可通過的障礙區(qū)域闺魏,其代價(jià)應(yīng)為無窮大非洲。
對于一個(gè)擁有k個(gè)圓形障礙的地圖鸭限,若路徑不穿過方形區(qū)域,由m個(gè)關(guān)鍵點(diǎn)組成两踏,有n個(gè)采樣點(diǎn)败京,其最終代價(jià)計(jì)算如下:
其中d為路徑的長度,p由公式(2)計(jì)算得出梦染,r為采樣點(diǎn)距圓心的距離赡麦。
同時(shí)朴皆,由于計(jì)算路徑時(shí)需要先知道其關(guān)鍵點(diǎn)數(shù)量。故計(jì)算之前需要先確定m的值泛粹。但由于m的值越大遂铡,路徑的計(jì)算越復(fù)雜也越慢,而我們無法得知m的最小值晶姊。故在計(jì)算完后我們需要計(jì)算路徑中是否有多余的關(guān)鍵點(diǎn)扒接。這個(gè)步驟其實(shí)可以省略,但是有多余的點(diǎn)時(shí)計(jì)算量會比較大们衙,算法需要更長時(shí)間才能得出結(jié)果钾怔。
如上圖6,在得出路徑A-K1-K2-K3-K4-B后蒙挑,我們可以依次去掉各關(guān)鍵點(diǎn)蒂教,計(jì)算其代價(jià):即A-K2-K3-K4-B,A-K1-K3-K4-B脆荷,A-K1-K2-K4-B,A-K1-K2-K3-B這四條路徑的代價(jià)懊悯,如果其中有一條路徑的代價(jià)小于原路徑蜓谋,則可以將m-1后重新進(jìn)行計(jì)算。
三. 模型代碼實(shí)現(xiàn)
根據(jù)上面的模型炭分,我們可以將模型代碼劃分為三塊:地圖以及兩只障礙物桃焕。
路徑是模型的輸入,代價(jià)是模型的輸出捧毛。
由于下面需要使用優(yōu)化算法來對模型進(jìn)行優(yōu)化观堂,之前優(yōu)化算法matlab實(shí)現(xiàn)中,適應(yīng)度函數(shù)的輸入時(shí)一個(gè)向量呀忧,而這里模型的輸入時(shí)一個(gè)關(guān)鍵點(diǎn)序列师痕,故需要將關(guān)鍵點(diǎn)序列與向量相互轉(zhuǎn)化:
如上公式(4),左邊為m個(gè)二維點(diǎn)的坐標(biāo)而账,右邊為模型的輸入序列胰坟,在計(jì)算代價(jià)時(shí),需要將右邊的序列轉(zhuǎn)化為左邊的點(diǎn)去計(jì)算泞辐,而在優(yōu)化算法中則使用右邊的序列去進(jìn)行笔横。
代碼文件列表如下:
optimization algorithm\application_path_planning為該應(yīng)用根目錄
文件名 | 說明 |
---|---|
Obstacle_Rect.m | 矩形障礙區(qū)域。 |
Obstacle_Circle.m | 圓形障礙區(qū)域咐吼。 |
Map_Model.m | 地圖模型吹缔。 |
其實(shí)現(xiàn)如下:
optimization algorithm\application_path_planning\Obstacle_Rect.m
矩形區(qū)域:判斷是否有點(diǎn)在該區(qū)域內(nèi)
% 障礙區(qū)域:矩形,不可通過
classdef Obstacle_Rect
properties
% 數(shù)值較大的頂點(diǎn)锯茄,類似于左下頂點(diǎn)
point_low;
% 數(shù)值較大的頂點(diǎn)厢塘,類似于右上頂點(diǎn)
point_up;
end
methods
% 構(gòu)造函數(shù)
function self = Obstacle_Rect(point_low,point_up)
self.point_low = point_low;
self.point_up = point_up;
end
% 懲罰函數(shù)
function value = get_penalty(self,path_point)
% 如果>成立,I,J的對應(yīng)維度值為1俗冻,否則為0
I = self.point_up > path_point;
J = path_point > self.point_low;
% 如果I,J的所有維值均為1礁叔,則說明路點(diǎn)在該矩形內(nèi)
if sum(I.*J) == length(path_point)
% 由于該障礙無法通過,故懲罰數(shù)值為最大
value = realmax('double');
else
value = 0;
end
end
end
end
optimization algorithm\application_path_planning\Obstacle_Circle.m
圓形區(qū)域:判斷點(diǎn)與圓心的距離迄薄,計(jì)算代價(jià)
% 障礙區(qū)域:圓形琅关,可以通過,但會受到一定懲罰
classdef Obstacle_Circle
properties
% 中心點(diǎn)的坐標(biāo)讥蔽,2維或者3維的點(diǎn)(長度為2或者3的向量)
point;
% 區(qū)域半徑涣易,數(shù)值
radius;
% 系數(shù),用于計(jì)算懲罰函數(shù)冶伞,數(shù)值新症,默認(rèn)為1
coefficient = 1;
end
methods
% 構(gòu)造函數(shù)
function self = Obstacle_Circle(point,radius,coefficient)
self.point = point;
self.radius = radius;
self.coefficient = coefficient;
end
% 懲罰函數(shù)
function value = get_penalty(self,path_point)
% 計(jì)算路點(diǎn)到障礙中心的距離
dist = sqrt(sum((path_point - self.point).^2));
if dist < self.radius
% 將路點(diǎn)距中心的距離系數(shù)作為懲罰系數(shù)
% 即距離中越近,懲罰系數(shù)越大
value = self.coefficient*(1-dist/self.radius);
else
value = 0;
end
end
end
end
optimization algorithm\application_path_planning\Map_Model.m
地圖模型:
1.設(shè)定障礙區(qū)域响禽,地圖邊界
2.關(guān)鍵點(diǎn)序列與向量轉(zhuǎn)換
3.根據(jù)關(guān)鍵點(diǎn)和步長得到采樣點(diǎn)
4.根據(jù)關(guān)鍵點(diǎn)徒爹,采樣點(diǎn)計(jì)算代價(jià)
5.繪制地圖和路徑
% 原文鏈接:http://www.reibang.com/p/70252c42b37d
% 地圖模型
classdef Map_Model
properties
% 地圖維度,2芋类,表示為平面地圖
dim = 2;
% 插值步長
step_size = 0.5;
% 地圖上界
bound_up = [100,100];
% 地圖下界
bound_low = [0,0];
% 起點(diǎn)x=5,y=90
point_start = [5,90];
% 終點(diǎn)x=90,y=5
point_end = [90,5];
% 不可通過的障礙列表
obstacle_rect_list=[Obstacle_Rect([5,20],[20,30]),Obstacle_Rect([30,45],[50,60])];
% 懲罰性質(zhì)的障礙列表
% 中心為(55,70)隆嗅,半徑為8,懲罰系數(shù)為5
% 中心為(65,40)侯繁,半徑為10胖喳,懲罰系數(shù)為5
obstacle_circle_list=[Obstacle_Circle([55,70],8,5),Obstacle_Circle([65,45],10,5),Obstacle_Circle([20,55],7,5),Obstacle_Circle([40,30],8,5)];;
end
methods
% 構(gòu)造函數(shù)
function self = Map_Model()
end
% 輸入為向量,輸出為適應(yīng)度值
function value = fit_function(self,x)
% 將向量x,轉(zhuǎn)化為數(shù)個(gè)關(guān)鍵點(diǎn)坐標(biāo)
key_point_list = self.get_point_from_vector(x);
value = self.get_path_value(key_point_list);
end
% 從輸入的向量中獲取點(diǎn)的坐標(biāo)
function key_point_list = get_point_from_vector(self,x)
% 加入起點(diǎn)
key_point_list = [self.point_start];
for i = 1:(length(x)/self.dim)
% x中相鄰數(shù)個(gè)值組成一個(gè)點(diǎn)
path_point = x((i-1)*self.dim+1:i*self.dim);
% 將該點(diǎn)加入列表
key_point_list = [key_point_list;path_point];
end
% 加入終點(diǎn)
key_point_list = [key_point_list;self.point_end];
end
% 輸入路徑關(guān)鍵點(diǎn)贮竟,計(jì)算其評價(jià)值
function value = get_path_value(self,key_point_list)
value = 0;
for i = 2:length(key_point_list)
cur_point = key_point_list(i,:);
last_point = key_point_list(i-1,:);
% 計(jì)算兩點(diǎn)之間的距離
dist = sqrt(sum((last_point-cur_point).^2));
% 累加兩點(diǎn)之間的距離丽焊,作為適應(yīng)度函數(shù)的一部分
value = value + dist;
end
% 獲取采樣點(diǎn)
sampling_point_list = self.get_sampling_point_list(key_point_list);
% 遍歷每個(gè)點(diǎn)采樣點(diǎn),計(jì)算懲罰系數(shù)
for i = 1:size(sampling_point_list,1)
% 計(jì)算長方形區(qū)域的懲罰
for j = 1:length(self.obstacle_rect_list)
value = value + self.obstacle_rect_list(j).get_penalty(sampling_point_list(i,:));
end
% 計(jì)算圓形區(qū)域的懲罰
for j = 1:length(self.obstacle_circle_list)
penalty = self.obstacle_circle_list(j).get_penalty(sampling_point_list(i,:));
value = value + penalty;
end
end
end
% 計(jì)算路徑中的采樣點(diǎn)
function sampling_point_list = get_sampling_point_list(self,key_point_list)
% 加入起點(diǎn)
sampling_point_list = [key_point_list(1,:)];
for i = 2:length(key_point_list)
% 獲取當(dāng)前點(diǎn)
path_point = key_point_list(i,:);
% 計(jì)算該點(diǎn)和上一個(gè)點(diǎn)之間的中間點(diǎn)
middle_point_list = self.get_middle_point(sampling_point_list(end,:),path_point);
% 將中間點(diǎn)加入列表
sampling_point_list = [sampling_point_list;middle_point_list];
% 將該點(diǎn)加入列表
sampling_point_list = [sampling_point_list;path_point];
end
end
% 計(jì)算兩個(gè)關(guān)鍵點(diǎn)之間的插值點(diǎn)
function middle_point_list = get_middle_point(self,path_point_start,path_point_end)
% step_size 為插值步長咕别,步長越小技健,插入的中間點(diǎn)越多
% 計(jì)算兩點(diǎn)之間的距離
dist = sqrt(sum((path_point_start-path_point_end).^2));
% 計(jì)算插值點(diǎn)數(shù)
middle_num = floor(dist/self.step_size)+1;
middle_point_list = [];
if middle_num > 0
% 如果插值點(diǎn)數(shù)大于0
for i = 1:middle_num
middle_point = (i*path_point_end+(middle_num+1-i)*path_point_start)/(middle_num+1);
middle_point_list = [middle_point_list;middle_point];
end
end
end
% 判斷是否有多余的點(diǎn)
function has_surplus = get_surplus_point_num(self,x)
has_surplus = 0;
% 將向量x,轉(zhuǎn)化為數(shù)個(gè)關(guān)鍵點(diǎn)坐標(biāo)
key_point_list = self.get_point_from_vector(x);
% 計(jì)算當(dāng)前值
value = self.get_path_value(key_point_list);
for i = 2:(length(key_point_list)-1)
% 去除一個(gè)關(guān)鍵點(diǎn)計(jì)算其值
temp_point_list = [key_point_list(1:i-1,:);key_point_list(i+1:end,:)];
% 計(jì)算去除一個(gè)點(diǎn)后的適應(yīng)度值
new_value = get_path_value(self,temp_point_list);
% 如果去除一個(gè)點(diǎn)的值更好則直接返回1
if new_value < value
has_surplus = 1;
break;
end
end
end
% 繪制地圖
function draw_map(self,input,num)
% 繪制圖像
for i = 1:length(self.obstacle_circle_list)
%圓心坐標(biāo)為point,半徑為radius,輪廓顏色為紅色
x = self.obstacle_circle_list(i).point(1);
y = self.obstacle_circle_list(i).point(2);
r = self.obstacle_circle_list(i).radius;
rectangle('Position',[x-r,y-r,2*r,2*r],'Curvature',[1,1],'edgecolor',[1 0.2 0.2],'FaceColor',[1 0.2 0.2]);
end
for i = 1:length(self.obstacle_rect_list)
%rectangle('Position',[x,y,w,h],'PropertyName',propertyvalue)
xy = self.obstacle_rect_list(i).point_low;
wh = self.obstacle_rect_list(i).point_up - self.obstacle_rect_list(i).point_low;
rectangle('Position',[xy,wh],'Linewidth',1,'LineStyle','-','EdgeColor',[0.5 0.5 0.5],'FaceColor',[0.5 0.5 0.5])
end
% 繪制起點(diǎn)
rectangle('Position',[self.point_start-3,6,6],'Linewidth',1,'LineStyle','-','EdgeColor',[0.5 1 0.5],'FaceColor',[0.5 1 0.5]);
% 繪制終點(diǎn)
rectangle('Position',[self.point_end-3,6,6],'Linewidth',1,'LineStyle','-','EdgeColor',[0.5 1 0.5],'FaceColor',[0.5 1 0.5]);
% 如果沒有有輸入關(guān)鍵點(diǎn)則返回惰拱,否則繪制路徑
if isempty(x)
return
end
hold on ;
% 繪制路徑
% 加入起點(diǎn)
path_point_list = [self.point_start];
for i = 1:(length(input)/self.dim)
% x中相鄰數(shù)個(gè)值組成一個(gè)點(diǎn)
path_point = input((i-1)*self.dim+1:i*self.dim);
x = [path_point(1),path_point_list(end,1)];
y = [path_point(2),path_point_list(end,2)];
scatter(path_point(1),path_point(2),20,'b','filled');
% 當(dāng)前點(diǎn)連接到上一個(gè)點(diǎn)
plot(x,y,'b','linewidth',1.5);
hold on ;
path_point_list = [path_point_list;path_point];
end
hold on ;
% 終點(diǎn)連接到上一個(gè)點(diǎn)
x = [path_point_list(end,1),self.point_end(1)];
y = [path_point_list(end,2),self.point_end(2)];
plot(x,y,'b','linewidth',1.5);
hold on;
% 加入終點(diǎn)
path_point_list = [path_point_list;self.point_end];
text(90,100,num2str(num),'FontSize',20);
% 繪制顯示區(qū)域
axis([self.bound_low(1)-10 self.bound_up(1)+10 self.bound_low(2)-10 self.bound_up(2)+10]);
axis equal;
% 固定橫縱坐標(biāo)軸
set(gca,'XLim',[self.bound_low(1)-10 self.bound_up(1)+10]);
set(gca,'YLim',[self.bound_low(2)-10 self.bound_up(2)+10])
end
end
end
模型建立完了凫乖,我給地圖中隨機(jī)添加了幾個(gè)障礙物,現(xiàn)在來看看地圖的樣子弓颈。
optimization algorithm\application_path_planning\Test.m
測試腳本
%% 清理之前的數(shù)據(jù)
% 清除所有數(shù)據(jù)
clear all;
close all;
% 清除窗口輸出
clc;
% 初始化模型
model = Map_Model();
% 繪制無路徑地圖帽芽,無編號
% 第一個(gè)參數(shù)為算法輸出的結(jié)果,第二個(gè)參數(shù)為編號翔冀,繪制動態(tài)圖用
model.draw_map([],'');
這是當(dāng)前的地圖模型导街,下面將使用優(yōu)化算法在該地圖中尋找一條代價(jià)最小的路徑連接起點(diǎn)和終點(diǎn)。
四. 優(yōu)化算法計(jì)算路徑
這里將使用差分進(jìn)化算法來求解路徑纤子,差分進(jìn)化算法實(shí)現(xiàn)可以看優(yōu)化算法matlab實(shí)現(xiàn)(七)差分進(jìn)化算法matlab實(shí)現(xiàn)搬瑰。如果想使用其他優(yōu)化算法款票,則引入相關(guān)的優(yōu)化算法路徑后,實(shí)例化即可泽论。
由于不知道需要多少個(gè)關(guān)鍵點(diǎn)才能確定路徑艾少,故先計(jì)算5個(gè)關(guān)鍵點(diǎn)的路徑,如果有多余的關(guān)鍵點(diǎn)翼悴,后面減少關(guān)鍵點(diǎn)后再次計(jì)算缚够。5個(gè)關(guān)鍵點(diǎn),每個(gè)關(guān)鍵點(diǎn)有x,y兩個(gè)坐標(biāo)鹦赎,對于優(yōu)化算法來說其維度為10維谍椅。
參數(shù) | 值 |
---|---|
維度 | 10(5個(gè)關(guān)鍵點(diǎn)) |
種群 | 50 |
最大迭代 | 1000 |
范圍 | [(0,0),(100,100)] |
步長 | 0.5 |
實(shí)現(xiàn)代碼如下:
optimization algorithm\application_path_planning\Test.m
%% 清理之前的數(shù)據(jù)
% 清除所有數(shù)據(jù)
clear all;
close all;
% 清除窗口輸出
clc;
%% 添加目錄
% 將上級目錄中的frame文件夾加入路徑
addpath('../frame')
% 引入差分進(jìn)化算法
addpath('../algorithm_differential_evolution')
% 初始化模型
model = Map_Model();
% 預(yù)設(shè)關(guān)鍵點(diǎn)數(shù)
point_num = 5;
% 重新計(jì)算每一維的取值范圍
% 將(100,200)轉(zhuǎn)化為(100,200,100,200,100,200,100,200....)
range_max = repmat(model.bound_up, 1, point_num);
range_max = reshape(range_max, 1, numel(range_max));
range_min = repmat(model.bound_low, 1, point_num);
range_min = reshape(range_min, 1, numel(range_min));
%% 算法實(shí)例
dim = model.dim*point_num;
% 種群數(shù)量
size = 50;
% 最大迭代次數(shù)
iter_max = 1000;
% 取值范圍上界
range_max_list = range_max;
% 取值范圍下界
range_min_list = range_min;
% 實(shí)例化差分進(jìn)化算法類
base = DE_Impl(dim,size,iter_max,range_min_list,range_max_list);
base.is_cal_max = false;
% 確定適應(yīng)度函數(shù)
base.fitfunction = @model.fit_function;
% 運(yùn)行
base.run();
disp(['復(fù)雜度',num2str(base.cal_fit_num)]);
%% 下面繪制動態(tài)圖
% 繪制每一代的路徑
for i = 1:length(base.position_best_history)
model.draw_map(base.position_best_history(i,:),i);
% 每0.01繪制一次
pause = 0.01;
%下面是保存為GIF的程序
frame=getframe(gcf);
% 返回單幀顏色圖像
imind=frame2im(frame);
% 顏色轉(zhuǎn)換
[imind,cm] = rgb2ind(imind,256);
filename = ['path_planning_',num2str(point_num),'.gif'];
if i==1
imwrite(imind,cm,filename,'gif', 'Loopcount',inf,'DelayTime',1e-4);
else
imwrite(imind,cm,filename,'gif','WriteMode','append','DelayTime',pause);
end
if i <length(base.position_best_history)
% 如果不是最后一張圖就清除窗口
clf;
end
end
% 判斷是否有多余的點(diǎn)
has_surplus = model.get_surplus_point_num(base.position_best);
if has_surplus
disp('包含多余的點(diǎn),將point_num減1后重新測試')
end
% 原文鏈接:http://www.reibang.com/p/70252c42b37d
最終結(jié)果如下
程序顯示有多余的點(diǎn)古话,接下來會測一測關(guān)鍵點(diǎn)為4,3,2,1時(shí)的情況雏吭。
關(guān)鍵點(diǎn)數(shù) | 運(yùn)行時(shí)間(秒) | 代價(jià) | 是否有多余點(diǎn) |
---|---|---|---|
5 | 1106 | 127.428 | 是 |
4 | 928 | 125.98 | 是 |
3 | 783 | 127.7271 | 否 |
2 | 760 | 128.0267 | 否 |
1 | 719 | 133.5343 | 否 |
迭代圖像如下:
從最終結(jié)果可以看出,上述模型至少需要2個(gè)關(guān)鍵點(diǎn)(可以看有4個(gè)關(guān)鍵點(diǎn)的動態(tài)圖陪踩,有兩個(gè)多余的點(diǎn))但是卻在有4個(gè)關(guān)鍵點(diǎn)時(shí)得到了整個(gè)結(jié)果中的最優(yōu)解杖们。畢竟優(yōu)化算法是概率算法,不保證一定能得到最優(yōu)解肩狂,所以需要多進(jìn)行幾次試驗(yàn)選取最優(yōu)的結(jié)果才行胀莹,上面只進(jìn)行了一次試驗(yàn),所以是一個(gè)正常的結(jié)果婚温。
試驗(yàn)的耗時(shí)隨著維度的增加而增加,但是這個(gè)增加并不明顯媳否。關(guān)鍵點(diǎn)的數(shù)量對計(jì)算模型代價(jià)所耗時(shí)并不直接栅螟。模型計(jì)算耗時(shí)的最關(guān)鍵因素是:關(guān)鍵點(diǎn)數(shù)量+采樣點(diǎn)數(shù)量。所以步長越大篱竭,路徑越短力图,耗時(shí)也就越少。在步長一定掺逼,且當(dāng)關(guān)鍵點(diǎn)數(shù)量較多時(shí)吃媒,解空間搜索范圍較大,出現(xiàn)較長路徑的概率很大吕喘,所以耗時(shí)會相對較多赘那。
下面在確定關(guān)鍵點(diǎn)為3時(shí),測試下步長為0.1氯质, 1.0募舟,2.0時(shí)的結(jié)果。
最終結(jié)果如下
步長 | 運(yùn)行時(shí)間(秒) | 代價(jià) | 是否有多余點(diǎn) |
---|---|---|---|
2 | 188 | 123.2993 | 否 |
1 | 411 | 123.7047 | 否 |
0.5 | 783 | 127.7271 | 否 |
0.1 | 3188 | 127.7327 | 否 |
從表格可得知,步長越大呢灶,所需計(jì)算時(shí)間越少吴超,但結(jié)果卻越好,這是因?yàn)槿狱c(diǎn)較少鸯乃,路徑代價(jià)計(jì)算有一定失真鲸阻。看圖可以看出飒责,當(dāng)步長為1.0和2.0時(shí)赘娄,路徑其實(shí)有掠過不可通過的障礙,但是由于步長較大宏蛉,沒有取樣點(diǎn)在該障礙區(qū)域內(nèi)遣臼,所以計(jì)算時(shí)認(rèn)為該路徑有效。
五. 總結(jié)
本文主要使用優(yōu)化算法解決了路徑規(guī)劃問題拾并。這個(gè)問題不算太復(fù)雜揍堰,優(yōu)化算法也不用修改,只需要將問題建立模型嗅义,然后使用優(yōu)化算法去計(jì)算結(jié)果即可屏歹。也就是說,只要問題模型建立好之碗,使用任何一個(gè)優(yōu)化算法來求解都是相同的步驟蝙眶。
對于更加復(fù)雜的問題模型,可能需要對指定的優(yōu)化算法進(jìn)行針對性的修改來提高計(jì)算效率和準(zhǔn)確度褪那。不過大多數(shù)使用通用算法即可幽纷,不需要定制。
對于開頭的問題博敬,可以參考下面的做法:
1如何建立模型:問題—》數(shù)學(xué)模型—》代碼實(shí)現(xiàn)友浸。
因?yàn)樾枰褂脙?yōu)化算法來求解,所以問題模型的核心是一個(gè)函數(shù)偏窝,其輸入是所需要的解收恢,其輸出是該解的評價(jià)函數(shù)。只要滿足這兩點(diǎn)祭往,函數(shù)內(nèi)如何計(jì)算伦意,根據(jù)實(shí)際情況處理即可。
2優(yōu)化算法如何處理解空間內(nèi)的無效區(qū)域硼补∧福
當(dāng)該解(個(gè)體位置)到達(dá)無效區(qū)域時(shí),直接返回一個(gè)極差值括勺。本問題中就是返回一個(gè)極大值缆八,這樣到達(dá)該區(qū)域的個(gè)體將會直接被淘汰曲掰。缺點(diǎn)是當(dāng)無效區(qū)域占解空間比例很大時(shí),會很費(fèi)時(shí)奈辰。如果要規(guī)避栏妖,就要對優(yōu)化算法的算子進(jìn)行修改了,也比較麻煩奖恰。
3問題模型每一維不是一個(gè)數(shù)值吊趾,優(yōu)化算法如何處理。
將模型的輸入轉(zhuǎn)化為一個(gè)一維的向量瑟啃,例如這里一個(gè)二維點(diǎn)可以轉(zhuǎn)換為一個(gè)2維的向量论泛,5個(gè)二維點(diǎn)就是一個(gè)10維的向量。雖然這樣做維度會比較高蛹屿,但是處理起來比較簡單屁奏。直接將5個(gè)點(diǎn)傳入優(yōu)化算法進(jìn)行迭代也不是不行,比較勉強(qiáng)错负,算法實(shí)現(xiàn)需要修改不少坟瓢,好在matlab這種動態(tài)語言沒聲明變量類型,需要處理的部分不太多犹撒,但還是有不少bug需要解決折联,就不勉強(qiáng)了。