前言:
迪杰斯特拉(Dijkstra)算法是典型最短路径算法,用于计算一个节点到其他节点的最短路径。
它的主要特点是以起始点为中心向外层层扩展(广度优先搜索思想),直到扩展到终点为止。
因为在Isomap 中要用到,这里简单介绍一下. 这里主要结合有相同图结束,无向图是对称矩阵
目录
1: 算法流程
2:算法实现
一 算法流程
如上图
1: 引入两个集合S,U。
S : 已求出最短路径的点
u: 未求出最短路径的点
如上图,当求A点时候
2: 从u 集合中找到最短路径的点B,加入到S中
如上图:
AB 最短
3: 从u中找到满足最短路径的点k,更新当前的路径
满足下面特征
如上图
AB[1]+BC[9]<AC[12]
更新AC 为 10
4: 重复2-3 直到找不到u
二 算法实现
# -*- coding: utf-8 -*-
"""
Created on Wed Oct 16 17:15:25 2019
@author: chengxf2
"""
import numpy as np
import copy
class Dijkstra:
"""
加载数据集
Args
-1: 代表无穷大,不可达
return
None
"""
def LoadPath(self):
"""
self.path = np.array([[0, 1, 4, -1, -1, -1],
[1, 0, 2, 7, 5, -1],
[4, 2, 0, -1, 1, -1 ],
[-1, 7, -1, 0, 3, 2 ],
[ -1, 5, 1, 3, 0, 6],
[-1, -1, -1, 2, 6, 0] ])
"""
self.path = np.array([[0, 1, 12, -1, -1, -1],
[-1, 0, 9, 3, -1, -1],
[-1, -1, 0, -1, 5, -1 ],
[-1, -1, 4, 0, 13, 15 ],
[-1, -1, -1, -1, 0, 4],
[-1, -1, -1, -1, -1, 0] ])
self.m , self.n = np.shape(self.path)
def __init__(self):
self.m = 0 ##样本个数
self.n = 0 ##样本维度
self.LoadPath()
self.Updata()
"""
类似step3, step4
"""
def MinPath(self, path ,i, uList):
minPath = float('inf')
minU = -1
for u in uList:
curPath = path[u]
if curPath>=0 and curPath<minPath:
minPath = curPath
minU = u
return minU
"""
FindPath
Args
i: 当前的点
u: 当前最邻近的点
uList: 未访问的点
return
None
"""
def FindPath(self, i, u, uList):
path_iu = self.path[i,u]
for k in uList:
path_ik= self.path[i,k]
path_uk = self.path[u,k]
if path_uk ==-1: ##无法建立新的路径
continue
if path_ik ==-1 or path_iu+path_uk <path_ik:
print("\n i: ",i,"u:",u,"k:",k, "\t path_iu:",path_iu,"\t path_uk: \t" ,path_uk)
self.path[i,k] = path_iu+path_uk
# self.path[k,i]=self.path[i,k]
if -1==path_ik: : 如果是无向图,对称矩阵
self.path[k,i]=self.path[i,k]
else:
dist = min(self.path[i,k],self.path[k,i])
self.path[i,k]=self.path[k,i]=dist
"""
更新路劲矩阵
Args
None
return
None
"""
def Updata(self):
for i in range(self.m):
visted =[i] ##step1 已经访问过的
uList = np.arange(0,self.m).tolist()
uList.remove(i)
#.remove(i) ##step1 未访问过的路径
while(True):
path = self.path[i]
u = self.MinPath(path,i, uList) ##step2 找到当前的最小路径
if u<0: ##当前找不到最小路径了
break
visted.append(u) ##step3
uList.remove(u) ## step3
print("\n ---更新路径参数---- \n")
self.FindPath(i, u, uList)
print("\n ----更新结束-- \n")
print(" END i:",i,"\t Path: \n" ,self.path)
# print("i:",i,"\t Path: \n" ,self.path)
dij =Dijkstra()