日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

AStar算法通用实现+可视化(Matlab)

發布時間:2023/12/14 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 AStar算法通用实现+可视化(Matlab) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
%% AStar算法通用實現+可視化clc, clear, close all;%% 定義結構體% 全局變量 起點 終點 當前點 global start_point end_point current_point ValueSet% 加載地圖 load("mapData01.mat") % 地圖大小 [row, col] = size(map);% 新節點 NewPoint = @(a, b) struct('x', a, 'y', b);SetKeyStr = @(x, y) string(num2str([x, y], '%03d'));InvalidKeyStr = "000000"; % 新待搜索的節點 NewSearchPoint = @(a, b) struct('key', SetKeyStr(a, b), 'x', a, 'y', b, 'G', 0, 'H', 0, 'F', 0, 'parent_key', InvalidKeyStr); %啟發式搜索代價函數類型 HType = 2; % 各類值設定(同樣用于染色) ValueSet = struct('passable', 255, 'impassable', 0, 'openlist', 180, 'closelist', 120, 'start', 60, 'target', 60, 'current', 30, 'path', 60);% 定義起點 與 終點 [start_point, end_point] = deal(NewPoint(2, 2), NewPoint(20, 20)); %起始/結束點坐標 [map(start_point.x, start_point.y), map(end_point.x, end_point.y)] = deal(ValueSet.start, ValueSet.target);% 搜索點(下左右4點 分別為dx dy 以及移動代價(實際為sqrt(dx*dx+dy*dy)) SearchDxy = [0, -1, 1; -1, 0, 1; 1, 0, 1; 0, 1, 1];%% 初始化 1.起始點加入open_list% 初始狀態設定 open_list(1) = NewSearchPoint(start_point.x, start_point.y); % 計算代價 根據函數: F = G + H open_list(1).H = CalcH(start_point.x, start_point.y, end_point.x, end_point.y, HType); open_list(1).G = 0; open_list(1).F = open_list.H; %待確定代價的點 open_list = struct2table(open_list); %已確定代價的點 close_list = []; %當前點(設定為初始點) current_point = open_list; figure % 是否發現路徑 b_find_path = 0; %% 2.遍歷open_list,找到最小合代價F點 while ~isempty(open_list)index_min_open_list_F = SearchOptimalPoint(open_list, close_list, current_point, end_point);% 最小代價F的點選中為當前點,進行后續open_list選取current_point = open_list(index_min_open_list_F, :); % 在open_list中將其刪除open_list(index_min_open_list_F, :) = [];% 將其加入close_listclose_list = [close_list; current_point]; % 將新加入的close_list點標記(染色)map(current_point.x, current_point.y) = ValueSet.closelist; DrawMap(map); %繪圖% 3.檢查是否符合退出條件if current_point.x == end_point.x && current_point.y == end_point.yb_find_path = true;break;end% 4. 檢查當前點周圍可移動點,并加入open_list中for search_dxy = SearchDxy'search_point = NewSearchPoint(current_point.x + search_dxy(1), current_point.y + search_dxy(2));key = SetKeyStr(search_point.x, search_point.y);% 4.1如果它是不可抵達的或者它在 close list 中,忽略它if search_point.x <= 0 || search_point.y <= 0 || map(search_point.x, search_point.y) == ValueSet.impassable || map(search_point.x, search_point.y) == ValueSet.closelistcontinue;endsearch_point = struct2table(search_point);% 移動代價search_point.G = current_point.G + search_dxy(3); % 估算成本search_point.H = CalcH(search_point.x, search_point.y, end_point.x, end_point.y, HType); search_point.F = search_point.G + search_point.H;search_point.parent_key = current_point.key;% 判定當前open_list中是否存在該搜索點index_existed_in_openlist = find(open_list.key == key, 1); % 4.2如果它不在 open list 中 把它加入 open list% 并且把當前方格設置為它的父親 記錄該方格的 F G 和 H 值if map(search_point.x, search_point.y) ~= ValueSet.openlistopen_list = [open_list; search_point];% 將新加入的open_list點標記(染色)map(search_point.x, search_point.y) = ValueSet.openlist; % 4.3如果它已經在 open list 中 檢查這條路徑 ( 即經由當前方格到達它那里 ) 是否更好,用 G 值作參考% 更小的 G 值表示這是更好的路徑。如果是這樣 把它的父親設置為當前方格 并重新計算它的 G 和 F 值else if search_point.G < open_list.G(index_existed_in_openlist)%若open_list中存在值的G值更大,表示由當前點到達該值更優,將原本儲存點的信息替換為當前搜索點信息open_list(index_existed_in_openlist, :) = search_point; % 進行替換endendend end%% 從候選點中選取與目標方向最接近的點 function index_min_dyaw = FindMinDyaw(base_point_start, base_point_end, candidate_point_start, candidate_point_end, b_output_single)if nargin < 5%是否只輸出唯一值b_output_single = false;endend_yaw = atan2(base_point_end.y - base_point_start.y, base_point_end.x - base_point_start.x);open_list_yaw = atan2(candidate_point_end.y - candidate_point_start.y, candidate_point_end.x - candidate_point_start.x);dyaw = abs(LimitInPi(open_list_yaw - end_yaw));if ~b_output_singleindex_min_dyaw = find(dyaw == min(dyaw));elseindex_min_dyaw = find(dyaw == min(dyaw), 1, 'last');end end%% 估算代價計算 % 參考文章《A*算法中啟發函數H的選取》 % h_diagonal = 沿著對角線移動的步數, h_straight = 曼哈頓距離, % 通過考慮所有的對角線移動的步數(每步耗散D2)以及剩下的直線移動的步數(每步耗散D)將這兩者結合在一起. function H = CalcH(x1, y1, x2, y2, type)if nargin < 5type = 3;enddx = x2 - x1;dy = y2 - y1;switch typecase 1% 歐式距離 乘以系數可以加快搜索距離,但可能造成無解情況H = sqrt(dx * dx + dy * dy); case 2% 曼哈頓距離H = abs(dx) + abs(dy); case 3h_diagonal = min(abs(dx), abs(dy));h_straight = abs(dx) + abs(dy);H = sqrt(2) * h_diagonal + (h_straight - 2 * h_diagonal); % 可沿對角移動時的代價函數case 4% Dijkstra算法H = 0; end end%% 繪制map圖 function DrawMap(map)global start_point end_point current_point ValueSet% 注意這里對map的操作只是為了顯示效果,不會影響到主函數內的map,[map(start_point.x, start_point.y), map(end_point.x, end_point.y), map(current_point.x, current_point.y)] = deal(ValueSet.start, ValueSet.target, ValueSet.current);imagesc(map')% 注意用plot和imagesc的區別,這里加了一個轉置set(gca, 'XDir', 'normal', 'YDir', 'normal'); %如果不加normal是直接顯示A的結構pause(0.0001); end%% 搜索最小代價點 function index_min_open_list_F = SearchOptimalPoint(open_list, close_list, current_point, end_point)%找到最小代價indexindex_min_open_list_F = find(open_list.F == min(open_list.F)); %如果有多個最小代價值,按一定規則優先選取最優解if length(index_min_open_list_F) > 1% 起點時出現,則優先選取同起始/結束連線夾角最接近者if height(close_list) == 1index_min_dyaw_end = FindMinDyaw(current_point, end_point, current_point, open_list(index_min_open_list_F, :), 1);index_min_open_list_F = index_min_open_list_F(index_min_dyaw_end);% 否則找到與上一刻方向最接近的點else index_last = find(close_list.key == current_point.parent_key, 1);last_point = close_list(index_last, :);index_min_dyaw_last = FindMinDyaw(last_point, current_point, current_point, open_list(index_min_open_list_F, :));index_min_open_list_F = index_min_open_list_F(index_min_dyaw_last);% 如果還有多個結果,優先選取同當前/結束連線夾角最接近者if length(index_min_open_list_F) > 1index_min_dyaw_end = FindMinDyaw(current_point, end_point, current_point, open_list(index_min_open_list_F, :), 1);index_min_open_list_F = index_min_open_list_F(index_min_dyaw_end);endendend end%% 功能:將輸入角度范圍限制在+-pi以內 function angle = LimitInPi(angle)% 輸入:弧度% 輸出:限制在+-pi以內的弧度angle = mod(angle, 2 * pi); % 對2pi取余kk = find(abs(angle) > pi);if ~isempty(kk)angle(kk) = angle(kk) - sign(angle(kk)) * 2 * pi;end end

說明

  • matlab實現并不實用,僅作演示,會考慮用c#的實現
  • load("mapData01.mat")這里,地圖數據如下表
  • csv數據格式,直接改擴展名為.xlsx即可
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0 0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0 0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0 0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0 0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0 0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0 0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0 0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0 0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0 0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0 0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0 0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0 0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  • 參考&感謝

    https://www.cnblogs.com/technology/archive/2011/05/26/2058842.html

總結

以上是生活随笔為你收集整理的AStar算法通用实现+可视化(Matlab)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。