最小生成树算法普利姆算法和克鲁斯卡尔算法实现

最小生成树算法:
普里姆算法:顶点集合N,辅助顶点集合S,初始化中,将出发点vi加入S,并从N中删除
1.从顶点集合N中找到一条到集合S最近的边(vi,vj),存储该边,并将vj从N移到S中
2.重复1步骤直至所有顶点加入S集合
普里姆算法:与边的多少关系不大,适合计算边稠密的图

克鲁斯卡尔算法:将图中的N个订单分成Ni个点集合,T是边集合,TE是最小生成树的边集合。
1.从T中找出一条最短的边,这条边是连接两个不同集合的边
2.将该边的顶点所在的集合合并成一个集合,将边的两点和值记录到TE中
3.从T中删除该边
4.重复步骤1-3,知道所有顶点合并成一个集合

代码实现:

/**
     * @name 最小生成树普利姆算法
     * @use 使用普利姆算法计算图的最小生成树,图用矩阵(二维数组)表示
     * @param chart 图矩阵
     * @param poin 起始点
     * @return 最小生成树集合
     */
    public static function mainTreePrim($chart, $point) 
    {
        $minTree = array();
        $S = array($point);//包含点集合的集合
        while (count($S) < count($chart)) {
            $min = PHP_INT_MAX;
            $x = 0;
            $y = 0;
            foreach ($chart as $key1 => $value1) {
                if (in_array($key1,$S)) {
                    continue;
                }
                foreach ($S as $value2) {
                    if ($chart[$value2][$key1] != 0 && $chart[$value2][$key1] < $min) {
                        $min = $chart[$value2][$key1];
                        $x = $value2;
                        $y = $key1;
                    }
                }

            }
            $minTree[] = array('start' => $x, 'end' => $y);
            $S[] = $y;
        }
        return $minTree;
    }
    /**
     * @name 最小生成树克鲁斯卡尔算法
     * @use 使用克鲁斯卡尔算法计算图的最小生成树,图用矩阵(二维数组)表示
     * @param chart 图矩阵
     * @param poin 起始点
     * @return 最小生成树集合
     */
    public static function mainTreeKruskal($chart, $point) 
    {
        $T = array();//未访问的边
        $TE = array();//已访问的边
        $nodes = array(array($point));
        foreach ($chart as $key1 => $value1) {
            foreach ($value1 as $key2 => $value2) {
                if ($value2 != 0) {
                    $T[] = array('x' => $key1, 'y' => $key2, 'value' => $value2);
                }
            }
        }
        while ($T) {
            $min = PHP_INT_MAX;
            $slide = array();
            $tempKey = 0;
            foreach ($T as $key => $value) {
                if ($value['value'] < $min) {
                    $min = $value['value'];
                    $slide = $value;
                    $tempKey = $key;
                }
            }
            $set1 = -1;
            $set2 = -1;
            foreach ($nodes as $key => $value) {
                if (in_array($slide['x'],$value)) {
                    $set1 = $key;
                }
                if (in_array($slide['y'],$value)) {
                    $set2 = $key;
                }
            }
            unset($T[$tempKey]);
            if ($set1 !== -1 && $set1 === $set2) {
                continue;
            }
            if ($set1 === -1 && $set2 === -1){
                $nodes[] = array($slide['x'],$slide['y']);
            } else if ($set1 === -1) {
                $nodes[$set2][] = $slide['x'];
            } else if ($set2 === -1) {
                $nodes[$set1][] = $slide['y'];
            } else {
                $nodes[$set1] = array_merge($nodes[$set1],$nodes[$set2]);
                unset($nodes[$set2]);
            }
            $TE[] = $slide;
        }
        return $TE;
    }

猜你喜欢

转载自blog.csdn.net/qq_25744595/article/details/84564357