[経路計画]スターグリッド経路計画[Matlab026]

1.はじめに

誰かが壁で区切られた点Aから点Bに移動したいとします。下の図に示すように、緑は始点A、赤は終点B、青い四角は中央の壁です。
ここに画像の説明を挿入
最初に、検索領域が私たちによって正方形のグリッドに分割されていることに気づきました。このように、検索領域を単純化することは、経路探索の最初のステップです。この方法は、検索領域を2次元配列に単純化します。配列の各要素はグリッドの正方形であり、正方形は合格および不合格としてマークされています。パスは、AからBに渡す正方形のセットとして記述されます。道が見つかると、私たちの人々は目的地に到着するまで、ある広場の中心から別の広場へと歩きます。

これらの中点は「ノード」と呼ばれます。他の経路探索資料を読むと、ノードについて議論している人々をよく目にします。それらを正方形として説明してみませんか?パスが正方形ではない他の構造に分割されている可能性があるためです。それらは、長方形、六角形、またはその他の形状にすることができます。ノードは、形状のどこにでも配置できます。ノードは、中央、境界線などに配置できます。とにかく、このシステムは最も単純なので使用します。

検索の開始
上の図のグリッドで行ったように、検索領域が扱いやすいノードに変換されたら、次のステップは最短パスを見つけるために検索をガイドすることです。A *パスファインディングアルゴリズムでは、ポイントAから開始し、隣接する正方形をチェックして、ターゲットが見つかるまで外側に拡張します。

検索を開始するには、次の操作を実行します
。1。ポイントAから開始し、保留ポイントとして「オープンリスト」に保存します。オープンリストは買い物リストのようなものです。現在リストに含まれている要素は1つだけですが、将来的にはさらに多くの要素が含まれる予定です。パスは、そこに含まれる正方形を通過する場合と通過しない場合があります。基本的に、これはチェックする正方形のリストです。

2.開始点の周りの到達可能または通過可能なすべての正方形を探し、壁、水、またはその他のアクセスできない地形のある正方形をスキップします。到達可能または通過可能な正方形がオープンリストに追加されます。これらすべての正方形の「親正方形」としてポイントAを保存します。パスを記述したい場合、親グリッドの情報は非常に重要です。その具体的な目的については後で説明します。

3.開いているリストからポイントAを削除し、それを「閉じるリスト」に追加して、再度チェックする必要のないすべての正方形をリストに保存します。

この時点で、図に示す構造を形成する必要があります。写真では、濃い緑色の正方形が開始正方形の中心です。クローズドリストに追加されたことを示すために、水色でストロークされています。隣接するすべてのセルがオープンリストに追加され、薄緑色でストロークされます。各正方形には、開始正方形である親正方形を指す灰色のポインターがあります。

ここに画像の説明を挿入
次に、リスト内の隣接する正方形をオンにして、次のように前のプロセスを大まかに繰り返します。しかし、どの正方形を選ぶべきでしょうか?F値が最も低いもの。

パススコアリングパス
を通過する正方形を選択するための鍵は、次の式です。

F = G + H

ここに:

  • G =開始点Aから生成されたパスに沿ってグリッド上の指定された正方形に移動するコスト。
  • H =グリッド上のその正方形から終点Bに移動するための推定コスト。これはヒューリスティックと呼ばれることが多く、少し混乱する可能性があります。これは単なる推測であるためです。道路にはさまざまな障害物(壁、水など)がある可能性があるため、事前に経路の長さを知る方法はありません。この記事ではHを計算する方法しか提供していませんが、インターネット上で他の多くの方法を見つけることができます。

私たちのパスは、開いているリストを繰り返しトラバースし、F値が最も低い正方形を選択することによって生成されます。この記事では、このプロセスについて詳しく説明します。まず、この方程式の計算方法を詳しく見てみましょう。

前述のように、Gは、パスに沿って開始点から現在の点に移動するコストを表します。この例では、水平方向または垂直方向の移動のコストを10に設定し、対角線方向のコストを14に設定します。対角線に沿った距離は2の平方根(恐れることはありません)、つまり水平または垂直に移動するコストの約1.414倍であるため、これらの値を使用します。簡単にするために、10と14を概算します。比率は基本的に正しく、ルート演算と小数は避けています。これは、私たちがトラブルを恐れたり、数学が嫌いだりするからではありません。このような整数を使用すると、コンピューターの場合も高速になります。これらの単純化された方法を使用しないと、パスファインディングが非常に遅くなることがすぐにわかります。

特定のパスに沿って特定の正方形のG値を計算しているので、評価の方法は、その親ノードのG値を取得し、それが対角線であるか直角(非対角線)であるかによって異なります。親ノード、それぞれ14と10ずつ増加します。(正方形のG値=親ノードのG値+ 10または+14)この例では、開始正方形から複数の正方形を取得しているため、このメソッドの需要はさらに大きくなります。

H値は、さまざまな方法で推定できます。ここで使用する方法はマンハッタン法と呼ばれ、対角方向を無視して、現在のグリッドから目的のグリッドまでの水平方向と垂直方向の正方形の数の合計を計算します。次に、結果に10を掛けます。これは、街のある場所から別の場所へのブロックの数を数えるように見えるため、マンハッタン方式と呼ばれます。この場合、ブロックを斜めに横切ることはできません。すべての障害を無視することが非常に重要です。これは残りの距離の推定値であり、実際の値ではありません。そのため、この方法はヒューリスティックと呼ばれます。

Fの値は、GとHの合計です。最初の検索の結果は、以下のチャートで見ることができます。F、G、Hのスコアは各四角に書かれています。開始グリッドのすぐ右側の四角で示されているように、Fは左上隅に、Gは左下隅に、Hは右下隅に印刷されます。
ここに画像の説明を挿入
それでは、これらの正方形を見てみましょう。文字を書くための正方形、G = 10。これは、開始グリッドから水平方向に1グリッド間隔だけずれているためです。開始正方形のすぐ上、下、および左側の正方形のG値は10です。対角線の正方形のG値は14です。

H値は、マンハッタンから赤いターゲットグリッドまでの距離(| x2-x1 | + | y2-y1 |)* 10を解くことによって得られます。このグリッドは、水平方向と垂直方向にのみ移動し、中央の壁は無視されます。このように、開始点のすぐ右側の正方形は、赤い正方形から3正方形離れており、H値は30です。この正方形の上の正方形の距離は4正方形であり(水平方向と垂直方向にのみ移動できることに注意してください)、H値は40です。他の正方形のH値を計算する方法を知っているはずです〜。

各グリッドのF値は、GとHを加算するだけで得られます。

探し続ける

検索を続行するには、開いているリストからF値が最も低い正方形を選択するだけです。次に、選択した正方形に対して次の処理を実行します。

4.オープンリストから削除し、クローズドリストに追加します。

5.隣接するすべてのグリッドを確認します。すでにクローズドリストにあるか、通行できないもの(壁、水上地形、またはその他の通行不能な地形)をスキップし、まだ存在しない場合はオープンリストに追加します。選択した正方形を新しい正方形の親ノードとして使用します。

6.隣接するグリッドがすでにオープンリストにある場合は、現在のパスが適切かどうかを確認します。つまり、新しいパスを使用してG値に到達した場合に、G値が低くなるかどうかを確認します。そうでない場合は、何もしません。

一方、新しいG値が低い場合は、隣接する正方形の親ノードを現在選択されている正方形に変更します(上のグラフで、矢印の方向をこの正方形を指すように変更します)。最後に、FとGの値を再計算します。これが十分に明確でないと思われる場合は、下の図をご覧ください。

さて、それがどのように機能するか見てみましょう。最初の9つの正方形では、開始点が閉じたリストに切り替えられた後、開いたリストに8つの正方形が残っています。ここで、F値が最も低いのは、開始グリッドのすぐ右側のグリッドであり、そのF値は40です。したがって、この正方形を次に処理する正方形として選択します。直後の画像では、青色で強調表示されています。
ここに画像の説明を挿入
まず、オープンリストから取り出してクローズドリストに入れます(これが青色で強調表示されている理由です)。次に、隣接するグリッドを確認します。ああ、右側の3つのグリッドは壁なので、スキップします。左側のグリッドが開始グリッドです。クローズドリストにあるので、スキップします。

他の4つのグリッドはすでにオープンリストに含まれているため、G値をチェックして、このグリッドを通過した場合にパスが優れているかどうかを判断します。選択したグリッドの下のグリッドを見てみましょう。そのG値は14です。現在のグリッドからそこに移動すると、G値は20に等しくなります(現在のグリッドに到達するためのG値は10であり、上のグリッドに移動するとG値が10増加します)。20のG値は14より大きいため、これは適切なパスではありません。写真を見れば分かります。1つの正方形を水平に移動してから1つの正方形を垂直に移動する代わりに、1つの正方形を斜めに移動するのと同じくらい簡単です。

オープンリストにすでに存在する4つの隣接するグリッドに対してこのプロセスを繰り返すと、現在のグリッドを使用してもパスを改善できないことがわかったため、変更を加えません。隣接するすべての正方形を確認したので、次の正方形に移動できます。

したがって、オープンリストを検索すると、グリッドは7つしかなく、F値が最も低いグリッドを選択します。興味深いことに、今回は、54個の値を持つ2つのグリッドがあります。どのように選択しますか?これは面倒ではありません。速度に関しては、リストに追加された最後のグリッドを選択する方が速くなります。これにより、パスファインディングプロセスでターゲットに近づくときに、最初に新しく見つかったグリッドを使用することが優先されます。しかし、それは問題ではありません。(同じ値の処理が異なると、A *アルゴリズムのバージョンが異なると、同じ長さの異なるパスが検出されます。)

次に、図に示すように、開始グリッドの右下にあるグリッドを選択します。
ここに画像の説明を挿入
今回、隣接するグリッドを確認したところ、右側に壁があったのでスキップしました。トップボックスもスキップされています。また、壁の下のグリッドをスキップしました。どうして?角を越えずにそのグリッドに直接到達することはできないからです。あなたは本当に最初に降りて、それからその広場に着き、そして角を一歩ずつ歩く必要があります。(注:コーナーを交差させるルールはオプションです。ノードの配置方法によって異なります。)

このようにして、他の5つのグリッドが残ります。現在のグリッドの下にある他の2つのグリッドは現在オープンリストにないため、それらを追加し、現在のグリッドを親ノードとして指定します。残りの3つのグリッドのうち、2つはすでにクローズドリストに含まれているため(開始グリッドと、現在のグリッドの上にあるグリッドで、表で青色で強調表示されています)、スキップします。現在のグリッドの左側にある最後のグリッドは、このパスを通じてG値が低いかどうかを確認するためにチェックされます。心配しないでください。オープンリストの次のグリッドを確認する準備ができています。

次の図に示すように、ターゲットセルがクローズドリスト(注釈)に追加されるまで、このプロセスを繰り返します。
ここに画像の説明を挿入
開始グリッドの下のグリッドの親ノードは、前のノードとはすでに異なっていることに注意してください。以前は、そのG値は28で、右上のグリッドを指していました。現在、そのG値は20であり、その上のグリッドを指しています。これはパスファインディングプロセスのどこかで発生します。新しいパスが適用されると、G値が低くなるようにチェックされます。そのため、親ノードが再割り当てされ、G値とF値が再計算されます。この例ではこの変更は重要ではありませんが、多くの場合、この変更はパスファインディングの結果に大きな変化をもたらす可能性があります。

では、このパスをどのように決定するのでしょうか。非常に簡単です。赤いターゲットグリッドから開始し、矢印の方向に親ノードに向かって移動します。これは最終的にあなたを最初のグリッドに戻すでしょう、これがあなたの道です!写真のようになります。開始グリッドAからターゲットグリッドBへの移動は、ターゲットポイントに到達するまで、パスに沿って各グリッド(ノード)の中点から次のグリッドに移動するだけです。とても簡単です。

ここに画像の説明を挿入
次のJAVAバージョンのコードは次のとおりです。

A-starアルゴリズムの手順:
1。最初に開始点をオープンリストに追加します

2.オープンリストにノードがある場合は、最初のノード、つまりF値が最小のノードを取り出し、
このノードがターゲットポイントであるかどうか判断します。見つかった場合は、ジャンプし
てノードを取得します。このノードに従って8方向に進み、G、H、F値を見つけます。
各ノードがマップを通過できるかどうかを判断し、失敗した場合は、閉じたリストに追加して飛び出します。
各ノードが閉じた状態にあるかどうかを判断します。リストし、ある場合はジャンプします。
各ノードがオープンリストにあるかどうかを判断します。ある場合は、G値、F値、およびその親ノードを更新します。ない場合は、オープンリストに追加し、G値を計算します。 、H値、F値、およびそのノードを追加します。

3.このノードをオープンリストから削除し、クローズドリストに追加します。

4. F値が最小のノードに従って開いているリストをソートし、最小のF値が最初になります。

5.ターゲットポイントがオープンリストに含まれる、つまり検出されるまで、手順2、3、4を繰り返します。ターゲットポイントはオープンリストに含まれず、オープンリストは空、つまり検出されません。

第二に、ソースコード

%% A* demo
 
clc;
clear;
% pause(3); 
%% init
n=30;
starNum=1;
% starNum = randi(n*n,[1,1]);
goalNum=172;
goalNum = randi(n*n,[1,1]);
banper=0.25;
%% map init
figure('name','A*','NumberTitle','off','MenuBar','none');
global point 
for ii=1:n*n
    point(ii).num = ii;
    point(ii).father=[];
    point(ii).Gcost=[];
    point(ii).Hcost=[];
end
%% banper
banList=[randi(n*n,[1,floor(banper*n*n)])];
load banList
banList(find(banList==goalNum))=[];
for jj = 1:length(banList)
    if banList(jj)~=goalNum || banList(jj)~=starNum
        point(banList(jj)).Gcost = Inf;
    end
end
point(starNum).Gcost=0;
point(starNum).father = point(starNum).num;
point(starNum).Hcost=getHcost(point(starNum),point(goalNum),n);
 
%% A*core
openList = [];
closeList = [];
closeListNum=[];
openListNum=[];
openList = [openList,point(starNum)];
while length(openList)
    % opneList
    costList = getCost(openList,point(goalNum),n);
    currentPoint = openList(find(costList==min(costList),1));
    openList(find(min(costList)==costList,1))=[];
    closeList = [closeList,currentPoint];
    neighbourNum = getNeighbour(currentPoint,n);
    closeListNum = cat(1,closeList.num);
    openListNum = cat(1,openList.num);
    for ii = 1:length(neighbourNum)
        if neighbourNum(ii)==point(goalNum).num
            point(neighbourNum(ii)).father = currentPoint.num;
            point(goalNum).father = currentPoint.num;
            disp('ok')
            routPlot(goalNum,n);
            return;
        end
            log1=0;
            try
                tmp=point(neighbourNum(ii)).Gcost;
                if tmp ==inf
                    log1 = 1;
                end
            catch
                log1=0;
            end
            if log1 || ismember(neighbourNum(ii),closeListNum)
                continue;
            elseif (ismember(neighbourNum(ii),openListNum))
            oldGcost = getGcost(point(neighbourNum(ii)),n);
            father = point(neighbourNum(ii)).father;
            point(neighbourNum(ii)).father = currentPoint.num;
            newGcost = getGcost(point(neighbourNum(ii)),n);
            if newGcost>oldGcost
                point(neighbourNum(ii)).father = father;
            else
                point(neighbourNum(ii)).Gcost = newGcost;
            end
            continue;
        elseif ~ismember(neighbourNum(ii),closeListNum)
            point(neighbourNum(ii)).father = currentPoint.num;
            point(neighbourNum(ii)).Gcost = getGcost(point(neighbourNum(ii)),n);
            point(neighbourNum(ii)).Hcost = getHcost(point(neighbourNum(ii)),point(goalNum),n);
            openList = [openList,point(neighbourNum(ii))];
            end
    end
    closeListNum = cat(1,closeList.num);
    openListNum = cat(1,openList.num);
    pause(0.1);
    mydrawnow(starNum,goalNum,banList,closeListNum,openListNum,n);
end
 

3、実行中の結果

ここに画像の説明を挿入

四、備考

QQ912100926の過去のレビューを追加するための完全なコードまたは記述
>>>>>>
[経路計画] 3次元UAV経路計画のための粒子群最適化アルゴリズム[ Matlab012 ]
[経路計画]複数のロジスティクスセンターでのオープンビークルの遺伝的アルゴリズム経路計画[ Matlab 013]
[経路計画]ロボットグリッド経路計画のための粒子群アルゴリズム[Matlab014]
[経路計画]最短経路を解決するためのAntコロニーアルゴリズム[Matlab015]
[経路計画]ロジスティクスセンターの免疫アルゴリズムサイト選択[Matlab016]
[経路計画]人工蜂コロニーを備えたドローンの3次元経路計画[Matlab017]
[経路計画]グリッドマップロボット経路計画に基づく遺伝的アルゴリズム[Matlab018]
[経路計画]複数のドローン攻撃スケジューリングのためのAntSwarmアルゴリズム[Matlab 019]
[経路計画]グリッドマップに基づくロボットの最適な経路計画のための遺伝的アルゴリズム[Matlab020]
[経路計画]分布の順序を考慮した複数の無人システムのための遺伝的アルゴリズム[Matlab021問題]
[経路計画]
多施設VRP Antコロニーアルゴリズムの問​​題[Matlab022] [経路計画]時間ウィンドウで多施設VRPを解くAntコロニーアルゴリズム[Matlab023問題]
[経路計画]遺伝子アルゴリズムに基づく多施設VRPソリューション[Matlab024]
[経路計画] VRP問題に対するシミュレートされたアニーリングソリューション[Matlab025]

おすすめ

転載: blog.csdn.net/m0_54742769/article/details/113041821