单源最短路径——Djkstra算法

所谓单源最短路径,是指从一个顶点(源点)出发到其他各顶点的最短路径,即给定有向网G和源点Vk,求从Vk到G中其他各顶点Vj(j=1,2,····,n,j!=k)的最短路径。

迪杰斯特拉提出了一种按路径长度递增的次序产生最短路径的算法。其基本思想是,把网中所有顶点分成两组,第一组是已确定最短路径的顶点集合S,第二组是尚未确定最短路径的顶点集合V;把V中的顶点按最短路径长度递增的顺序逐个添加到S中,添加过程中始终保持从Vk到S中每个顶点的最短路径长度都不大于从Vk到V中任何顶点的最短路径长度,直到从Vk出发可以到达的顶点都在S中为止。

一开始,S中只有顶点Vk,其余顶点在V中。引入一维数组dist,用dist[i]表示当前时刻所找的从源点到每个中点Vi的最短路径长度;其初始值为dis[k]=0;若存在弧(vk,vi),则dist[i]为其弧上的权值,否则从Vk到Vi无弧时dist[i]=max。然后每次从V中的顶点选取一个dist值最小的顶点Vj(dist[j]=min{dist[i]|Vi属于V})加入到S中,并对V中顶点的dist值进行相应的修改,即若以加入S中的顶点Vj作为中间顶点使得V中某顶点的dist值更小时要相应地修改该顶点的dist值。这样从V中选一个顶点加入到S中,对V中的顶点的dist值修改一遍,只需做n-1次就可求得Vk到其余各顶点的最短路径。

在求最短路径的过程中,最短路径长度已记在dist数组中,同时需要把路径也记下来。为此设一个一维数组pre,pre[i]存放从Vk到Vi的路径上Vi前一个顶点的序号;若Vk到Vi无路径可达,则vi的前一个顶点序号用0表示(即pre[i]=0)。在算法结束时,沿着顶点Vi对应的pre[i]向前追溯就能确定从Vk到Vi的最短路径,其最短路径长度为dist[i].

设有向网用邻接矩阵a表示,a[i,j]表示弧(Vi,Vj)上的权值,无弧(Vi,Vj)时a[i,j]为max;a[i,j]=0,当Vi进入S中时,用a[i,j]=1来标识。求有向图中从顶点Vk出发到其他各顶点的最短路径的Dijkstra算法如下:

void dijkstra(int a[][],int k,int pre[],int dist[],int n)//求用邻接矩阵a表示的有向网中从Vk到其他各顶点最短路径
{
    int i,j,p,min;//定义局部变量
    for(i=1;i<=n;i++)//数组dist,pre初始化
    {
        dist[i]=a[k][i];
        if(dist[i]<max)
            pre[i]=k;
        else 
            pre[i]=0;
    }
    pre[k]=0;
    dist[k]=0;
    a[k][k]=1;//Vk加入S中控制n-1次按长度递增产生最短路径
    for(p=1;p<=n-1;p++)
    {
        min=max;//预置最短路径长度为max
        j=-1;//设结束标志
        for(i=1;i<=n;i++)
            if(a[i][i]==0&&dist[i]<min)
            {
                j=i;
                min=dist[i];//在V中选dist最小的点
            }
        if(j==-1) break;//已无顶点可加入S,退出
        else 
        {
            a[j][j]=1;//把选出的顶点Vj加入S中
            for(i=1;i<=n;i++)//更新V中顶点的dist和pre值
                if(a[i][i]==0&&(min+a[j][i]<dist[i]))
                {
                    dist[i]=min+a[j][i];
                    pre[i]=j;
                }
        }
    }
}//dijkstra


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 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、付费专栏及课程。

余额充值