图——Dijkstra算法实现

在这里插入图片描述

package graph;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Vector;

public class Dijkstra {

    int max = 65535;

    int numVertex = 6;
    char Vertexes[] = {'u','v','w','x','y','z'};
    int graph[][] = {
          /* u  v w x  y   z      */
            {0,2,5,1,max,max},
            {2,0,3,2,max,max},
            {5,3,0,3,1,5},
            {1,2,3,0,1,max},
            {max,max,1,1,0,2},
            {max,max,5,max,2,0}
    };

    /**
     * 传入一个顶点,求出它到其他顶点的最短路径
     *
     *  算法思想:两个集合:S(表示已经找到最短路径的顶点集合)  T(表示为未找到最短路径的集合)
     *                  S 初始化为起点  T初始化为全部除起点外的顶点
     *           ST[]:用来区分S和T集合,值为1表示为S集合(即已经找到顶点与它的最短路径),为0则是T集合
     *          数组D[]:表示起点与其他顶点的路径,初始化为顶点与其他顶点的直接相连路径,如果没有直接相连则初始化为最大表示没有边相连
     *          pre[] :表示起点到某个顶点的最小路径中该顶点的前驱节点
     *
     *       步骤 1、  遍历除T集合的顶点 ,找到D中与 起点路径最短的 顶点下标 和距离 ,将其添加到S集合(即ST[]中把该顶点对应的位置设为1)
     *           2、   更新起点到 T集合中其他顶点 的距离
     *           3、  继续步骤1的操作,知道遍历完所有顶点
     *
     * @param n  表示传入的顶点在数组中的下标
     */
    public void Dijsk(int n){

        /*存放最短路径(初始化为起点与其他顶点的直接相连的边权重)*/
        int D[] = new int[numVertex];
        /*区分顶点是S集合还是T集合*/
        int ST[] = new int[numVertex];
        /*最短路径的前驱节点*/
        int pre[] = new int[numVertex];

        /*初始化D、ST、pre*/
        for(int i=0;i<numVertex;++i){
            D[i] = graph[n][i];
            ST[i]=0;
            pre[i]=n;
        }

        /*初始化起始顶点(放入S集合)*/
        ST[n] =1;

        /*存放到某点最短路径的前驱节点*/
        HashMap<Integer,Integer> preNode = new HashMap<>();


        /*开始求遍历其他顶点求最短路径 需要遍历numVertex-1次(排除掉起点一次)*/
        for(int i=0;i<numVertex;++i){
            /*if排除自身到自身的最短路径*/
            if(i!=n){
                /*寻找离起点最近的节点 且 该节点还没添加到啊路径*/
                int min = max;   //最大数65535 表示没有距离
                int k=-1;           //存储距离最近顶点的下标

                /*找到T集合中离起点最近的顶点*/
                for (int j=0;j<numVertex;++j){
                    /**/
                    if(ST[j]==0 && D[j]<min){
                        min = D[j];
                        k = j;
                    }
                }
                /*将T集合中距离起点最近的顶点添加到S集合*/
                ST[k] = 1;

                /*更新T集合中其他顶点到起点的距离*/
                for(int j=0;j<numVertex;++j){

                    /*防止溢出  max65535 再加会溢出*/
                    /*起点到k再加k到j的路径和*/
                    int temp =(graph[k][j]==max ? max:D[k]+graph[k][j]  );

                    /*如果起点 到k再加k到j的路径和 比 原先到 j的路径更短  则更新 */
                    if(ST[j]==0 && temp<D[j]){
                        D[j] = temp;
                        /*更新T集合j的前驱节点*/
                        pre[j] =k;
                    }
                }


            }

        }
        System.out.println("起点"+Vertexes[n]+"到其他顶点的最短路径:");
        for(int item=0;item<numVertex;++item){
            System.out.println(""+Vertexes[n]+"-->"+Vertexes[item]+":"+D[item]);
        }

    }
    public static void main(String[] args) {
        Dijkstra dis = new Dijkstra();
        dis.Dijsk(0);
    }
}

离字典,将起始节点的距离设为0,其他节点的距离设为无穷大 distances = {node: sys.maxsize for node in graph} distances[start] = 0 # 初始化已访问节点的集合和未访以下是使用问节点D的集ijkstra合 visited = set() unvisited算法求解最短路径的Python = set(graph) while unvisited: # 代码示例: ```python class D选择当前ijkstra距: def __init__(self, graph离最小的节点 , start, current goal): self.graph = graph # 邻接表_node = min(unvisited, key=lambda self node: distances[node]) # 更新.start = start当前节点的 # 起邻居节点点 self.goal =的距离 goal # 终点 for neighbor in graph self.open[current_node]: _list = {} if neighbor in # open 表 self.closed_list unvisited: new_distance = distances[current_node] + = {} graph[current_node][neighbor # closed 表 self.open_list[start] if new_distance] = < distances[neighbor]: 0.0 # 将 distances[neighbor] = new_distance # 将当前起点放入 open_list 中 self.parent = {节点标记start:为已访 None} 问,并从未访问集合中移除 visited.add # 存储节点的父子关系。键为(current_node) 子节点, unvisited值为父.remove(current_node) return节点。方便做最 distances def print后_path(dist路径的ances,回 start溯 self.min, end): _dis = None # 根 # 最短路径的长度 def shortest_path据距离字典和终点节点(self): while True: ,逆向 if self打印路径.open_list is path = [end None: ] print('搜索 current_node =失败 end while current_node !=, 结束!') break distance start: , min_node = for neighbor in graph min(zip[current_node]: if(self.open_list distances[current.values(), self_node] ==.open_list.keys distances[neighbor())) #] + graph 取出距[neighbor][current_node]: 离最小的节点 self path.open_list.pop.append(min_node)(neighbor) current_node = neighbor break path.reverse() # 将其从 open_list 中去除 self print.closed("_list[minShortest_node] = path from", distance # 将节点加入 closed start, "to", end,_list ":", "->".join(path)) # 示例 中 if min_node == self.goal: # 如果节点为的邻接矩阵终点 self.min_dis = distance 表示 graph shortest = { _path = [ 'Aself.goal]': {'B': # 5, 'C 记录从': 终1}, 点回溯的路径 'B
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值