Floyd 算法实现

一 问题描述

求节点0到节点2的最短路径。

二 代码

package graph.floyd;

import java.util.Scanner;

public class Floyd {
    static final int MaxVnum = 100;  // 顶点数最大值
    static final int INF = 0x3f3f3f3f; //无穷大
    static final int dist[][] = new int[MaxVnum][MaxVnum]; // 最短距离
    static final int p[][] = new int[MaxVnum][MaxVnum]; // 前驱数组
    static final boolean flag[] = new boolean[MaxVnum]; // 如果 s[i] 等于 true,说明顶点 i 已经加入到集合 S ;否则顶点 i 属于集合 V-S

    static int locatevex(AMGraph G, char x) {
        for (int i = 0; i < G.vexnum; i++) // 查找顶点信息的下标
            if (x == G.Vex[i])
                return i;
        return -1; // 没找到
    }

    static void CreateAMGraph(AMGraph G) {
        Scanner scanner = new Scanner(System.in);
        int i, j;
        char u, v;
        int w;
        System.out.println("请输入顶点数:");
        G.vexnum = scanner.nextInt();
        System.out.println("请输入边数:");
        G.edgenum = scanner.nextInt();
        System.out.println("请输入顶点信息:");

        // 输入顶点信息,存入顶点信息数组
        for (int k = 0; k < G.vexnum; k++) {
            G.Vex[k] = scanner.next().charAt(0);
        }
        //初始化邻接矩阵所有值为0,如果是网,则初始化邻接矩阵为无穷大
        for (int m = 0; m < G.vexnum; m++)
            for (int n = 0; n < G.vexnum; n++)
                if (m != n)
                    G.Edge[m][n] = INF;
                else
                    G.Edge[m][n] = 0; // 注意m==n时,设置为 0

        System.out.println("请输入每条边依附的两个顶点及权值:");
        while (G.edgenum-- > 0) {
            u = scanner.next().charAt(0);
            v = scanner.next().charAt(0);
            w = scanner.nextInt();

            i = locatevex(G, u);// 查找顶点 u 的存储下标
            j = locatevex(G, v);// 查找顶点 v 的存储下标
            if (i != -1 && j != -1)
                G.Edge[i][j] = w; //有向图邻接矩阵
            else {
                System.out.println("输入顶点信息错!请重新输入!");
                G.edgenum++; // 本次输入不算
            }
        }
    }

    static void Floyd(AMGraph G) { // 用 Floyd 算法求有向网 G 中各对顶点 i 和 j 之间的最短路径
        int i, j, k;
        for (i = 0; i < G.vexnum; i++)                // 各对结点之间初始已知路径及距离
            for (j = 0; j < G.vexnum; j++) {
                dist[i][j] = G.Edge[i][j];
                if (dist[i][j] < INF && i != j)
                    p[i][j] = i;    // 如果 i 和 j 之间有弧,则将 j 的前驱置为 i
                else p[i][j] = -1;  // 如果 i 和 j 之间无弧,则将 j 的前驱置为 -1
            }
        for (k = 0; k < G.vexnum; k++)
            for (i = 0; i < G.vexnum; i++)
                for (j = 0; j < G.vexnum; j++)
                    if (dist[i][k] + dist[k][j] < dist[i][j]) { // 从 i 经 k 到 j 的一条路径更短
                        dist[i][j] = dist[i][k] + dist[k][j]; // 更新dist[i][j]
                        p[i][j] = p[k][j];   // 更改 j 的前驱
                    }
    }

    static void print(AMGraph G) { // 输出邻接矩阵
        int i, j;
        for (i = 0; i < G.vexnum; i++) {//输出最短距离数组
            for (j = 0; j < G.vexnum; j++)
                System.out.print(dist[i][j] + "\t");
            System.out.println();
        }
        System.out.println();
        for (i = 0; i < G.vexnum; i++) {//输出前驱数组
            for (j = 0; j < G.vexnum; j++)
                System.out.print(p[i][j] + "\t");
            System.out.println();
        }
    }

    static void DisplayPath(AMGraph G, int s, int t) { // 显示最短路径
        if (p[s][t] != -1) {
            DisplayPath(G, s, p[s][t]);
            System.out.print(G.Vex[p[s][t]] + "-->");
        }
    }

    public static void main(String[] args) {
        char start, destination;
        int u, v;
        AMGraph G = new AMGraph();
        CreateAMGraph(G);
        Floyd(G);
        print(G);
        System.out.print("请依次输入路径的起点与终点的名称:");
        Scanner scanner = new Scanner(System.in);
        start = scanner.next().charAt(0);
        destination = scanner.next().charAt(0);
        u = locatevex(G, start);
        v = locatevex(G, destination);
        DisplayPath(G, u, v);
        System.out.println(G.Vex[v]);
        System.out.println("最短路径的长度为:" + dist[u][v]);
        System.out.println();
    }
}

class AMGraph {
    char Vex[] = new char[Floyd.MaxVnum];
    int Edge[][] = new int[Floyd.MaxVnum][Floyd.MaxVnum];
    int vexnum; // 顶点数
    int edgenum; // 边数
}

三 实现

白色为输出,绿色为输入。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Matlab Floyd算法实现是一个用于求解最短路径的算法。在这个算法中,我们通过计算每个顶点到其他顶点的最短路径来构建一个邻接矩阵。该算法实现如下所示: ```matlab function [dist, path] = matlabFloyd(a, sb, db) n = size(a, 1); dist = a; path = zeros(n); for k = 1:n for i = 1:n for j = 1:n if dist(i, j) > dist(i, k) + dist(k, j) dist(i, j) = dist(i, k) + dist(k, j); path(i, j) = k; end end end end shortestPath = [sb]; currentNode = sb; while currentNode ~= db nextNode = path(currentNode, db); shortestPath = [shortestPath, nextNode]; currentNode = nextNode; end shortestPath = [shortestPath, db]; disp('最短路径为:'); disp(shortestPath); disp('最短距离为:'); disp(dist(sb, db)); end ``` 在这个实现中,我们首先初始化距离矩阵`dist`为原始邻接矩阵`a`,路径矩阵`path`为全零矩阵。然后,我们通过三重循环对每个顶点对之间的最短路径进行更新。在更新过程中,我们比较通过顶点`k`的路径是否比直接路径更短,如果是,则更新距离矩阵和路径矩阵。最后,我们根据路径矩阵构建最短路径,并输出最短路径和最短距离。 注意:在这个实现中,我们假设输入的邻接矩阵`a`是一个有向图的距离矩阵。`sb`和`db`分别表示起点和终点的标号。输出结果将会显示最短路径和最短距离。<span class="em">1</span><span class="em">2</span> #### 引用[.reference_title] - *1* [Floyd算法(matlab实现)](https://blog.csdn.net/weixin_45913125/article/details/115248807)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [详解floyd算法 及<MATLAB>实现](https://blog.csdn.net/qq_43218185/article/details/90039890)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值