Day12:单源最短路径的C语言实现

1. Dijkstra算法的思想

对于一个图,求从某个顶点出发到其它顶点的最短路径,就是单源最短路径问题。
Dijkstra算法是求单源最短路径的经典算法,它设置以下集合:

  • 真假数组visited:记录已求得和尚未求得最短路径的顶点
    (也可以设置两个顶点集合visited和unvisited)
  • 路径数组dist:记录当前求得到某顶点的最短路径长度
    (某个顶点的visited为真时,dist中对应记录的是最终求得的最短路径)
  • 顶点数组path:记录已经求得最短路径的顶点其前驱结点
    (可用于回溯构建路径)

算法流程如下:

  1. 初始时,设置出发顶点v0已求得,最短路径长为0,前驱顶点为v0
  2. 将dist设置为v0到相邻结点的弧的权值,path设为v0;非相邻结点设为无穷大,path设为-1
  3. 在dist中选择一条最短的路径,对应的vi即求得了最短路径
  4. 更新dist和path,若有value[i][j] + dist[i] < dist[j],说明有更短的路径,修改对应的dist[j]和path[j]
  5. 重复3、4,直到所有的顶点都已经求得最短路径,visited数组全真

2. Dijkstra算法的C语言实现

对Day9的邻接矩阵加以简单改造,使其可以表示带权有向图。

// 只需修改这一函数
void MatrixGraphInserArc(MatrixGraph *mg, char vex1, char vex2, int value)
{
    int vexNo1 = MatrixGraphLocateVex(mg, vex1);
    int vexNo2 = MatrixGraphLocateVex(mg, vex2);
    if(vexNo1 < 0 || vexNo2 < 0)
        return;
    mg->arcs[vexNo1][vexNo2] = value;
    mg->arcNum++;
}

Dijkstra算法的函数如下:

void Dijkstra(MatrixGraph *mg, char startVex, int dist[], int path[])
{
    // 初始设置
    int start = MatrixGraphLocateVex(mg, startVex);
    int *visited = malloc(sizeof(int) * mg->vexNum);
    memset(visited, 0, sizeof(int) * mg->vexNum);
    for(int i = 0;i < mg->vexNum;i++) {
        if(mg->arcs[start][i] == 0) {
            dist[i] = 0x7fffffff;       // int型最大整数
            path[i] = -1;
        }
        else {
            dist[i] = mg->arcs[start][i];
            path[i] = start;
        }
    }
    visited[start] = 1;
    dist[start] = 0;
    path[start] = 0;
    // 贪心选择
    for(int i = 0;i < mg->vexNum - 1;i++) {     // 共进行vexNum - 1次贪心选择
        int minValue = 0x7fffffff;
        int v = -1;
        for(int j = 0;j < mg->vexNum;j++) {     // 找到最短的路径长度
            if(visited[j] == 0 && dist[j] < minValue) {
                v = j;
                minValue = dist[j];
            }
        }
        if(v == -1)
            return;                             // 非连通图,未连通start的最短路径为无穷,前驱为-1
        visited[v] = 1;                         // 当前最短为已经求得
        for(int j = 0;j < mg->vexNum;j++) {     // 更新dist和path
            if(visited[j] == 0 && mg->arcs[v][j] > 0 && mg->arcs[v][j] + dist[v] < dist[j]) {       // 未求得的点,邻接到v且路径更短,则更新
                dist[j] = mg->arcs[v][j] + dist[v];
                path[j] = v;
            }
        }
    }
}
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
分支限界法(Branch and Bound)是一种求解最优化问题的算法,它将问题分解成多个子问题,并通过优先级队列选取当前最有希望的子问题进行求解。在单源最短路径问题中,分支限界法可以用来找到从源点到其他各个顶点的最短路径。 对于单源最短路径,我们可以使用Dijkstra算法或者Bellman-Ford算法来解决。但是当图中边的权重为负值时,Dijkstra算法不能正确处理。因此,分支限界法可以作为一种解决带有负权边的单源最短路径问题的方法。 分支限界法的基本思想是将问题空间划分为多个子空间,并通过限定条件来减少搜索空间。在单源最短路径问题中,我们可以通过设定一个上界来限制搜索的深度,以避免搜索过程中陷入无限循环。 具体实现分支限界法的步骤如下: 1. 初始化一个优先级队列,将源点加入队列。 2. 从优先级队列中选取优先级最高的节点,并向其邻接节点扩展,计算当前路径长度。 3. 若当前路径长度小于已知最短路径长度,则更新最短路径长度,并将该节点加入优先级队列中。 4. 重复步骤2和3,直到搜索到目标节点或者优先级队列为空。 在C语言实现分支限界法的单源最短路径算法,可以使用邻接矩阵或邻接表来表示图结构,并通过优先级队列来实现分支限界法的搜索过程。具体实现时需要定义适当的数据结构算法逻辑来处理节点的扩展和路径长度的计算。 总之,分支限界法是一种有效解决带有负权边的单源最短路径问题的方法,它通过划分搜索空间和限定搜索条件来减少问题规模,从而达到高效求解的目的。在C语言实现分支限界法的单源最短路径算法需要合理选择数据结构算法逻辑,以实现路径长度的计算和节点的扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值