zoukankan      html  css  js  c++  java
  • 第八节--图的数据结构及其算法

    第八节–图的数据结构及其算法

    图除了被应用在数据结构中最短路径搜索,拓扑排序外,还能应用在系统分析中以时间为评审标准的性能评审技术等。采用Dijkstra这种图形算法就能快速寻找出两个节点之间的最短路径

    一.图的遍历

    图的遍历,可以定义如下:
    一个图G=(V,E),存在某一顶点v属于V,我们希望从v开始,通过此节点相邻的节点而去访问图G中的其他节点,这就被称为"图的遍历"。也就是从某一个顶点V1开始,遍历可以经过V1到达的顶点,接着遍历下一个顶点直到全部的顶点遍历完毕为止

    图遍历的方法有两种:即"深度优先遍历"和"广度优先遍历",也称为"深度优先搜索"和"广度优先搜索"

    1.深度优先遍历法

    深度优先遍历的方式有点类似于前序遍历,从图的某一顶点开始遍历,被访问过的顶点就做上已访问的记号,接着遍历此顶点所有相邻且未访问过的顶点中的任意一个顶点,并做上已访问的记号,再以该点为新的起点继续进行深度优先搜索

    这种图的遍历方法结合了递归和堆栈两种数据结构的技巧,由于此方法会造成无限循环,因此必须加入一个变量,判断该点是否已经遍历完毕
    未命名文件.png
    步骤01:以顶点1为起点,将相邻的顶点2和顶点5压人堆栈
    未命名文件 (1).png
    步骤02:弹出顶点2,将与顶点2相邻且未访问过的顶点3和顶点4压人堆栈
    未命名文件 (2).png
    步骤03:弹出顶点3,将与顶点3相邻且未访问过的顶点4和顶点5压人堆栈
    未命名文件 (3).png
    步骤04:弹出顶点4,将顶点4相邻且未访问过的顶点5压人堆栈
    未命名文件 (4).png
    步骤05:弹出顶点5,将与顶点5相邻且未访问过的顶点压人堆栈,大家可以发现与5相邻的顶点全部被访问过了,所以无须压人堆栈
    未命名文件 (5).png
    步骤06:将堆栈内的值弹出并判断是否已经遍历过了,直到堆栈内无节点可遍历为止
    未命名文件 (6).png
    故深度优先的遍历顺序为:顶点1,顶点2,顶点3,顶点4,顶点5

    深度优先函数的算法如下:

    def dfs(current): #深度优先函数
        run[current]=1
        print('[%d] ' %current, end='')
        ptr=head[current].next
        while ptr!=None:
            if run[ptr.val]==0:        #如果顶点尚未遍历,
                dfs(ptr.val)           #就进行dfs的递归调用
            ptr=ptr.next
    

    1.2.程序说明
    1.2.1图的数组如下,进行深度优先遍历法

    #声明图的边线数组       
    data=[[1,2],[2,1],[1,3],[3,1], 
          [2,4],[4,2],[2,5],[5,2], 
          [3,6],[6,3],[3,7],[7,3], 
          [4,8],[8,4],[5,8],[8,5], 
          [6,8],[8,6],[8,7],[7,8]]
    

    1.2.2源程序

    class list_node:
        def __init__(self):
            self.val=0
            self.next=None
    
    head=[list_node()]*9 #声明一个节点类型的链表数组
            
    run=[0]*9
    
    def dfs(current): #深度优先函数
        run[current]=1
        print('[%d] ' %current, end='')
        ptr=head[current].next
        while ptr!=None:
            if run[ptr.val]==0:        #如果顶点尚未遍历,
                dfs(ptr.val)           #就进行dfs的递归调用
            ptr=ptr.next
            
    #声明图的边线数组       
    data=[[1,2],[2,1],[1,3],[3,1], 
          [2,4],[4,2],[2,5],[5,2], 
          [3,6],[6,3],[3,7],[7,3], 
          [4,8],[8,4],[5,8],[8,5], 
          [6,8],[8,6],[8,7],[7,8]]
    for i in range(1,9):  #共有八个顶点
        run[i]=0          #把所有顶点设置成尚未遍历过
        head[i]=list_node()
        head[i].val=i     #设置各个链表头的初值
        head[i].next=None
        ptr=head[i]        #设置指针指向链表头
        for j in range(20): #二十条边线
            if data[j][0]==i: #如果起点和链表头相等,则把顶点加入链表
                newnode=list_node()
                newnode.val=data[j][1]
                newnode.next=None
                while True:
                    ptr.next=newnode    #加入新节点
                    ptr=ptr.next
                    if ptr.next==None:
                        break
            
    
    print('图的邻接表内容:')      #打印图的邻接表内容
    for i in range(1,9):
        ptr=head[i]
        print('顶点 %d=> ' %i,end='')
        ptr =ptr.next
        while ptr!=None:
            print('[%d] ' %ptr.val,end='')
            ptr=ptr.next
        print()
    print('深度优先遍历的顶点:')      #打印深度优先遍历的顶点
    dfs(1)
    print()
    

    2.3运行结果

    图的邻接表内容:
    顶点 1=> [2] [3] 
    顶点 2=> [1] [4] [5] 
    顶点 3=> [1] [6] [7] 
    顶点 4=> [2] [8] 
    顶点 5=> [2] [8] 
    顶点 6=> [3] [8] 
    顶点 7=> [3] [8] 
    顶点 8=> [4] [5] [6] [7] 
    深度优先遍历的顶点:
    [1] [2] [4] [8] [5] [6] [3] [7] 
    

    2.广度优先遍历法

    广度优先(Breadth-FIrst Search,BFS)遍历法则是使用队列和递归技巧来遍历,也是从图的某一顶点开始遍历,被访问过的顶点就做上已访问的记号。接着遍历此顶点的所有相邻且未访问过的顶点中的任意一个顶点,并做上已访问的记号,再以该点为新的起点继续进行广度优先的遍历

    步骤01:以顶点1为起点,将相邻且未访问过的顶点2和顶点5加入队列
    未命名文件.png
    步骤02:取出顶点2,将与顶点2相邻且未访问过的顶点3和顶点4加入队列
    未命名文件 (1).png
    步骤03:取出顶点5,将与顶点5相邻且未访问过的顶点3和顶点4加入队列
    未命名文件 (2).png
    步骤04:取出顶点3,将顶点3相邻且未访问过的顶点4加入队列
    未命名文件 (3).png
    步骤05:取出顶点4,将与顶点4相邻且未访问过的顶点加入队列中,大家可以发现与顶点4相邻的顶点全部被访问过了,所以无须再加入队列中
    未命名文件 (4).png
    步骤06:将队列内的值弹出并判断是否已经遍历过了,直到队列内无节点可遍历为止
    未命名文件 (5).png
    故深度优先的遍历顺序为:顶点1,顶点2,顶点5,顶点3,顶点4

    广度优先函数的python函数:

    #广度优先查找法
    def bfs(current):
        global front
        global rear
        global Head
        global run
        enqueue(current) #将第一个顶点存入队列
        run[current]=1   #将遍历过的顶点设置为1
        print('[%d]' %current, end='') #打印出该遍历过的顶点
        while front!=rear:             #判断当前的队伍是否为空
            current=dequeue()            #将顶点从队列中取出
            tempnode=Head[current].first #先记录当前顶点的位置
            while tempnode!=None:
                if run[tempnode.x]==0:
                    enqueue(tempnode.x)
                    run[tempnode.x]=1   #记录已遍历过
                    print('[%d]' %tempnode.x,end='')
                tempnode=tempnode.next
    

    2.1程序说明
    2.1.1存放图的数组如下:

    Data =[[1,2],[2,1],[1,3],[3,1],[2,4], 
           [4,2],[2,5],[5,2],[3,6],[6,3], 
           [3,7],[7,3],[4,5],[5,4],[6,7],[7,6],[5,8],[8,5],[6,8],[8,6]]
    

    2.1.2源程序

    MAXSIZE=10  #定义队列的最大容量	
    
    front=-1 #指向队列的前端
    rear=-1  #指向队列的末尾
    
    class Node:
        def __init__(self,x):
            self.x=x        #顶点数据
            self.next=None  #指向下一个顶点的指针
            
    class GraphLink:
        def __init__(self):
            self.first=None
            self.last=None
            
        def my_print(self):
            current=self.first
            while current!=None:
                print('[%d]' %current.x,end='')
                current=current.next
            print()
    
        def insert(self,x):
            newNode=Node(x)
            if self.first==None:
                self.first=newNode
                self.last=newNode
            else:
                self.last.next=newNode
                self.last=newNode
     
    #队列数据的存入
    def enqueue(value):
        global MAXSIZE
        global rear
        global queue
        if rear>=MAXSIZE:
            return
        rear+=1
        queue[rear]=value
        
    
    #队列数据的取出
    def dequeue():
        global front
        global queue
        if front==rear:
            return -1
        front+=1
        return queue[front]
    
    #广度优先查找法
    def bfs(current):
        global front
        global rear
        global Head
        global run
        enqueue(current) #将第一个顶点存入队列
        run[current]=1   #将遍历过的顶点设置为1
        print('[%d]' %current, end='') #打印出该遍历过的顶点
        while front!=rear:             #判断当前的队伍是否为空
            current=dequeue()            #将顶点从队列中取出
            tempnode=Head[current].first #先记录当前顶点的位置
            while tempnode!=None:
                if run[tempnode.x]==0:
                    enqueue(tempnode.x)
                    run[tempnode.x]=1   #记录已遍历过
                    print('[%d]' %tempnode.x,end='')
                tempnode=tempnode.next
    
    #声明图的边线数组
    Data=[[0]*2 for row in range(20)]
    
    Data =[[1,2],[2,1],[1,3],[3,1],[2,4], 
           [4,2],[2,5],[5,2],[3,6],[6,3], 
           [3,7],[7,3],[4,5],[5,4],[6,7],[7,6],[5,8],[8,5],[6,8],[8,6]]
    
    run=[0]*9 #用来记录各顶点是否遍历过
    queue=[0]*MAXSIZE
    Head=[GraphLink]*9
     			
    print('图的邻接表内容:') #打印图的邻接表内容
    for i in range(1,9):      #共有8个顶点
        run[i]=0              #把所有顶点设置成尚未遍历过
        print('顶点%d=>' %i,end='')
        Head[i]=GraphLink()
        for j in range(20):
            if Data[j][0]==i: #如果起点和链表头相等,则把顶点加入链表
                DataNum = Data[j][1]
                Head[i].insert(DataNum)
        Head[i].my_print()    #打印图的邻接标内容
    
    print('广度优先遍历的顶点:') #打印广度优先遍历的顶点
    bfs(1)
    print()
    

    2.1.3运行结果

    图的邻接表内容:
    顶点1=>[2][3]
    顶点2=>[1][4][5]
    顶点3=>[1][6][7]
    顶点4=>[2][5]
    顶点5=>[2][4][8]
    顶点6=>[3][7][8]
    顶点7=>[3][6]
    顶点8=>[5][6]
    广度优先遍历的顶点:
    [1][2][3][4][5][6][7][8]
    

    二.最小生成树

    生成树又称"花费树",“出本树"或"值树”,一个图的生成树(spanning tree)就是以最少的边来连通图中所有的顶点,且不造成回路(cycle)的树形结构。假设在树的边加上一个权重(weight)值,这种图就成为"加权图(weighted graph)"。如果这个权重值代表两个顶点间的距离(distance)或成本(cost),这类图就被称为网络(network)
    未命名文件.png

    介绍以所谓"贪婪法则"(Greedy Rule)为基础来求得一个无向连通图的最小生成树的常见问题,分别是Prim算法和Kruskal算法

    1.Prim算法

    Prim算法又称P氏法,对一个加权图形G=(V,E),设V={1,2,…,n},假设U={1},也就是说,U和V是两个顶点的集合
    然后从U-V差集所产生的集合找出一个顶点x,该顶点x能与U集合中的某点形成最小成本边,且不会造成回路。然后将顶点x加入U集合中,反复执行同样的步骤,一直到U集合等于V集合(U=V)为止

    接下来,我们实际使用P氏法求出下图的最小生成树
    未命名文件 (1).png

    从此图中可得V={1,2,3,4,5,6},U=1
    步骤1:从V-U={2,3,4,5,6}中找一个顶点与U顶点能形成最小成本的边
    步骤2:V-U={2,3,4,6},U={1,5}。从V-U中找到一个顶点与U顶点能形成最小成本的边
    步骤3:U={1,5,6},V-U={2,3,4}。同理找到顶点4
    步骤4:U={1,5,6,4},V-U={2,3},同理找到顶点3
    步骤5:U={1,5,6,4,3},V-U={2},同理找到顶点2
    未命名文件.png

    2.Kruskal算法

    Kruskal算法是将各边按权值大小从小到大排列,接着从权值最低的边开始建立最小成本生成树,如果加入的边会造成回路则舍弃不用,直到加入了n-1个边为止
    未命名文件.png
    步骤01:把所有边的成本列出并从小到大排序

    起始顶点 终止顶点 成本
    B C 3
    B D 5
    A B 6
    C D 7
    B F 8
    D E 9
    A E 10
    D F 11
    A F 12
    E F 16

    步骤02:选择成本最低的一条边作为最小成本树的起点
    未命名文件 (1).png
    步骤03:按所建立的表格,按序加入边
    未命名文件.png

    步骤04:C-D加入会形成回路,所以直接跳过
    未命名文件 (1).png
    步骤05:完成图
    未命名文件 (2).png

    用python语言编写的Kruskal算法:

    VERTS=6                #图的顶点数
    
    class edge:            #声明边的类
        def __init__(self):
            self.start=0
            self.to=0
            self.find=0
            self.val=0
            self.next=None
    
    v=[0]*(VERTS+1)   
    
    
    def findmincost(head):  #搜索成本最小的边
        minval=100
        ptr=head
        while ptr!=None:
            if ptr.val<minval and ptr.find==0: #假如ptr.val的值小于minval
                minval=ptr.val                 #就把ptr.val设为最小值
                retptr=ptr                     #并且把ptr纪录下来
            ptr=ptr.next
        retptr.find=1  #将retptr设为已找到的边
        return retptr  #返回retptr
            
    
    def mintree(head):                    #最小成本生成树函数
        global VERTS
        result=0
        ptr=head
        for i in range(VERTS):
            v[i]=0
        while ptr!=None:
            mceptr=findmincost(head)
            v[mceptr.start]=v[mceptr.start]+1
            v[mceptr.to]=v[mceptr.to]+1
            if v[mceptr.start]>1 and v[mceptr.to]>1:
                v[mceptr.start]=v[mceptr.start]-1
                v[mceptr.to]=v[mceptr.to]-1
                result=1
            else:
                result=0
            if result==0:
                print('起始顶点 [%d] -> 终止顶点 [%d] -> 路径长度 [%d]' 
                      %(mceptr.start,mceptr.to,mceptr.val))
            ptr=ptr.next
    

    2.1程序说明
    2.1.1功能说明
    使用一个二维数组存储树并对K使法的成本表进行排序,试设计一个python程序来求取最小成本生成树

    2.1.2源程序

    VERTS=6                #图的顶点数
    
    class edge:            #声明边的类
        def __init__(self):
            self.start=0
            self.to=0
            self.find=0
            self.val=0
            self.next=None
    
    v=[0]*(VERTS+1)   
    
    
    def findmincost(head):  #搜索成本最小的边
        minval=100
        ptr=head
        while ptr!=None:
            if ptr.val<minval and ptr.find==0: #假如ptr.val的值小于minval
                minval=ptr.val                 #就把ptr.val设为最小值
                retptr=ptr                     #并且把ptr纪录下来
            ptr=ptr.next
        retptr.find=1  #将retptr设为已找到的边
        return retptr  #返回retptr
            
    
    def mintree(head):                    #最小成本生成树函数
        global VERTS
        result=0
        ptr=head
        for i in range(VERTS):
            v[i]=0
        while ptr!=None:
            mceptr=findmincost(head)
            v[mceptr.start]=v[mceptr.start]+1
            v[mceptr.to]=v[mceptr.to]+1
            if v[mceptr.start]>1 and v[mceptr.to]>1:
                v[mceptr.start]=v[mceptr.start]-1
                v[mceptr.to]=v[mceptr.to]-1
                result=1
            else:
                result=0
            if result==0:
                print('起始顶点 [%d] -> 终止顶点 [%d] -> 路径长度 [%d]' 
                      %(mceptr.start,mceptr.to,mceptr.val))
            ptr=ptr.next
                
    #成本表数组
    data=[[1,2,6],[1,6,12],[1,5,10],[2,3,3], 
          [2,4,5],[2,6,8],[3,4,7],[4,6,11], 
          [4,5,9],[5,6,16]]
    head=None
    #建立图的链表
    for i in range(10):
        for j in range(1,VERTS+1):
            if data[i][0]==j:
                newnode=edge()
                newnode.start=data[i][0]
                newnode.to=data[i][1]
                newnode.val=data[i][2]
                newnode.find=0
                newnode.next=None
                if head==None:
                    head=newnode
                    head.next=None
                    ptr=head
                else:
                    ptr.next=newnode
                    ptr=ptr.next
                
    print('-------------------------------------------------')
    print('建立最小成本生成树:')
    print('-------------------------------------------------')
    mintree(head)                        #建立最小成本生成树
    

    2.1.3运行结果

    -------------------------------------------------
    建立最小成本生成树:
    -------------------------------------------------
    起始顶点 [2] -> 终止顶点 [3] -> 路径长度 [3]
    起始顶点 [2] -> 终止顶点 [4] -> 路径长度 [5]
    起始顶点 [1] -> 终止顶点 [2] -> 路径长度 [6]
    起始顶点 [2] -> 终止顶点 [6] -> 路径长度 [8]
    起始顶点 [4] -> 终止顶点 [5] -> 路径长度 [9]
    

    三.图的最短路径法

    在一个有向图G=(V,E)中,每一条边都有一个比例常数W(Weight)与之对应,如果想求G图中某一个顶点V到其他顶点的最少W总和之值,这类问题就称为最短路径问题(The Shortest Path Problem)

    最小成本生成树(MST,或称最小花费生成树)就是计算连通网络中每一个顶点所需的最少花费,但是连通树中任意两顶点的路径不一定是一条花费最少的路径,这也是本节将研究最短路径问题的主要理由。一般讨论的方向有两种:一种是Dijkstra算法与A算法,另一种是Floyd算法

    1.Dijkstra算法与A算法

    1.1Dijkstra算法
    一个顶点到多个顶点通常使用Dijkstra算法求得,Dijkstra的算法如下:
    假设S={Vi | V````V},且``Vi在已发现的最短路径中,其中V``S是起点


    假设w∉S,定义Dist(w)是从V到w的最短路径,这条路径除了w外必属于S,且有下列几点特性:

    1. 如果u是当前所找到最短路径的下一个节点,则u必属于V-S集合中最小成本的边
    2. 若u被选中,将u加入S集合中,则会产生当前的从V到u的最短路径,对于w∉S,DIST(w)被改变成DIST(w)<—Min{DIST(w),DIST(u)+COST(u,w)}

    步骤如下:
    步骤01:首先进行定义

    G=(V,E)
    D[K]=A[F,K] 其中K从1到N
    S={F}
    V={1,2,.....N}
    
    • D为一个N维数组,用来存放某一顶点到其他顶点的最短距离
    • F表示起始顶点
    • A[F,I]为顶点F到I的距离
    • V是网络中所有顶点的集合
    • E是网络中所有边的组合
    • S也是顶点的集合,其初始值是S={F}

    步骤02:从V-S集合中找到一个顶点x,使D(x)的值为最小值,并把x放入S集合中
    步骤03:按公式D[I]=min(D[I],D[x]+A[x,I])(其中(x,I)∈E)来调整D数组的值,其中I是指x的相邻各顶点
    步骤04:重复执行步骤2,一直到V-S是空集合为止

    现在来直接看一个例子。在下图中,找出顶点5到各顶点间的最短路径
    未命名文件.png

    做法相当简单,首先从顶点5开始,找出顶点5到各顶点间最小的距离,到达不了的以∞表示。步骤如下:
    步骤01:D[0]=∞,D[1]=12,D[2]=∞,D[3]=20,D[4]=14。在其中找出值最小的顶点并加入S集合中D[1]
    步骤02:D[0]=∞,D[1]=12,D[2]=18,D[3]=20,D[4]=14。D[4]最小,加入S集合中
    步骤03:D[0]=26,D[1]=12,D[2]=18,D[3]=20,D[4]=14。D[2]最小,加入S集合中
    步骤04:D[0]=26,D[1]=12,D[2]=18,D[3]=20,D[4]=14。D[3]最小,加入S集合中
    步骤05:加入最后一个顶点,即可得到下面的数据

    步骤 S 0 1 2 3 4 5 选择
    1 5 12 20 14 0 1
    2 5,1 12 18 20 14 0 4
    3 5,1,4 26 12 18 20 14 0 2
    4 5,1,4,2 26 12 18 20 14 0 3
    5 5,1,4,2,3 26 12 18 20 14 0 0

    从顶点5到其他各顶点的最短距离为:

    • 顶点5—>顶点0:26
    • 顶点5—>顶点1:12
    • 顶点5—>顶点2:18
    • 顶点5—>顶点3:20
    • 顶点5—>顶点4:14

    程序说明
    1.功能要求
    使用Dijkstra算法来求取下面图结构中顶点1对全部图的顶点间的最短路径

    Path_Cost = [ [1, 2, 29], [2, 3, 30],[2, 4, 35], 
                  [3, 5, 28],[3, 6, 87],[4, 5, 42], 
                  [4, 6, 75],[5, 6, 97]]
    

    2.源程序

    SIZE=7  
    NUMBER=6
    INFINITE=99999 # 无穷大  
    
    Graph_Matrix=[[0]*SIZE for row in range(SIZE)] # 图的数组
    distance=[0]*SIZE  # 路径长度数组
    
    def BuildGraph_Matrix(Path_Cost):
        for i in range(1,SIZE):
            for j in range(1,SIZE):
                if i == j :
                    Graph_Matrix[i][j] = 0 # 对角线设为0
                else:
                    Graph_Matrix[i][j] = INFINITE
        # 存入图的边
        i=0
        while i<SIZE:
            Start_Point = Path_Cost[i][0]
            End_Point = Path_Cost[i][1]
            Graph_Matrix[Start_Point][End_Point]=Path_Cost[i][2]
            i+=1
                
    
    # 单点对全部顶点的最短距离  
    def shortestPath(vertex1, vertex_total):
        shortest_vertex = 1   #记录最短距离的顶点
        goal=[0]*SIZE         #用来记录该顶点是否被选取
        for i in range(1,vertex_total+1):
            goal[i] = 0
            distance[i] = Graph_Matrix[vertex1][i]
        goal[vertex1] = 1
        distance[vertex1] = 0
        print()
    
        for i in range(1,vertex_total):
            shortest_distance = INFINITE
            for j in range(1,vertex_total+1):
                if goal[j]==0 and shortest_distance>distance[j]:
                    shortest_distance=distance[j]
                    shortest_vertex=j
                
            goal[shortest_vertex] = 1
            # 计算开始顶点到各顶点的最短距离 
            for j in range(vertex_total+1):
                if goal[j] == 0 and 
                   distance[shortest_vertex]+Graph_Matrix[shortest_vertex][j] 
                   <distance[j]:
                    distance[j]=distance[shortest_vertex] 
                    +Graph_Matrix[shortest_vertex][j]
    
    # 主程序
    global Path_Cost
    Path_Cost = [ [1, 2, 29], [2, 3, 30],[2, 4, 35], 
                  [3, 5, 28],[3, 6, 87],[4, 5, 42], 
                  [4, 6, 75],[5, 6, 97]]
    
    BuildGraph_Matrix(Path_Cost)
    shortestPath(1,NUMBER) # 搜索最短路径 
    print('-----------------------------------')
    print('顶点1到各顶点最短距离的最终结果')
    print('-----------------------------------')
    for j in range(1,SIZE):
        print('顶点 1到顶点%2d的最短距离=%3d' %(j,distance[j]))
    print('-----------------------------------')
    print()
    

    3.运行结果

    -----------------------------------
    顶点1到各顶点最短距离的最终结果
    -----------------------------------
    顶点 1到顶点 1的最短距离=  0
    顶点 1到顶点 2的最短距离= 29
    顶点 1到顶点 3的最短距离= 59
    顶点 1到顶点 4的最短距离= 64
    顶点 1到顶点 5的最短距离= 87
    顶点 1到顶点 6的最短距离=139
    

    2.A算法




    3.Floyd算法

    Dijkstra的方法只能求出某一点到其他顶点的最短距离,如果要求出图中任意两点甚至所有顶点间最短的距离,就必须使用Floyd算法。

    Floyd算法定义:

    1. A[i][j]=ming{A[i][j],A[i][k]+A[k][j]},k>=1。k表示经过的顶点,A[i][j]为从顶点i到j的经由k顶点的最短路径
    2. A[i][j]=COST[i]j,A为顶点i到j间的直通距离
    3. A[i,j]代表i到j的最短距离,即A便是我们所要求出的最短路径成本矩阵

  • 相关阅读:
    Java匹马行天下之C国程序员的秃头原因
    Java匹马行天下之学编程的起点——高级语言大锅烩
    jdbc连接案例
    Java匹马行天下之学编程的起点——走进编程的殿堂
    Java匹马行天下之学编程的起点——编程常识知多少
    cookie、session和application超详解说
    匹马行天下之博客园五月纪念日——去你的写博无用论
    匹马行天下之高薪编程,品牌公司——人往高处走,作为程序员的你够格吗
    MySQL中boolean类型设置
    python使用rsa库做公钥解密(网上别处找不到)
  • 原文地址:https://www.cnblogs.com/LQ6H/p/10346663.html
Copyright © 2011-2022 走看看