ホームページ >バックエンド開発 >PHPチュートリアル >PHP アルゴリズム設計のヒント: ベルマン・フォード アルゴリズムを使用して単一ソースの最短パス問題を解決するにはどうすればよいですか?

PHP アルゴリズム設計のヒント: ベルマン・フォード アルゴリズムを使用して単一ソースの最短パス問題を解決するにはどうすればよいですか?

PHPz
PHPzオリジナル
2023-09-19 11:30:14686ブラウズ

PHP アルゴリズム設計のヒント: ベルマン・フォード アルゴリズムを使用して単一ソースの最短パス問題を解決するにはどうすればよいですか?

PHP アルゴリズム設計のヒント: 単一ソースの最短パス問題を解決するために Bellman-Ford アルゴリズムを使用する方法

概要:
Bellman-Ford アルゴリズムは、グラフ内の単一ソース最短経路問題を解決するための古典的なアルゴリズムです。負の重みエッジを持つグラフを処理でき、負の重みサイクルの存在を検出できます。この記事では、PHP を使用して Bellman-Ford アルゴリズムを実装する方法とコード例を紹介します。

背景知識:
ベルマン・フォード アルゴリズムを深く理解する前に、グラフ理論の基本的な知識を理解する必要があります。

  1. グラフの表現:
    グラフはノード(頂点)とエッジ(辺)で構成されます。ノードは数値または文字列として表現でき、エッジは 2 つのノードと重み情報を含むタプルとして表現できます。
  2. グラフ表現方法:
    隣接行列と隣接リストは、2 つの一般的なグラフ表現方法です。
  3. 隣接行列: ノード間の接続関係を 2 次元配列で表します。ノード i とノード j の間にエッジがある場合、隣接行列の i 行、j 列の値がエッジの重みとなり、エッジがない場合、この位置の値は無限大 (inf) になります。
  4. 隣接リスト: 各ノードについて、リンク リストを使用して、ノードに接続されているエッジに関する情報を保存します。
  5. 単一ソース最短パス問題:
    有向グラフが与えられた場合、1 つのソース ノードから他のすべてのノードへの最短パスを見つけます。

Bellman-Ford アルゴリズムの実装:
以下は、PHP を使用して Bellman-Ford アルゴリズムを実装するサンプル コードです:

<?php

class Graph {
    private $vertices;
    private $edges;

    public function __construct($vertices) {
        $this->vertices = $vertices;
        $this->edges = [];
    }

    public function addEdge($start, $end, $weight) {
        $this->edges[] = [$start, $end, $weight];
    }

    public function bellmanFord($source) {
        $distance = [];
        $predecessor = [];

        // 设置源节点到其他所有节点的初始距离为无穷大
        foreach ($this->vertices as $vertex) {
            $distance[$vertex] = INF;
            $predecessor[$vertex] = null;
        }

        $distance[$source] = 0;

        // 对每个节点进行松弛操作
        for ($i = 0; $i < count($this->vertices) - 1; $i++) {
            foreach ($this->edges as $edge) {
                $u = $edge[0];
                $v = $edge[1];
                $w = $edge[2];

                if ($distance[$u] != INF && $distance[$u] + $w < $distance[$v]) {
                    $distance[$v] = $distance[$u] + $w;
                    $predecessor[$v] = $u;
                }
            }
        }

        // 检测负权环
        foreach ($this->edges as $edge) {
            $u = $edge[0];
            $v = $edge[1];
            $w = $edge[2];

            if ($distance[$u] != INF && $distance[$u] + $w < $distance[$v]) {
                echo "图中存在负权环";
                return;
            }
        }

        // 输出最短路径结果
        foreach ($this->vertices as $vertex) {
            echo "节点" . $vertex . "的最短路径长度为: " . $distance[$vertex] . ",路径为: ";
            $path = [];
            $current = $vertex;

            while ($current != $source) {
                array_unshift($path, $current);
                $current = $predecessor[$current];
            }

            array_unshift($path, $source);
            echo implode(" -> ", $path) . "
";
        }
    }
}

$graph = new Graph(["A", "B", "C", "D", "E"]);
$graph->addEdge("A", "B", 4);
$graph->addEdge("A", "C", 1);
$graph->addEdge("C", "B", -3);
$graph->addEdge("B", "D", 2);
$graph->addEdge("D", "E", 3);
$graph->addEdge("E", "D", -5);

$graph->bellmanFord("A");

コード分析:
まず、 Graph クラスは、ノードとエッジの情報を含むグラフを表します。グラフのエッジ情報はedges配列に格納されます。

addEdge メソッドを使用してエッジ情報を追加します。

bellmanFord メソッドは、Bellman-Ford アルゴリズムを実装します。まず、距離配列と先行ノード配列を初期化します。次に、ソース ノードの距離を 0 に設定します。次に、各ノードで V-1 サイクルを実行します。ここで、V はノードの数です。ループ内で各エッジをチェックし、より短いパスが存在する場合はエッジを緩和します。最後に、負の体重サイクルがあるかどうかを確認し、存在する場合はプロンプト メッセージを出力します。最後に、各ノードの最短パスとパス長を出力します。

サンプル コードでは、いくつかの正と負の重みエッジを含む 5 つのノードを含むグラフを作成します。最後に、「A」をソース ノードとして使用する bellmanFord メソッドを使用して、最短パスを計算します。

概要:
この記事では、PHP を使用してベルマン・フォード アルゴリズムを実装し、グラフ内の単一ソース最短経路問題を解決する方法を紹介します。 Bellman-Ford アルゴリズムは、負の重みエッジを含むグラフに適しており、負の重みサイクルの存在を検出できます。グラフの表現方法を理解し、ベルマン・フォードアルゴリズムの原理を理解し、サンプルコードで実践することで、アルゴリズムへの理解がさらに深まると思います。

以上がPHP アルゴリズム設計のヒント: ベルマン・フォード アルゴリズムを使用して単一ソースの最短パス問題を解決するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。