You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

邻接矩阵实现最宽路径问题:修改版Dijkstra路径打印异常排查

问题排查与修复方案

1. 路径打印异常问题根因

  • previous数组初始化错误:现有代码仅将previous[0] = -1,其余元素为内存随机值,导致printPath中previous[j] != -1的终止判断失效,无法输出中间节点。
  • 路径输出顺序错误:现有printPath从终点向起点遍历直接打印,输出的是倒序路径,和起点拼接后逻辑错误。
  • 隐式声明异常:若island.h中未对dijkstra_mod、printSolution等函数做前置声明,C语言会触发隐式声明规则,参数类型不匹配会导致printf输出异常值(如你提到的类地址值)。
  • 节点输入范围校验错误:你的图大小为9,合法节点索引为0~8,现有代码判断current_node >9、destination>10范围错误,且未做循环校验,输入非法值后仅提示一次就继续执行。

2. Dijkstra算法逻辑错误根因

你的需求是边权均大于卡车重量的前提下,找最大瓶颈路径(路径最小边权尽可能大)、瓶颈相同时选边数最少的路径,现有实现完全不符合需求:

  • 松弛逻辑错误:最大瓶颈路径的权重计算不是边权累加,而是取路径上的最小边权。现有代码使用sptWeight[u] + Graph[u][v]的累加逻辑完全错误,且初始化sptWeight为INT_MIN,累加值永远大于初始值,根本不会触发更新逻辑。
  • 未过滤不可通行边:完全没有增加Graph[u][v] > truck_weight的判断,会把不能承载卡车重量的边纳入路径计算。
  • 未处理边数最少的优先级:相同瓶颈值下没有比较路径长度,无法保证输出边数最少的路径。

3. 修复后的核心代码

打印逻辑修复

// 递归打印保证路径顺序正确
void printPath(int previous[], int j){
    if(previous[j] == -1) return;
    printPath(previous, previous[j]);
    printf("%d -> ", j);
}

void printSolution(int destination, int source, int previous[SIZE], int sptBottleneck[SIZE]){
    if(sptBottleneck[destination] == INT_MIN){
        printf("\n无符合载重要求的路径从 %d 到 %d\n", source, destination);
        return;
    }
    printf("\n%d 到 %d \t 最大瓶颈载重: %d\t 路径: %d -> ", source, destination, sptBottleneck[destination], source);
    printPath(previous, destination);
    printf("\n");
}

Dijkstra核心逻辑修复

// 没有min宏可以自己实现,避免引入额外依赖
#define min(a,b) ((a)<(b)?(a):(b))

void dijkstra_mod(int Graph[SIZE][SIZE], int source, int destination, int truck_weight){
    int sptBottleneck[SIZE]; // 存储到每个节点的最大瓶颈值
    int pathLen[SIZE]; // 存储到每个节点的路径边数,同瓶颈下选边数少的
    bool sptSet[SIZE];
    int previous[SIZE];
    // 全数组初始化
    for(int i = 0; i < SIZE; i++){
        sptBottleneck[i] = INT_MIN;
        pathLen[i] = INT_MAX;
        sptSet[i] = false;
        previous[i] = -1;
    }
    sptBottleneck[source] = INT_MAX; // 起点瓶颈设为无穷大
    pathLen[source] = 0;

    for(int count = 0; count < SIZE-1; count++){
        int u = maxSupportWeight(sptBottleneck,sptSet);
        if(u == -1) break; // 无可达节点直接退出
        sptSet[u] = true;
        for(int v = 0; v < SIZE; v++){
            // 过滤未加入spt、边存在、边权满足载重要求的边
            if(!sptSet[v] && Graph[u][v] && Graph[u][v] > truck_weight){
                int new_bottleneck = min(sptBottleneck[u], Graph[u][v]);
                // 新路径瓶颈更大,直接更新
                if(new_bottleneck > sptBottleneck[v]){
                    previous[v] = u;
                    sptBottleneck[v] = new_bottleneck;
                    pathLen[v] = pathLen[u] + 1;
                }
                // 瓶颈相同,新路径边数更少,更新
                else if(new_bottleneck == sptBottleneck[v] && pathLen[u] + 1 < pathLen[v]){
                    previous[v] = u;
                    pathLen[v] = pathLen[u] + 1;
                }
            }
        }
    }
    printSolution(destination, source, previous, sptBottleneck);
}

节点输入校验修复(main.c中对应逻辑替换)

printf("Inserisci il nodo di partenza\n");
scanf("%d", &current_node);
while(current_node < 0 || current_node >= SIZE){
    printf("Nodo di partenza non riconosciuto,输入范围为0~%d,请重新输入:\n", SIZE-1);
    scanf("%d", &current_node);
}
printf("Inserisci la tua destinazione\n");
scanf("%d", &destination);
while(destination < 0 || destination >= SIZE){
    printf("Destinazione non riconosciuta,输入范围为0~%d,请重新输入:\n", SIZE-1);
    scanf("%d", &destination);
}

额外注意:要在island.h中添加所有对外暴露函数的前置声明,避免隐式声明导致的参数解析异常。

内容的提问来源于stack exchange,提问作者Nicholas Marsicano

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.19 18:36:04