zoukankan      html  css  js  c++  java
  • Prim算法与Dijkstra算法的联系与区别

    /* 图结构,邻接矩阵形式 */
    
    ElemType nodes[n];
    
    int edges[n][n];
    
    
    prim_or_dijkstra( int index, bool usePrim )     /* 起点 */
    
    {
        int dist[n] = { INF };                  /* 从起点开始,到其他所有边的距离 */
    
        int distIndex[n] = { -1 };
    
        int visited[n] = { 0 };
    
        int selected = index;                   /*选中的点 */
    
    /* 初始化起点的可达边距离 */
    
        for ( i = 0; i < nodes.length; i++ )
    
    /* edges[起点][终点]=权重(不是INF就有边),穷举 */
    
        {
            if ( visited[i] )
                break;
    
            visited[i] = true;
    
            if ( edges[selected][i] != INF )
            {
                dist[i] = edges[selected][i];   /* index到可达边的距离 */
            }
        }
    
    
        for ( k = 0; k < nodes.length - 1; k++ )        /* n-1次循环取点 */
    
        {
            visited[selected] = true;
    
            int min = INF;
    
            int sel = -1;
    
            for ( i = 0; i < nodes.length; i++ )
    
    /* edges[起点][终点]=权重(不是INF就有边),穷举 */
    
            {
                if ( visited[i] )
                    break;  /* 属于同一集合,不必考虑 */
    
                if ( edges[selected][i] != INF )
                {
                    if ( min > dist[i] )
                    {
                        min = dist[i]; sel = i;
                    }
    
    /* min=已经被选中的点的集合到其他单独的点的最短距离 */
    
    /* sel=相应的点 */
                }
            }
    
            distIndex[sel] = selected; /* sel->selected映射,存放边 */
    
    /* 一个sel只对应一个selected, */
    
    /* 一个selected对应多个sel */
    
    /* 第一次distIndex v2->v1 */
    
            selected = sel; /*选中的点要更新 */
    
    /* 此时 */
    
    /* prim中令 dist[selected]=0 */
    
    /* dijkstra不添加代码 */
    
            if ( usePrim )
            {
                dist[selected] = 0;
            }
    
            for ( i = 0; i < nodes.length; i++ ) /* selected->i,更新其他边 */
    
    /* 由于selected已经是集合的一部分, */
    
    /* selected的可达边的距离属于集合的可达边的距离 */
    
            {
    /* 在所有的集合的可达边(不包含集合自身)的距离中取较小值 */
    
    /*下面是两种方法相同的部分 */
    
                if ( !visited[i]
    
                     && dist[i] > dist[selected] + edges[selected][i] )
    
                {
                    dist[i] = dist[selected] + edges[selected][i]
                }
            }
        }

    联系:

    两者在连边时,用的是同一种贪心策略,即对于将扩展的集合总是在非扩展的点中找一条最短的边入集合,并用新入集合的点修改剩下点的到集合的最短路。

    共同点:都有visited标记数组,dist数组,min,distIndex数组

    注意:网上大多数教程中,prim算法是没有visited数组的,它用令dist[]=0来简化,而在这里,两种方法都用了visited数组,减少了差异性

    区别:

    在于dist的修改和意义

    dijkstra仅仅就多了一个dist[selected],用做累积距离

    而prim中由于dist[selected]=0,故可消去dist[selected]

    prim

    if(!visited[i] && dist[i] > edges[selected][i])

    {dist[i] = edges[selected][i];}

    //解释:prim中集合内部的边看做短路,可忽略,长度为0

    dijkstra

    if(!visited[i]

    && dist[i] > dist[selected]+ edges[selected][i])

    {dist[i] = dist[selected]+ edges[selected][i]}

    //解释:dijkstra中集合内部的边不可忽略,长度存在

  • 相关阅读:
    爬虫项目数据解析方式
    数据分析
    爬虫项目代理操作和线程池爬取
    Python网络爬虫
    Django多表操作
    网络编程
    python中什么是元类
    Python面向对象中super用法与MRO机制
    mysql之pymysql
    mysql之索引原理
  • 原文地址:https://www.cnblogs.com/bajdcc/p/4738070.html
Copyright © 2011-2022 走看看