Parallel-algorithm-quick-guide
並列アルゴリズム-はじめに
- アルゴリズム*は、ユーザーから入力を受け取り、何らかの計算後に出力を生成する一連のステップです。 *並列アルゴリズム*は、異なる処理デバイスで複数の命令を同時に実行し、個々の出力をすべて組み合わせて最終結果を生成できるアルゴリズムです。
並行処理
インターネットの成長とともにコンピューターが容易に利用できるようになったことで、データの保存および処理方法が変わりました。 私たちは、データが豊富にある日と年齢に住んでいます。 毎日、複雑なコンピューティングを必要とする膨大な量のデータを迅速に処理しています。 時には、同時に発生する類似または相互に関連するイベントからデータを取得する必要があります。 これは、複雑なタスクを分割して複数のシステムを処理し、迅速に出力を生成できる*並行処理*が必要な場所です。
大量の複雑なデータの処理がタスクに含まれる場合、同時処理が不可欠です。 例には、大規模データベースへのアクセス、航空機試験、天文計算、原子および核物理学、生物医学分析、経済計画、画像処理、ロボット工学、天気予報、ウェブベースのサービスなどが含まれます。
並列処理とは何ですか?
- 並列*は、複数の命令セットを同時に処理するプロセスです。 合計計算時間を短縮します。 並列処理は、*並列コンピューター*を使用して実装できます。 多くのプロセッサを搭載したコンピューター。 並列コンピューターには、マルチタスクをサポートする並列アルゴリズム、プログラミング言語、コンパイラー、およびオペレーティングシステムが必要です。
このチュートリアルでは、*並列アルゴリズム*についてのみ説明します。 さらに進む前に、まずアルゴリズムとそのタイプについて説明します。
アルゴリズムとは何ですか?
- アルゴリズム*は、問題を解決するために従う一連の命令です。 アルゴリズムを設計する際には、アルゴリズムが実行されるコンピューターのアーキテクチャを検討する必要があります。 アーキテクチャごとに、2種類のコンピューターがあります-
- シーケンシャルコンピューター
- 並列コンピューター
コンピュータのアーキテクチャに応じて、2種類のアルゴリズムがあります-
- Sequential Algorithm -問題を解決するために、命令のいくつかの連続したステップが時系列で実行されるアルゴリズム。
- 並列アルゴリズム-問題はサブ問題に分割され、個々の出力を取得するために並行して実行されます。 後で、これらの個々の出力が組み合わされて、最終的な望ましい出力が得られます。
大きな問題をサブ問題に分割するのは簡単ではありません。 副問題には、データ間の依存関係がある場合があります。 したがって、問題を解決するには、プロセッサーが相互に通信する必要があります。
プロセッサが互いに通信するのに必要な時間は、実際の処理時間よりも長いことがわかっています。 したがって、並列アルゴリズムを設計する際には、効率的なアルゴリズムを得るために適切なCPU使用率を考慮する必要があります。
アルゴリズムを適切に設計するには、並列コンピューターの基本的な*計算モデル*の明確なアイデアが必要です。
計算のモデル
順次および並列コンピューターは、アルゴリズムと呼ばれる命令のセット(ストリーム)で動作します。 これらの一連の指示(アルゴリズム)は、各ステップで何をする必要があるかをコンピューターに指示します。
命令ストリームとデータストリームに応じて、コンピュータは4つのカテゴリに分類することができます-
- 単一命令ストリーム、単一データストリーム(SISD)コンピューター
- 単一命令ストリーム、複数データストリーム(SIMD)コンピューター
- 複数命令ストリーム、単一データストリーム(MISD)コンピューター
- 複数命令ストリーム、複数データストリーム(MIMD)コンピューター
SISDコンピューター
SISDコンピュータには、* 1つの制御ユニット、1つの処理ユニット*、* 1つのメモリユニット*が含まれています。
このタイプのコンピューターでは、プロセッサーは制御ユニットから命令の単一ストリームを受信し、メモリーユニットからのデータの単一ストリームで動作します。 計算中、各ステップで、プロセッサは制御ユニットから1つの命令を受け取り、メモリユニットから受け取った単一のデータを操作します。
SIMDコンピューター
SIMDコンピュータには、* 1つの制御ユニット、複数の処理ユニット*、*共有メモリまたは相互接続ネットワーク*が含まれています。
ここでは、1つの制御ユニットがすべての処理ユニットに命令を送信します。 計算中、各ステップで、すべてのプロセッサは制御ユニットから単一の命令セットを受け取り、メモリユニットからの異なるデータセットで動作します。
各処理ユニットには、データと命令の両方を保存する独自のローカルメモリユニットがあります。 SIMDコンピューターでは、プロセッサー間で通信する必要があります。 これは、*共有メモリ*または*相互接続ネットワーク*によって行われます。
一部のプロセッサが一連の命令を実行している間、残りのプロセッサは次の一連の命令を待ちます。 コントロールユニットからの命令により、どのプロセッサが*アクティブ*(命令を実行)または*非アクティブ*(次の命令を待つ)になるかが決定されます。
MISDコンピューター
名前が示すように、MISDコンピューターには*複数の制御ユニット、複数の処理ユニット*、* 1つの共通メモリユニット*が含まれています。
ここで、各プロセッサには独自の制御ユニットがあり、共通のメモリユニットを共有しています。 すべてのプロセッサは、独自の制御ユニットから個別に命令を取得し、それぞれの制御ユニットから受信した命令に従って、単一のデータストリームで動作します。 このプロセッサは同時に動作します。
MIMDコンピューター
MIMDコンピューターには、複数の制御ユニット、複数の処理ユニット、*共有メモリ*または*相互接続ネットワーク*があります。
ここでは、各プロセッサに独自の制御ユニット、ローカルメモリユニット、および算術論理ユニットがあります。 彼らは、それぞれの制御ユニットから異なる命令セットを受け取り、異なるデータセットで動作します。
Note
- 共通メモリを共有するMIMDコンピューターは「マルチプロセッサー」と呼ばれ、相互接続ネットワークを使用するMIMDコンピューターは「マルチコンピューター」と呼ばれます。
- プロセッサの物理的な距離に基づいて、マルチコンピューターには2つのタイプがあります-
- マルチコンピューター-すべてのプロセッサーが互いに非常に近い場合(例えば、同じ部屋に)。
- 分散システム-すべてのプロセッサが互いに離れている場合(例:異なる都市)
並列アルゴリズム-分析
アルゴリズムの分析は、アルゴリズムが有用かどうかを判断するのに役立ちます。 一般に、アルゴリズムは、実行時間*(時間の複雑さ)および必要なスペースの量(スペースの複雑さ)*に基づいて分析されます。
洗練されたメモリデバイスを手頃な価格で利用できるため、ストレージスペースは問題になりません。 したがって、スペースの複雑さはそれほど重要ではありません。
並列アルゴリズムは、コンピューターの計算速度を向上させるように設計されています。 並列アルゴリズムを分析するために、通常、次のパラメータを考慮します-
- 時間の複雑さ(実行時間)、
- 使用されているプロセッサの合計数、および
- 総費用。
時間の複雑さ
並列アルゴリズムを開発した主な理由は、アルゴリズムの計算時間を短縮することでした。 したがって、アルゴリズムの実行時間を評価することは、その効率を分析する上で非常に重要です。
実行時間は、アルゴリズムが問題を解決するのにかかった時間に基づいて測定されます。 合計実行時間は、アルゴリズムが実行を開始してから停止するまでの時間を計算します。 すべてのプロセッサが同時に実行を開始または終了しない場合、アルゴリズムの合計実行時間は、最初のプロセッサが実行を開始した瞬間から最後のプロセッサが実行を停止する瞬間までです。
アルゴリズムの時間の複雑さは、3つのカテゴリに分類できます。
- 最悪の複雑さ-特定の入力のアルゴリズムに必要な時間が*最大*の場合。
- 平均ケースの複雑さ-特定の入力のアルゴリズムに必要な時間が*平均*の場合。
- ベストケースの複雑さ-特定の入力のアルゴリズムに必要な時間が*最小*の場合。
漸近解析
アルゴリズムの複雑さまたは効率は、目的の出力を得るためにアルゴリズムによって実行されるステップの数です。 漸近解析は、理論解析でアルゴリズムの複雑さを計算するために行われます。 漸近解析では、アルゴリズムの複雑度関数を計算するために長い入力が使用されます。
注-*漸近*は、線が曲線に接する傾向があるが交差しない条件です。 ここで、直線と曲線は互いに漸近しています。
漸近表記法は、速度の上限と下限を使用するアルゴリズムの可能な限り最も速い実行時間と最も遅い実行時間を記述する最も簡単な方法です。 このために、我々は次の表記法を使用します-
- ビッグオー表記
- オメガ表記
- シータ表記
ビッグオー表記
数学では、関数の漸近的特性を表すためにBig O表記が使用されます。 シンプルで正確な方法で、大規模な入力に対する関数の動作を表します。 これは、アルゴリズムの実行時間の上限を表す方法です。 これは、アルゴリズムが実行を完了するのにかかる最長時間を表します。 機能-
f(n)= O(g(n))
すべての n に対して f(n)≤c g(n)となる正の定数 *c および* n〜0〜が存在する場合(ただし、 n≥n〜0〜*)。
オメガ表記
オメガ表記法は、アルゴリズムの実行時間の下限を表す方法です。 機能-
f(n)=Ω(g(n))
すべての n に対して f(n)≥c g(n)となる正の定数 *c および* n〜0〜が存在する場合( n≥n〜0〜*)。
シータ表記
シータ表記は、アルゴリズムの実行時間の下限と上限の両方を表す方法です。 機能-
f(n)=θ(g(n))
すべての n に対してc1 g(n)≤f(n)≤c2 g(n)となるような正の定数* c〜1〜、c〜2〜、および n〜0〜が存在する場合 n≥n〜0〜*。
アルゴリズムの高速化
並列アルゴリズムのパフォーマンスは、 speedup を計算することにより決定されます。 スピードアップは、特定の問題に対する既知の最速のシーケンシャルアルゴリズムの最悪の場合の実行時間と、パラレルアルゴリズムの最悪の場合の実行時間の比率として定義されます。
スピードアップ=
Worst case execution time of the fastest known sequential for a particular problem / Worst case execution time of the parallel algorithm
使用プロセッサ数
使用されるプロセッサの数は、並列アルゴリズムの効率を分析する上で重要な要素です。 コンピューターの購入、保守、および実行のコストが計算されます。 問題を解決するためにアルゴリズムが使用するプロセッサーの数が増えると、得られる結果がより高価になります。
総費用
並列アルゴリズムの総コストは、時間の複雑さと特定のアルゴリズムで使用されるプロセッサの数の積です。
総コスト=時間の複雑さ×使用するプロセッサの数
したがって、並列アルゴリズムの*効率*は-
効率=
Worst case execution time of sequential algorithm / Worst case execution time of the parallel algorithm
並列アルゴリズム-モデル
並列アルゴリズムのモデルは、データと処理方法を分割する戦略を検討し、適切な戦略を適用して相互作用を削減することにより開発されます。 この章では、次の並列アルゴリズムモデルについて説明します-
- データ並列モデル
- タスクグラフモデル
- ワークプールモデル
- マスタースレーブモデル
- 生産者消費者またはパイプラインモデル *ハイブリッドモデル
データ並列
データ並列モデルでは、タスクはプロセスに割り当てられ、各タスクは異なるデータに対して同様のタイプの操作を実行します。* データの並列性*は、複数のデータ項目に適用される単一の操作の結果です。
データ並列モデルは、共有アドレススペースとメッセージパッシングパラダイムに適用できます。 データ並列モデルでは、局所性保存分解を選択するか、最適化された集団相互作用ルーチンを使用するか、計算と相互作用を重複させることにより、相互作用のオーバーヘッドを削減できます。
データ並列モデルの問題の主な特徴は、データ並列性の強度が問題のサイズとともに増加することです。これにより、より大きな問題を解決するためにより多くのプロセスを使用できるようになります。
例-密行列の乗算。
タスクグラフモデル
タスクグラフモデルでは、並列性は*タスクグラフ*で表されます。 タスクグラフは、自明または非自明のいずれかです。 このモデルでは、タスク間の相関関係を利用して、局所性を促進したり、相互作用コストを最小化します。 このモデルは、タスクに関連付けられた計算の数と比較して、タスクに関連付けられたデータの量が膨大になる問題を解決するために実施されます。 タスクは、タスク間のデータ移動のコストを改善するために割り当てられます。
例-並列クイックソート、スパースマトリックス因数分解、および分割統治アプローチによる並列アルゴリズム。
ここでは、問題はアトミックタスクに分割され、グラフとして実装されます。 各タスクは、1つ以上の先行タスクに依存する独立したジョブ単位です。 タスクの完了後、先行タスクの出力は依存タスクに渡されます。 先行タスクを持つタスクは、その先行タスク全体が完了したときにのみ実行を開始します。 グラフの最終出力は、最後の依存タスクが完了すると受信されます(上の図のタスク6)。
ワークプールモデル
ワークプールモデルでは、負荷を分散するために、タスクがプロセスに動的に割り当てられます。 したがって、任意のプロセスが任意のタスクを実行する可能性があります。 このモデルは、タスクに関連付けられたデータの量がタスクに関連付けられた計算よりも比較的少ない場合に使用されます。
プロセスにタスクを事前に割り当てる必要はありません。 タスクの割り当ては集中化または分散化されます。 タスクへのポインターは、物理的に共有されたリスト、優先度キュー、またはハッシュテーブルまたはツリーに保存されます。また、物理的に分散されたデータ構造に保存することもできます。
タスクは最初に使用可能になるか、動的に生成されます。 タスクが動的に生成され、タスクの分散割り当てが行われる場合、すべてのプロセスが実際にプログラム全体の完了を検出し、他のタスクの検索を停止できるように、終了検出アルゴリズムが必要です。
例-並列ツリー検索
マスタースレーブモデル
マスタースレーブモデルでは、1つ以上のマスタープロセスがタスクを生成し、スレーブプロセスに割り当てます。 次の場合、タスクを事前に割り当てることができます-
- マスターがタスクのボリュームを推定できる、または
- ランダムな割り当てにより、負荷を分散するのに十分なジョブを実行できます。または
- スレーブには、異なる時間にタスクの小さな部分が割り当てられます。
通常、このモデルは shared-address-space または message-passing paradigms に適しています。これは、相互作用が自然に2つの方法であるためです。
場合によっては、タスクを段階的に完了する必要があり、次の段階のタスクを生成する前に各段階のタスクを完了する必要があります。 マスタースレーブモデルは、*階層*または*マルチレベルマスタースレーブモデル*に一般化できます。このモデルでは、最上位レベルのマスターがタスクの大部分を第2レベルのマスターに送ります。タスク自体の一部を実行できます。
マスタースレーブモデルを使用する際の注意事項
マスターが輻輳ポイントにならないように注意する必要があります。 タスクが小さすぎる場合や、作業者が比較的速い場合に発生する可能性があります。
タスクは、タスクの実行コストが通信のコストと同期のコストを支配するように選択する必要があります。
非同期の相互作用は、相互作用とマスターによる作業生成に関連する計算の重複を支援する場合があります。
パイプラインモデル
また、*生産者-消費者モデル*として知られています。 ここでは、一連のデータが一連のプロセスを介して渡され、各プロセスが何らかのタスクを実行します。 ここでは、新しいデータの到着により、キュー内のプロセスによる新しいタスクの実行が生成されます。 プロセスは、サイクルの有無にかかわらず、線形または多次元配列、ツリー、または一般的なグラフの形のキューを形成できます。
このモデルは、生産者と消費者のチェーンです。 キュー内の各プロセスは、キュー内で先行するプロセスの一連のデータ項目のコンシューマー、およびキュー内で後続のプロセスのデータのプロデューサーと見なすことができます。 キューは線形チェーンである必要はありません。有向グラフにすることができます。 このモデルに適用できる最も一般的な相互作用最小化手法は、計算との相互作用の重複です。
例-並列LU分解アルゴリズム。
ハイブリッドモデル
問題を解決するために複数のモデルが必要な場合は、ハイブリッドアルゴリズムモデルが必要です。
ハイブリッドモデルは、階層的に適用される複数のモデル、または並列アルゴリズムの異なるフェーズに順次適用される複数のモデルのいずれかで構成されます。
例-並列クイックソート
並列ランダムアクセスマシン
- Parallel Random Access Machines(PRAM)*はモデルであり、ほとんどの並列アルゴリズムで考慮されています。 ここでは、複数のプロセッサがメモリの単一ブロックに接続されています。 PRAMモデルには以下が含まれます-
- 同様のタイプのプロセッサーのセット。
- すべてのプロセッサは、共通のメモリユニットを共有します。 プロセッサは、共有メモリを介してのみ相互に通信できます。
- メモリアクセスユニット(MAU)は、プロセッサを単一の共有メモリに接続します。
ここで、 n 個のプロセッサは、特定の時間単位で n 個のデータに対して独立した操作を実行できます。 これにより、異なるプロセッサが同じメモリ位置に同時にアクセスする可能性があります。
この問題を解決するために、次の制約がPRAMモデルに適用されています-
- * Exclusive Read Exclusive Write(EREW)*-ここでは、2つのプロセッサが同じメモリ位置から同時に読み書きすることはできません。
- 排他的読み取り同時書き込み(ERCW)-ここでは、2つのプロセッサが同じメモリ位置から同時に読み取ることはできませんが、同じメモリ位置に同時に書き込むことはできません。
- 同時読み取り排他書き込み(CREW)-ここでは、すべてのプロセッサが同じメモリ位置から同時に読み取ることができますが、同じメモリ位置に同時に書き込むことはできません。
- 同時読み取り同時書き込み(CRCW)-すべてのプロセッサは、同じメモリ位置から同時に読み取りまたは書き込みを行うことができます。
PRAMモデルを実装する多くの方法がありますが、最も顕著なものは次のとおりです-
- 共有メモリモデル
- メッセージパッシングモデル
- データ並列モデル
共有メモリモデル
共有メモリは、 data parallelism よりも control parallelism を重視しています。 共有メモリモデルでは、複数のプロセスが異なるプロセッサで独立して実行されますが、共通のメモリ空間を共有します。 プロセッサのアクティビティにより、メモリの場所に変更があった場合、残りのプロセッサから見えるようになります。
複数のプロセッサが同じメモリロケーションにアクセスするため、特定の時点で、複数のプロセッサが同じメモリロケーションにアクセスすることがあります。 1人がその場所を読み取り、もう1人がその場所に書き込みを行っているとします。 混乱を招く可能性があります。 これを回避するために、 lock/semaphore などの制御メカニズムを実装して、相互排除を保証します。
共有メモリプログラミングは次のように実装されています-
- スレッドライブラリ-スレッドライブラリは、同じメモリ位置で同時に実行される複数の制御スレッドを許可します。 スレッドライブラリは、サブルーチンのライブラリを介してマルチスレッドをサポートするインターフェイスを提供します。 サブルーチンが含まれています
- スレッドの作成と破棄
- スレッドの実行のスケジューリング
- スレッド間でデータとメッセージを渡す
- スレッドコンテキストの保存と復元
スレッドライブラリの例には、Solaris用のSolarisTMスレッド、Linuxで実装されたPOSIXスレッド、Windows NTおよびWindows 2000で使用可能なWin32スレッド、標準JavaTM Development Kit(JDK)の一部としてのJavaTMスレッドが含まれます。
- 分散共有メモリ(DSM)システム-DSMシステムは、ハードウェアサポートなしで共有メモリプログラミングを実装するために、疎結合アーキテクチャで共有メモリの抽象化を作成します。 標準ライブラリを実装し、最新のオペレーティングシステムに存在する高度なユーザーレベルのメモリ管理機能を使用します。 例には、Tread Marks System、Munin、IVY、Shasta、Brazos、Cashmereが含まれます。
- プログラム注釈パッケージ-これは、均一なメモリアクセス特性を持つアーキテクチャに実装されています。 プログラム注釈パッケージの最も注目すべき例は、OpenMPです。 OpenMPは機能的な並列処理を実装しています。 主にループの並列化に焦点を当てています。
共有メモリの概念は、共有メモリシステムの低レベルの制御を提供しますが、退屈で誤っている傾向があります。 アプリケーションプログラミングよりもシステムプログラミングに適しています。
共有メモリプログラミングのメリット
- グローバルアドレス空間は、メモリに対するユーザーフレンドリーなプログラミングアプローチを提供します。
- メモリはCPUに近いため、プロセス間のデータ共有は高速で均一です。
- プロセス間でデータの通信を明確に指定する必要はありません。
- プロセス通信のオーバーヘッドは無視できます。
- 学ぶのはとても簡単です。
共有メモリプログラミングのデメリット
- ポータブルではありません。
- データの局所性の管理は非常に困難です。
メッセージパッシングモデル
メッセージパッシングは、分散メモリシステムで最も一般的に使用される並列プログラミングアプローチです。 ここでは、プログラマーが並列処理を決定する必要があります。 このモデルでは、すべてのプロセッサに独自のローカルメモリユニットがあり、通信ネットワークを介してデータを交換します。
プロセッサは、メッセージパッシングライブラリを使用して、プロセッサ間の通信を行います。 送信されるデータとともに、メッセージには次のコンポーネントが含まれます-
- メッセージの送信元のプロセッサのアドレス。
- 送信プロセッサのデータのメモリ位置の開始アドレス。
- 送信データのデータ型。
- 送信データのデータサイズ。
- メッセージの送信先のプロセッサのアドレス。
- 受信プロセッサのデータのメモリ位置の開始アドレス。
プロセッサは、次のいずれかの方法で相互に通信できます-
- ポイントツーポイント通信
- 集団コミュニケーション
- メッセージパッシングインターフェース
ポイントツーポイント通信
ポイントツーポイント通信は、メッセージパッシングの最も単純な形式です。 ここでは、次の転送モードのいずれかによって、メッセージを送信プロセッサから受信プロセッサに送信できます-
- 同期モード-次のメッセージは、メッセージのシーケンスを維持するために、前のメッセージが配信されたことの確認を受信した後にのみ送信されます。
- 非同期モード-次のメッセージを送信するには、前のメッセージの配信確認の受信は必要ありません。
集団コミュニケーション
集団通信では、メッセージの受け渡しに3つ以上のプロセッサが必要です。 次のモードは、集団通信を可能にします-
- バリア-通信に含まれるすべてのプロセッサがメッセージパッシングのために特定のブロック(バリアブロック)を実行している場合、バリアモードが可能です。
- ブロードキャスト-ブロードキャストには2つのタイプがあります-
- One-to-all -ここでは、1つの操作を持つ1つのプロセッサが他のすべてのプロセッサに同じメッセージを送信します。
- All-to-All -ここでは、すべてのプロセッサが他のすべてのプロセッサにメッセージを送信します。
ブロードキャストされるメッセージには3つのタイプがあります-
- Personalized -他のすべての宛先プロセッサに一意のメッセージが送信されます。
- 非パーソナライズ-すべての宛先プロセッサが同じメッセージを受け取ります。
- リダクション-リダクションブロードキャストでは、グループの1つのプロセッサがグループ内の他のすべてのプロセッサからすべてのメッセージを収集し、グループ内の他のすべてのプロセッサがアクセスできる単一のメッセージに結合します。
メッセージパッシングのメリット
- 並列性の低レベル制御を提供します。
- ポータブルです。
- エラーが発生しにくい。
- 並列同期とデータ配布のオーバーヘッドが少なくなります。
メッセージパッシングのデメリット
- 並列共有メモリコードと比較して、メッセージパッシングコードは一般により多くのソフトウェアオーバーヘッドを必要とします。
メッセージパッシングライブラリ
多くのメッセージパッシングライブラリがあります。 ここでは、最もよく使用される2つのメッセージパッシングライブラリについて説明します-
- メッセージパッシングインターフェース(MPI) *並列仮想マシン(PVM)
メッセージパッシングインターフェース(MPI)
分散メモリシステム内のすべての並行プロセス間で通信を提供することは、普遍的な標準です。 一般的に使用される並列コンピューティングプラットフォームのほとんどは、メッセージパッシングインターフェイスの少なくとも1つの実装を提供します。* library *と呼ばれる定義済み関数のコレクションとして実装されており、C、C ++、Fortranなどの言語から呼び出すことができます。 MPIは、他のメッセージパッシングライブラリと比較して高速で移植性があります。
メッセージパッシングインターフェイスのメリット
- 共有メモリアーキテクチャまたは分散メモリアーキテクチャでのみ実行されます。
- 各プロセッサには独自のローカル変数があります。
- 大規模な共有メモリコンピュータと比較して、分散メモリコンピュータは安価です。
メッセージパッシングインターフェースのデメリット
- 並列アルゴリズムには、さらにプログラミングを変更する必要があります。
- デバッグが難しい場合があります。そして
- ノード間の通信ネットワークではうまく機能しません。
並列仮想マシン(PVM)
PVMは、個別の異種ホストマシンを接続して単一の仮想マシンを形成するように設計された、ポータブルなメッセージパッシングシステムです。 これは、単一の管理可能な並列コンピューティングリソースです。 超伝導研究、分子動力学シミュレーション、マトリックスアルゴリズムなどの大規模な計算上の問題は、多くのコンピューターのメモリと総処理能力を使用することで、よりコスト効率よく解決できます。 互換性のないコンピューターアーキテクチャのネットワークで、すべてのメッセージルーティング、データ変換、タスクスケジューリングを管理します。
- PVMの機能*
- インストールと設定が非常に簡単です。
- 複数のユーザーが同時にPVMを使用できます。
- 1人のユーザーが複数のアプリケーションを実行できます。
- それは小さなパッケージです。
- C、C ++、Fortranをサポート。
- PVMプログラムの所定の実行について、ユーザーはマシンのグループを選択できます。
- これはメッセージパッシングモデルです。
- プロセスベースの計算。
- 異種アーキテクチャをサポートします。
データ並列プログラミング
データ並列プログラミングモデルの主な焦点は、データセットの操作を同時に実行することです。 データセットは、配列、ハイパーキューブなどの構造に編成されます。 プロセッサは、同じデータ構造に対して操作をまとめて実行します。 各タスクは、同じデータ構造の異なるパーティションで実行されます。
すべてのアルゴリズムをデータ並列性の観点から指定できるわけではないため、制限的です。 これが、データの並列性が普遍的でない理由です。
データ並列言語は、データの分解とプロセッサへのマッピングを指定するのに役立ちます。 また、プログラマがデータ(たとえば、どのデータをどのプロセッサに送信するか)を制御して、プロセッサ内の通信量を削減できるようにするデータ配布ステートメントも含まれています。
並列アルゴリズム-構造
アルゴリズムを適切に適用するには、適切なデータ構造を選択することが非常に重要です。 これは、データ構造で実行される特定の操作は、別のデータ構造で実行される同じ操作と比較して時間がかかる可能性があるためです。
例-配列を使用してセット内のi ^ th ^要素にアクセスするには一定の時間がかかりますが、リンクリストを使用すると、同じ操作を実行するのに必要な時間が多項式になる場合があります。
したがって、データ構造の選択は、実行するアーキテクチャと操作の種類を考慮して行う必要があります。
以下のデータ構造は、並列プログラミングで一般的に使用されます-
- リンクリスト
- 配列
- ハイパーキューブネットワーク
リンクリスト
リンクリストは、ポインターで接続された0個以上のノードを持つデータ構造です。 ノードは、連続したメモリ位置を占有する場合と占有しない場合があります。 各ノードには2つまたは3つの部分があります。1つはデータを格納する*データ部分*で、残りの2つは前または次のノードのアドレスを格納する*リンクフィールド*です。 最初のノードのアドレスは、 head と呼ばれる外部ポインターに保存されます。 * tail、*と呼ばれる最後のノードには、通常、アドレスが含まれていません。
リンクリストには3種類あります-
- 単一リンクリスト
- 二重リンクリスト *循環リンクリスト
単一リンクリスト
片方向リンクリストのノードには、データと次のノードのアドレスが含まれます。* head *と呼ばれる外部ポインターは、最初のノードのアドレスを保存します。
二重リンクリスト
二重リンクリストのノードには、前のノードと次のノードの両方のデータとアドレスが含まれます。 head と呼ばれる外部ポインターは最初のノードのアドレスを保存し、 tail と呼ばれる外部ポインターは最後のノードのアドレスを保存します。
循環リンクリスト
循環リンクリストは、最後のノードが最初のノードのアドレスを保存したという事実を除いて、単一リンクリストに非常に似ています。
配列
配列は、同様のタイプのデータを格納できるデータ構造です。 1次元でも多次元でもかまいません。 配列は静的または動的に作成できます。
- *静的に宣言された配列*では、コンパイル時に配列の次元とサイズがわかります。
- *動的に宣言された配列*では、実行時に配列の次元とサイズがわかります。
共有メモリプログラミングの場合、アレイは共通メモリとして使用でき、データ並列プログラミングの場合は、サブアレイに分割して使用できます。
ハイパーキューブネットワーク
Hypercubeアーキテクチャは、各タスクが他のタスクと通信する必要がある並列アルゴリズムに役立ちます。 ハイパーキューブトポロジは、リングやメッシュなどの他のトポロジを簡単に埋め込むことができます。 nキューブとも呼ばれます。 n は次元数です。 ハイパーキューブは再帰的に構築できます。
画像:/parallel_algorithm/images/hypercube.jpg [Hypercube]画像:/parallel_algorithm/images/hypercube1.jpg [Hypercube 1]
並列アルゴリズム-設計手法
並列アルゴリズムに適した設計手法を選択することは、最も困難で重要なタスクです。 並列プログラミングの問題のほとんどには、複数の解決策があります。 この章では、並列アルゴリズムの次の設計手法について説明します-
- 分割統治
- 貪欲な方法
- 動的計画法
- バックトラッキング
- 分岐とバインド
- 線形計画
分割統治法
分割統治アプローチでは、問題はいくつかの小さな副問題に分割されます。 次に、副問題が再帰的に解決され、元の問題の解決策を得るために結合されます。
分割統治アプローチには、各レベルで次の手順が含まれます-
- 分割-元の問題はサブ問題に分割されます。
- 征服-副問題は再帰的に解決されます。
- 結合-副問題の解決策を組み合わせて、元の問題の解決策を取得します。
分割統治アプローチは、次のアルゴリズムに適用されます-
- 二分検索
- クイックソート
- ソートをマージ
- 整数乗算
- マトリックス反転
- 行列乗算
貪欲な方法
最適化ソリューションの貪欲なアルゴリズムでは、いつでも最適なソリューションが選択されます。 貪欲なアルゴリズムは、複雑な問題に非常に簡単に適用できます。 次のステップで最も正確なソリューションを提供するステップを決定します。
このアルゴリズムは greedy と呼ばれます。これは、小さいインスタンスに対する最適なソリューションが提供されると、アルゴリズムがプログラム全体を考慮しないためです。 解決策が考慮されると、貪欲なアルゴリズムは同じ解決策を再度考慮しません。
貪欲なアルゴリズムは、可能な限り小さいコンポーネントパーツからオブジェクトのグループを再帰的に作成します。 再帰は、特定の問題の解決策がその問題の小さなインスタンスの解決策に依存する問題を解決する手順です。
動的計画法
ダイナミックプログラミングは最適化手法であり、問題をより小さなサブ問題に分割し、各サブ問題を解決した後、ダイナミックプログラミングはすべてのソリューションを組み合わせて究極のソリューションを取得します。 分割統治法とは異なり、動的プログラミングでは、サブ問題に対するソリューションを何度も再利用します。
フィボナッチ数列の再帰アルゴリズムは、動的プログラミングの例です。
バックトラッキングアルゴリズム
バックトラッキングは、組み合わせの問題を解決する最適化手法です。 これは、プログラムの問題と現実の問題の両方に適用されます。 8つのクイーンの問題、数独パズル、迷路を進むことは、バックトラッキングアルゴリズムが使用される一般的な例です。
バックトラッキングでは、考えられるすべての条件を満たすソリューションから始めます。 次に、次のレベルに移動し、そのレベルで満足のいく解決策が得られない場合は、1つのレベルに戻り、新しいオプションから始めます。
分岐とバインド
分岐限定アルゴリズムは、問題の最適な解決策を得るための最適化手法です。 解決策の全領域で、与えられた問題に対する最適な解決策を探します。 最適化される関数の境界は、最新の最適なソリューションの値とマージされます。 これにより、アルゴリズムは解空間の一部を完全に見つけることができます。
分岐限定検索の目的は、ターゲットへの最低コストのパスを維持することです。 ソリューションが見つかると、ソリューションを改善し続けることができます。 分岐限定検索は、深さ限定検索および深さ優先検索で実装されます。
線形計画
線形計画法は、最適化基準と制約の両方が線形関数である幅広いクラスの最適化ジョブを表します。 これは、最大の利益、最短の経路、または最低のコストなど、最高の結果を得るための手法です。
このプログラミングでは、変数のセットがあり、それらに絶対値を割り当てて、線形方程式のセットを満たし、与えられた線形目的関数を最大化または最小化する必要があります。
並列アルゴリズム-行列乗算
マトリックスは、固定数の行と列に配置された数値データと非数値データのセットです。 行列乗算は、並列計算における重要な乗算設計です。 ここでは、メッシュやハイパーキューブなどのさまざまな通信ネットワークでの行列乗算の実装について説明します。 メッシュとハイパーキューブはネットワーク接続性が高いため、リングネットワークなどの他のネットワークよりも高速なアルゴリズムを使用できます。
メッシュネットワーク
ノードのセットがp次元グリッドを形成するトポロジは、メッシュトポロジと呼ばれます。 ここでは、すべてのエッジがグリッド軸に平行であり、すべての隣接ノードが相互に通信できます。
ノードの合計数=(行のノード数)×(列のノード数)
メッシュネットワークは、次の要因を使用して評価することができます-
- 直径
- 分割幅
直径-メッシュネットワークでは、2つのノード間の最長*距離*は直径です。 kP ノードを持つp次元メッシュネットワークの直径は* p(k–1)*です。
- 2分割幅*-2分割幅は、メッシュネットワークを2つの半分に分割するためにネットワークから削除する必要があるエッジの最小数です。
メッシュネットワークを使用した行列乗算
ラップアラウンド接続を持つ2DメッシュネットワークSIMDモデルを検討しました。 特定の時間内にn ^ 2 ^プロセッサを使用して2つのn×n配列を乗算するアルゴリズムを設計します。
行列AとBにはそれぞれ要素a〜ij〜とb〜ij〜があります。 処理要素PE〜ij〜は、a〜ij〜およびb〜ij〜を表します。 すべてのプロセッサに乗算する要素のペアがあるように、行列AとBを配置します。 マトリックスAの要素は左方向に移動し、マトリックスBの要素は上方向に移動します。 マトリックスAおよびBの要素の位置のこれらの変更は、各処理要素PE、乗算する値の新しいペアを表します。
アルゴリズムのステップ
- 2つの行列をずらします。
- すべての製品を計算、a〜ik〜×b〜kj〜
- ステップ2が完了したら、合計を計算します。
アルゴリズム
Procedure MatrixMulti
Begin
for k = 1 to n-1
for all Pij; where i and j ranges from 1 to n
ifi is greater than k then
rotate a in left direction
end if
if j is greater than k then
rotate b in the upward direction
end if
for all Pij ; where i and j lies between 1 and n
compute the product of a and b and store it in c
for k= 1 to n-1 step 1
for all Pi;j where i and j ranges from 1 to n
rotate a in left direction
rotate b in the upward direction
c=c+aXb
End
ハイパーキューブネットワーク
ハイパーキューブは、エッジが互いに垂直で、同じ長さのn次元の構造です。 n次元ハイパーキューブは、nキューブまたはn次元キューブとも呼ばれます。
2 ^ k ^ノードを持つHypercubeの機能
- 直径= k
- 分割幅= 2 ^ k–1 ^
- エッジの数= k
Hypercube Networkを使用した行列乗算
Hypercubeネットワークの一般仕様-
- N = 2 ^ m ^ をプロセッサの総数とします。 プロセッサをP〜0、〜P〜1〜…..P〜N-1〜とします。
- iとi ^ b ^を2つの整数、0 <i、i ^ b ^ <N-1とし、そのバイナリ表現は位置b、0 <b <k–1でのみ異なります。
- 2つのn×n行列、行列Aと行列Bを考えてみましょう。
- *ステップ1 *-行列Aおよび行列Bの要素は、位置i、j、kのプロセッサがa〜ji〜およびb〜ik〜を持つようにn ^ 3 ^プロセッサに割り当てられます。
- *ステップ2 *-位置(i、j、k)にあるすべてのプロセッサが積を計算します + C(i、j、k)= A(i、j、k)×B(i、j、k)
- *ステップ3 *-合計C(0、j、k)=ΣC(i、j、k)、0≤i≤n-1、ここで0≤j、k <n–1。
ブロックマトリックス
ブロックマトリックスまたはパーティションマトリックスは、各要素自体が個々のマトリックスを表すマトリックスです。 これらの個々のセクションは、*ブロック*または*サブマトリックス*として知られています。
例
図(a)で、Xはブロック行列で、A、B、C、Dはそれ自体の行列です。 図(f)は、マトリックス全体を示しています。
ブロック行列乗算
2つのブロック行列が正方行列である場合、単純な行列乗算を実行する方法で乗算されます。 例えば、
並列アルゴリズム-ソート
並べ替えは、特定の順序、つまり昇順、降順、アルファベット順などでグループ内の要素を配置するプロセスです。 ここでは、以下について説明します-
- 列挙ソート
- 奇偶転置ソート
- 並列マージソート
- ハイパークイックソート
要素のリストのソートは非常に一般的な操作です。 大量のデータをソートする必要がある場合、順次ソートアルゴリズムは十分に効率的ではない場合があります。 したがって、並べ替えには並列アルゴリズムが使用されます。
列挙ソート
列挙ソートは、ソートされたリスト内の各要素の最終位置を見つけることにより、リスト内のすべての要素を配置する方法です。 これは、各要素を他のすべての要素と比較し、値の小さい要素の数を見つけることによって行われます。
したがって、任意の2つの要素、a〜i〜およびa〜j〜については、次のいずれかの場合に該当する必要があります-
- a〜i〜<a〜j〜
- a〜i〜> a〜j〜
- a〜i〜= a〜j〜
アルゴリズム
procedure ENUM_SORTING (n)
begin
for each process P1,j do
C[j] := 0;
for each process Pi, j do
if (A[i] < A[j]) or A[i] = A[j] and i < j) then
C[j] := 1;
else
C[j] := 0;
for each process P1, j do
A[C[j]] := A[j];
end ENUM_SORTING
奇偶転置ソート
奇偶転置ソートは、バブルソート手法に基づいています。 最初の番号が2番目の番号よりも大きい場合、2つの隣接する番号を比較して、昇順リストを取得します。 逆の場合は、降順のシリーズに適用されます。 奇数-偶数転置ソートは、*奇数フェーズ*と*偶数フェーズ*の2つのフェーズで動作します。 両方のフェーズで、プロセスは番号を隣接する右側の番号と交換します。
アルゴリズム
procedure ODD-EVEN_PAR (n)
begin
id := process's label
for i := 1 to n do
begin
if i is odd and id is odd then
compare-exchange_min(id + 1);
else
compare-exchange_max(id - 1);
if i is even and id is even then
compare-exchange_min(id + 1);
else
compare-exchange_max(id - 1);
end for
end ODD-EVEN_PAR
並列マージソート
マージソートは、最初にソートされていないリストを可能な限り小さいサブリストに分割し、隣接するリストと比較して、ソートされた順序でマージします。 分割統治アルゴリズムに従って並列処理を非常にうまく実装します。
アルゴリズム
procedureparallelmergesort(id, n, data, newdata)
begin
data = sequentialmergesort(data)
for dim = 1 to n
data = parallelmerge(id, dim, data)
endfor
newdata = data
end
ハイパークイックソート
ハイパークイックソートは、ハイパーキューブでのクイックソートの実装です。 その手順は次のとおりです-
- ソートされていないリストを各ノードに分割します。
- 各ノードをローカルで並べ替えます。
- ノード0から、中央値をブロードキャストします。
- 各リストをローカルで分割し、次に最大次元で半分を交換します。
- 次元が0に達するまで、ステップ3と4を並行して繰り返します。
アルゴリズム
procedure HYPERQUICKSORT (B, n)
begin
id := process’s label;
for i := 1 to d do
begin
x := pivot;
partition B into B1 and B2 such that B1 ≤ x < B2;
if ith bit is 0 then
begin
send B2 to the process along the ith communication link;
C := subsequence received along the ith communication link;
B := B1 U C;
endif
else
send B1 to the process along the ith communication link;
C := subsequence received along the ith communication link;
B := B2 U C;
end else
end for
sort B using sequential quicksort;
end HYPERQUICKSORT
並列検索アルゴリズム
検索は、コンピューターサイエンスの基本的な操作の1つです。 要素が指定されたリストにあるかどうかを見つける必要があるすべてのアプリケーションで使用されます。 この章では、次の検索アルゴリズムについて説明します-
- 分割統治
- 深さ優先検索
- 幅優先検索
- ベストファースト検索
分割統治
分割統治アプローチでは、問題はいくつかの小さなサブ問題に分割されます。 次に、副問題が再帰的に解決され、元の問題の解決策を得るために結合されます。
分割統治アプローチには、各レベルで次の手順が含まれます-
- 分割-元の問題はサブ問題に分割されます。
- 征服-副問題は再帰的に解決されます。
- 結合-サブ問題の解決策を組み合わせて、元の問題の解決策を取得します。
バイナリ検索は、分割統治アルゴリズムの例です。
疑似コード
Binarysearch(a, b, low, high)
if low < high then
return NOT FOUND
else
mid ← (low+high)/2
if b = key(mid) then
return key(mid)
else if b < key(mid) then
return BinarySearch(a, b, low, mid−1)
else
return BinarySearch(a, b, mid+1, high)
深さ優先検索
深さ優先検索(またはDFS)は、ツリーまたは無向グラフのデータ構造を検索するためのアルゴリズムです。 ここでのコンセプトは、 root と呼ばれる開始ノードから開始し、同じブランチ内で可能な限りトラバースすることです。 後続ノードのないノードを取得した場合、まだアクセスされていない頂点に戻って続行します。
深さ優先検索の手順
- 以前にアクセスされていないノード(ルート)を検討し、アクセス済みとしてマークします。
- 最初の隣接する後続ノードにアクセスし、訪問済みとしてマークします。
- 考慮されたノードのすべての後続ノードが既にアクセスされているか、後続ノードがこれ以上ない場合は、その親ノードに戻ります。
疑似コード
グラフ G で検索を開始する頂点を v とします。
DFS(G,v)
Stack S := {};
for each vertex u, set visited[u] := false;
push S, v;
while (S is not empty) do
u := pop S;
if (not visited[u]) then
visited[u] := true;
for each unvisited neighbour w of u
push S, w;
end if
end while
END DFS()
幅優先検索
幅優先検索(またはBFS)は、ツリーまたは無向グラフデータ構造を検索するためのアルゴリズムです。 ここでは、ノードから開始して、同じレベルのすべての隣接ノードを訪問し、次のレベルの隣接する後続ノードに移動します。 これは、*レベルごとの検索*とも呼ばれます。
幅優先検索の手順
- ルートノードから開始し、訪問済みとしてマークします。
- ルートノードには同じレベルのノードがないため、次のレベルに進みます。
- 隣接するすべてのノードを訪問し、訪問済みとしてマークします。
- 次のレベルに移動し、未訪問のすべての隣接ノードにアクセスします。
- すべてのノードが訪問されるまで、このプロセスを続けます。
疑似コード
グラフ G で検索を開始する頂点を v とします。
BFS(G,v)
Queue Q := {};
for each vertex u, set visited[u] := false;
insert Q, v;
while (Q is not empty) do
u := delete Q;
if (not visited[u]) then
visited[u] := true;
for each unvisited neighbor w of u
insert Q, w;
end if
end while
END BFS()
ベストファースト検索
Best-First Searchは、グラフを横断して最短距離でターゲットに到達するアルゴリズムです。 BFSやDFSとは異なり、Best-First Searchは評価関数に従って、次に通過するのに最も適切なノードを決定します。
ベストファースト検索の手順
- ルートノードから開始し、訪問済みとしてマークします。
- 次の適切なノードを見つけて、訪問済みとしてマークします。
- 次のレベルに進み、適切なノードを見つけて、訪問済みとしてマークします。
- 目標に達するまでこのプロセスを続けます。
疑似コード
BFS( m )
Insert( m.StartNode )
Until PriorityQueue is empty
c ← PriorityQueue.DeleteMin
If c is the goal
Exit
Else
Foreach neighbor n of c
If n "Unvisited"
Mark n "Visited"
Insert( n )
Mark c "Examined"
End procedure
グラフアルゴリズム
グラフは、オブジェクトのペア間の接続を表すために使用される抽象的な表記です。 グラフはで構成されます-
- 頂点-グラフ内の相互接続されたオブジェクトは頂点と呼ばれます。 頂点は*ノード*とも呼ばれます。
- エッジ-エッジは、頂点を接続するリンクです。
グラフには2種類あります-
- 有向グラフ-有向グラフでは、エッジには方向があります。つまり、エッジはある頂点から別の頂点に移動します。
- 無向グラフ-無向グラフでは、エッジには方向がありません。
グラフの色付け
グラフの色付けは、隣接する2つの頂点が同じ色にならないように、グラフの頂点に色を割り当てる方法です。 いくつかのグラフの色の問題は-
- 頂点カラーリング-隣接する2つの頂点が同じ色を共有しないようにグラフの頂点をカラーリングする方法。
- Edge Coloring -2つの隣接するエッジが同じ色を持たないように、各エッジに色を割り当てる方法です。
- 顔の色-平面グラフの各面または領域に色を割り当て、共通の境界を共有する2つの面が同じ色を持たないようにします。
色数
色数は、グラフの色に必要な色の最小数です。 たとえば、次のグラフの色数は3です。
グラフの色付けの概念は、時刻表、モバイル無線周波数の割り当て、Suduku、レジスタ割り当て、およびマップの色付けの準備に適用されます。
グラフの色付けの手順
- n次元配列の各プロセッサーの初期値を1に設定します。
- 次に、特定の色を頂点に割り当てるには、その色が既に隣接する頂点に割り当てられているかどうかを判断します。
- プロセッサが隣接する頂点で同じ色を検出した場合、配列の値を0に設定します。
- n ^ 2 ^比較を行った後、配列の要素が1である場合、それは有効なカラーリングです。
グラフの色付けのための擬似コード
begin
create the processors P(i0,i1,...in-1) where 0_iv < m, 0 _ v < n
status[i0,..in-1] = 1
for j varies from 0 to n-1 do
begin
for k varies from 0 to n-1 do
begin
if aj,k=1 and ij=ikthen
status[i0,..in-1] =0
end
end
ok = ΣStatus
if ok > 0, then display valid coloring exists
else
display invalid coloring
end
最小スパニングツリー
すべてのエッジの重み(または長さ)の合計がグラフGの他のすべての可能なスパニングツリーよりも小さいスパニングツリーは、*最小スパニングツリー*または*最小コストスパニング*ツリーとして知られています。 次の図は、重み付き連結グラフを示しています。
上記のグラフのいくつかの可能なスパニングツリーは以下に示されています-
Spanning Tree Spanning Tree 1 Spanning Tree 2 Minimum Spanning Tree Spanning Tree 3 Spanning Tree 4 スパニングツリー5
上記のすべてのスパニングツリーの中で、図(d)は最小スパニングツリーです。 最小コストスパニングツリーの概念は、巡回セールスマン問題、電子回路の設計、効率的なネットワークの設計、効率的なルーティングアルゴリズムの設計に適用されます。
最小コストスパンニングツリーを実装するには、次の2つの方法が使用されます-
- プリムのアルゴリズム
- クラスカルのアルゴリズム
プリムのアルゴリズム
プリムのアルゴリズムは貪欲なアルゴリズムであり、重み付き無向グラフの最小スパニングツリーを見つけるのに役立ちます。 最初に頂点を選択し、その頂点に最小の重みを持つエッジを見つけます。
プリムのアルゴリズムの手順
- グラフGのv〜1〜などの頂点を選択します。
- エッジを選択します。たとえば、Gのe〜1〜は、e〜1〜= v〜1〜v〜2〜およびv〜1〜≠v〜2〜であり、e〜1〜はvに入射するエッジの中で最小の重みを持ちます。グラフGの〜1〜
- ここで、ステップ2に続いて、v〜2〜の最小加重エッジインシデントを選択します。
- n–1個のエッジが選択されるまでこれを続けます。 ここで、 n は頂点の数です。
最小スパニングツリーは-
Prim’s Algorithm Minimum Spanning Tree
クラスカルのアルゴリズム
Kruskalのアルゴリズムは貪欲なアルゴリズムであり、接続された重み付きグラフの最小スパニングツリーを見つけるのに役立ち、各ステップでコストアークが増加します。 これは、フォレスト内の2つのツリーを接続する最小の重みのエッジを見つける最小スパンニングツリーアルゴリズムです。
クラスカルのアルゴリズムの手順
- 最小重量のエッジを選択します。 Graph Gのe〜1〜とe〜1〜はループではないとします。
- e〜1〜に接続されている次の最小重み付きエッジを選択します。
- n–1個のエッジが選択されるまでこれを続けます。 ここで、 n は頂点の数です。
上記のグラフの最小全域木は-
最短経路アルゴリズム
最短パスアルゴリズムは、ソースノード(S)から宛先ノード(D)への最小コストパスを見つける方法です。 ここでは、Breadth First Search Algorithmとしても知られるMooreのアルゴリズムについて説明します。
ムーアのアルゴリズム
- ソース頂点Sにラベルを付け、 i にラベルを付け、 i = 0 に設定します。
- i というラベルの付いた頂点に隣接するラベルのないすべての頂点を見つけます。 頂点Sに頂点が接続されていない場合、頂点DはSに接続されません。 Sに接続されている頂点がある場合、それらに i + 1 というラベルを付けます。
- Dにラベルが付いている場合は、ステップ4に進み、そうでない場合は、ステップ2に進んでi = i + 1を増やします。
- 最短パスの長さが見つかったら停止します。