算法导论25章-25.2Floyd-Warshall算法

请原谅我用世界上最好的语言来写这个算法

<?php

define("∞", 99);
define("N", NULL);

/**
 * O(n^3)
 * @param array $W
 * D_k[i][j]为从节点i到节点j的所有中间节点全部取自集合{1,2,...,k}的一条最短路径的权重
 */

function floyd_warshall(array $W){
    $n = $W['rows'];
    $D_0 = $W;
    $P_0 = array();
    for($i = 1; $i <= $n; $i++){
        for($j = 1; $j <= $n; $j++){
            if($W[$i][$j] !=&& $i != $j){
                $P_0[$i][$j] = $i;
            }else{
                $P_0[$i][$j] = -1;
            }
        }
    }
    echo "D_0\n";
    print_square_matrix($D_0);
    echo "P_0\n";
    print_square_matrix($P_0);
    for($k = 1; $k <= $n; $k++){
        ${"D_".$k} = array();
        for($i = 1; $i <= $n; $i++){
            for($j = 1; $j <= $n; $j++){
                ${"P_$k"}[$i][$j] = ${"P_".($k-1)}[$i][$j];
                if(${"D_".($k-1)}[$i][$k] !=&& ${"D_".($k-1)}[$k][$j] !=&& ${"D_".($k-1)}[$i][$k] + ${"D_".($k-1)}[$k][$j] < ${"D_".($k-1)}[$i][$j]){
                    if($k != $j){
                        ${"P_$k"}[$i][$j] = ${"P_".($k-1)}[$k][$j];
                    }else{
                        ${"P_$k"}[$i][$j] = ${"P_".($k-1)}[$i][$k];
                    }
                }
                ${"D_".$k}[$i][$j] = min(${"D_".($k-1)}[$i][$j], ${"D_".($k-1)}[$i][$k] + ${"D_".($k-1)}[$k][$j]);
            }
        }
        echo "D_$k\n";
        print_square_matrix(${"D_$k"});
        echo "P_$k\n";
        print_square_matrix(${"P_$k"});
    }
    return ${"D_$n"};
}

/**
 * 有向图的传递闭包
 * @param array $G
 * 如果图中存在一条从节点i到节点j的所有中间节点都取自集合{1,2,...,k}的路径,则T_k[i][j]=1
 */

function transitive_closure(array $G){
    $n = $G['V'];
    $T_0 = array();
    for($i = 1; $i <= $n; $i++){
        for($j = 1; $j <= $n; $j++){
            if($i == $j || $G['E'][$i][$j] > 0){
                $T_0[$i][$j] = 1;
            }else{
                $T_0[$i][$j] = 0;
            }
        }
    }
    echo "T_0\n";
    print_square_matrix(${"T_0"});
    for($k = 1; $k <= $n; $k++){
        ${"T_$k"} = [];
        for($i = 1; $i <= $n; $i++){
            for($j = 1; $j <= $n; $j++){
                ${"T_$k"}[$i][$j] = ${"T_".($k-1)}[$i][$j] || (${"T_".($k-1)}[$i][$k] && ${"T_".($k-1)}[$k][$j]);
            }
        }
        echo "T_$k\n";
        print_square_matrix(${"T_$k"});
    }
    return ${"T_$n"};
}

function print_square_matrix(array $A){
    $n = isset($A['rows']) ? $A['rows'] : count($A);
    for ($i = 1; $i <= $n; $i++){
        for ($j = 1; $j <= $n; $j++){
            printf("%4d", $A[$i][$j]);
        }
        echo "\r\n";
    }
    echo "-------------------------------\r\n";
}

$W = [
    [N,  N,  N,  N,  N,  N],
    [N,  0,  3,  8,  ∞, -4],
    [N,  ∞,  0,  ∞,  1,  7],
    [N,  ∞,  4,  0,  ∞,  ∞],
    [N,  2,  ∞, -5,  0,  ∞],
    [N,  ∞,  ∞,  ∞,  6,  0],
];

$W['rows'] = 5;

floyd_warshall($W);

echo "************************************************\r\n";

$G = [
    'V' => 4,
    'E' => [
        [N,  N,  N,  N,  N],
        [N,  1,  N,  N,  N],
        [N,  N,  1,  1,  1],
        [N,  N,  1,  1,  N],
        [N,  1,  N,  1,  1],
    ]
];

transitive_closure($G);

//end

转载请注明:小Y » 算法导论25章-25.2Floyd-Warshall算法

赞 (2) 评论 (0) 分享 ()

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址