zoukankan      html  css  js  c++  java
  • 算法导论精华总结 ~ 图算法

    图的定义

      G=(V,E)

      G代表图

      V代表|V|为结点数

      E代表|E|为边的条数

    图的表示

       

      图的常规标准表示方式有两种,一种是邻接链表、一种是邻接矩阵。

      在稀疏图中多用链表,稠密图中多用矩阵。(稀疏与稠密看的是|E|与|V|的2次方的比较,|E|远远小于|V|的2次方为稀疏图)

      邻接链表的一大缺点是无法快速判断一条边是否是图中的,唯一的办法是搜索结点找边。

      图规模比较小时,更倾向于使用邻接矩阵表示法。

     广度优先搜索

      Prim的最小生成树算法和Dijkstra的单源最短路径算法都用了广度优先搜索。

      

    深度优先搜索

    最小生成树

      无向图中的最小权重树为最小生成树

      定义:在连通无向图G=(V,E)中找到一个无环子集T属于E,既能够将所有的结点(针脚)连接起来,又具有最小的权重。由于T是无环的,并且连通所有结点,因此,T必然是一棵树。我们称之为最小生成树。

    Kruskal算法和Prim算法

      这两个算法都是最小生成树算法

    Kruskal算法

      每次找最小的边,看是否在同一个树里(边(u,v)中u和v都在树里则为不安全)

      用的贪心策略

      下面为伪代码和解释

    MST-KRUSKAL(G,w)
        A=null
        for each vertex v∈G.V
            MAKE-SET(v) //初始化树根
        sort the edges of G.E into nondecreasing order by weight w
        for each edge(u,v)∈G.E, take in nondecreasing order by weight //循环边(最小权到最大权)
            if FIND-SET(u) != FIND-SET(v) //u与v是否同一棵树
                A=AU{(u,v)} //A中加入边(u,v)
                UNION(u,v) //两棵树中的结点合并
        return A

    Prim算法

      从一个点开始贪心其中最小的权边加入树中

      下面为伪代码

    MST-PRIM(G,w,r)
        for each u∈G.V                      //初始化每个结点u属于G.V
            u:key = 无限                     //u.key=无穷
            u:π = NIL                       //u.π=空
        r:key = 0;                          //根点的最小权为0
        Q=G.V                               //最小优先队列初始化为G.V
        while Q != null
            u=EXTRACT-MIN(Q)             //找Q中最小权点赋值给u
            for each v∈G.Adj[u]            //循环与u相连的点v
            if v∈Q and w(u,v) < v.key    //如果v属于Q 点u的权值加上边(u,v)的权值小于v.key
                v.π = u                    //v点的父结点 = u
                v.key = w(u,v)             //v点的权值 = 点u的权值加上边(u,v)的权值

    单源最短路径

      定义:给定一个图G=(V,E),我们希望找到从给定源结点s∈V到每个结点v∈V的最短路径。

      几个变体问题:

        1)单目的地最短路径问题:每个结点v到给定目的地点的最短路径

        2)单结点对最短路径问题:结点u到结点v的最短路径

        3)所有结点对最短路径问题:对于每个结点u和v,找到其最短路径

    最短路径的最优子结构

      两个结点之间的一条最短路径包含着其他的最短路径(最短路径的子路径也是最短路径)。

    最短路径的表示

      用前驱子图的表示方法,具体形式为每个结点开辟一个空间存储它的上一结点。(其实另开辟一个数组也是可以的)

    松弛操作

      松弛技术:对于每个结点v来说,我们维持一个属性v.d,用来记录从源结点s到结点v的最短路径权重的上界。我们称v.d为s到v的最短路径估计。

      松弛过程:v结点本身有一个最短估计值为v.d,又找到一条到v的路径把权值跟v.d进行比较,如果后者小,则更新v.d和v.π。

      以下是伪代码

    PELAX(u,v,w)
        if v.d > u.d + w(u,v) //如果新路径权值小于原来的估算权值
            v.d = u.d + w(u,v) //估算权值被更新
            v.π = u //前驱更新

    Bellman-Ford算法

      注意:此算法可处理边权值为负值的情况,此算法可判断出负值成环的存在。

      以下为伪代码

    BELLMAN-FORD(G,w,s)
    
        INITIALIZE-SINGLE-SOURCE(G,s) //初始化图
    
        for i = 1 to |G.V| - 1 //循环全部结点
            for each edge(u,v)∈G.E //循环每个结点所连边
                RELAX(u,v,w) //松弛操作
        
        for each edge(u,v)∈G.E //循环每条边
            if v.d > u.d + w(u,v) //测试是否还能松弛,从而找到环
                return FALSE //如果能松弛,则返回False
    
        return TRUE //运行正确放回True

    有向无环图的单源最短路径问题

      根据结点的拓扑排序次序来对带权重的有向无环图G=(V,E)进行边的松弛。

      注意:1.如果源结点s不是拓扑排序后的第一个结点,直到找到源结点s前的所有结点可以无视。

         2.边权非负

      以下是伪代码

    DAG-SHORTEST-PATHS(G,w,s)
        topologically sort the vertices of G //拓扑排序图G
        INITALIZE-SINGLE-SOURCE(G,s) //初始化G,并设源点s
        for each vertex u, taken in topologically sorted order //按拓扑排序后结点顺序循环结点
            for each vertex v∈G.Adj[u] //循环结点所连边
                RELAX(u,v,w) //松弛操作

    Dijkstra算法

      解决带权重的有向图上单源最短路径问题

      注意:1.边权非负

         2.Dijkstra算法比Bellman-Ford算法运行速度快。

      算法核心思想:重复从结点集V-S中选择最短路径估计最小的结点u,加入集合S,对从u出发的边进行松弛。(V为全部结点集合,S为已使用结点集合)

       以下是伪代码

    DIJKSTRA(G,w,s)
        INITIALIZE-SINGLE-SOURCE(G,s) //初始化图G,设源点s
        S=空 //初始化集合S为空
        Q=G.V //初始化集合Q,为V
        while Q != 空
            u = EXTRACT-MIN(Q) //找出Q中最小估算结点,赋值给u,并在Q中删除
            S = S U {u} //将结点u加入集合S中
            for each vertex v∈G.Adj[u] //循环与u相连的每个点
                RELAX(u,v,w) //松弛操作
     

      

      

  • 相关阅读:
    Maximum Depth of Binary Tree
    Single Number
    Merge Two Sorted Lists
    Remove Nth Node From End of List
    Remove Element
    Remove Duplicates from Sorted List
    Add Two Numbers
    编译视频直播点播平台EasyDSS数据排序使用Go 语言 slice 类型排序的实现介绍
    RTMP协议视频直播点播平台EasyDSS在Linux系统中以服务启动报错can’t evaluate field RootPath in type*struct排查
    【解决方案】5G时代RTMP推流服务器/互联网直播点播平台EasyDSS实现360°全景摄像机VR直播
  • 原文地址:https://www.cnblogs.com/SHOR/p/6266399.html
Copyright © 2011-2022 走看看