单源最短路径(分支限界)

优先级:当前路径长度

剪枝函数:由于图G中各边的权均非负,所以结点所对应的当前路长也是解空间树中以该结点为根的子树中所有结点对应的路长的一个下界。扩展结点的过程中,一旦发现一个结点的下界不小于当前找到的最短路长,则算法剪去以该结点为根的子树。

 

数据的存储:

①二维数组Type G[n][n]存储邻接矩阵

②数组Type dist[n]记录源点到各顶点的距离

③数组int prev[n]记录从源到各顶点路径上的前驱顶点

Graph

template <class Type>
class Graph{
    friend void main();
 public:
    void ShortestPaths(int);
 private:
    int n,        //顶点数
        *prev;    //前驱数组
    Type **c,     //邻接矩阵
        *dist;    //最短距离数组
};

 堆中顶点类MinHeapNode:

template <class Type>
class MinHeapNode{
    friend Graph<Type>;//友元类
public:
    bool operator<(const MinHeapNode& N)const{ return length<N.length; }
private:
    int i;        //顶点编号
    Type length;  //当前路径长度
}

具体算法:

template<class Type>
void Graph<Type> ::ShortestPaths(int v){
    priority_queue< MinHeapNode<Type> > H;
    //初始化
    MinHeapNode<Type> E;
    E.i=v;
    E.length=0;
    dist[v]=0;
    while(true){
        for(int j=1;j<=n;j++){//遍历所有顶点判断是否与i存在边
            if( (c[E.i][j]<inf) && (E.length+c[E.i][j]<dist[j]) ){//如果ij有边,而且经过i到达j的路径比当前更短,更新
                dist[j]=E.length+c[E.i][j];
                prev[j]=E.i;
                //添加新的结点
                MinHeapNode<Type> N;
                N.i=j;
                N.length=dist[j];
                H.push(E);
            }
        }
        if(H.empty())
            break;
        bool found=false;
        while(!H.empty()){
            E=H.top();
            H.pop(); 
            if(E.length==dist[E.i]){//判断是不是最新的结点
                 found=true;   
                 break;
            }
        }
        if(!found) break;
    }
       
}

tips:

  • 这个算法没有对已经求得最短路径的点进行标记,因此可能后续还会访问到(仅仅判断),但是一定不会再次加入活结点表
  • 如果找到更优的路径,要对dist和prev进行更新,但是活结点表中的原来的点不必删除,加入新的结点,以后肯定先访问到所有加入的点中最优的那个

 

  • 3
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hnu哈哈

请接受直女的么么哒????

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值