【问题标题】:C program doesn't start, implementing Dijkstras algorithmC 程序不启动,实现 Dijkstras 算法
【发布时间】:2020-08-04 18:19:47
【问题描述】:

我正在为应该以非常具体的方式编码的课程做作业。这是目标:

目标:实现单源最短路径问题的 Dijkstra 算法 对于给定的有向图,使用邻接矩阵表示 图表。

我正在使用 Makefile 来编译代码。输入将通过终端/控制台./a7 < datafile 进行。以下是输入示例:

6 11 0
0 1 50
0 2 10
0 4 45
1 2 15
1 4 10
2 0 20
2 3 15
3 1 20
3 4 35
4 3 30
5 4 03

以及预期的输出:

0 2 10
0 3 25
0 1 45
0 4 45
0 5 INF (no path)

代码如下:

#include <limits.h> /* for INT_MAX */
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>

#define N 10 /* max matrix size is 10 x 10 */
#define INF INT_MAX /* infinity? */

int main(int argc, char **argv) {
  void getdata(int amtrx[][N], int *sz, int *stv);
  void dijkstras(int amtrx[][N], int src);

  if (argc < 2) {
    printf("Missing Filename.\n");
    return(1);
  } else if (argc > 2) {
    printf("Too many arguments.\n");
    return(1);
  }
  FILE *f = fopen(argv[1], "r");

  int amtrx[N][N], *sz, *stv;
  stv = malloc(sizeof(int));
  sz = malloc(sizeof(int));
  getdata(amtrx, sz, stv);

  dijkstras(amtrx, *stv);

  fclose(f);
  return(0);
}

void getdata(int amtrx[][N], int *sz, int *stv) {
  int i, j, nsz, nedg, fr, to, vtx, wt;
  scanf("%d %d %d", &nsz, &nedg, &vtx);
  for(i = 0; i < nsz; i++)
    for(j = 0; j < nsz; j++)
      amtrx[i][j] = INF;
  for(i = 0; i < nedg; i++) {
    scanf("%d %d %d", &fr, &to, &wt);
    amtrx[fr][to] = wt;
    amtrx[to][fr] = wt;
  }
  *sz = nsz;
  *stv = vtx;
}

void dijkstras(int amtrx[][N], int src) {
  void printpaths(int amtrx[][N]);
  int mindistance(int dist[], bool sptSet[]);

  int dist[N];
  bool sptSet[N];
  int i, count, v, u;

  for (i = 0; i < N; i++)
    dist[i] = INF, sptSet[i] = false;

  dist[src] = 0;

  for (count = 0; count < N - 1; count++) {
    u = mindistance(dist, sptSet);

    sptSet[u] = true;

    for (v = 0; v < N; v++)
      if (!sptSet[v] && amtrx[u][v] && dist[u] != INF && dist[u] + amtrx[u][v] < dist[v]) {
        dist[v] = dist[u] + amtrx[u][v];
      }
    }
    printpaths(amtrx);
}

int mindistance(int dist[], bool sptSet[]) {
  int min = INF, min_index;
  int v;

  for (v = 0; v < N; v++)
    if (sptSet[v] == false && dist[v] <= min)
      min = dist[v], min_index = v;

  return min_index;
}

void printpaths(int amtrx[N][N]) {
  //to be written
}

到目前为止,它只是永远运行并且不打印任何内容。我怀疑可能是一个无限循环,但我看不到它发生在哪里。我试图在 GDB 中运行,它只是说Starting program: /a7 datafile 并且无处可去。我也想帮助确保我的算法是正确的,但如果需要,我可以将其保存为另一个问题。提前致谢!

【问题讨论】:

  • 提示:您的程序在打开f 后会做什么?

标签: c algorithm dijkstra adjacency-matrix


【解决方案1】:

要在 gdb 的帮助下找出问题所在,您通常需要以步进模式运行程序,以查看它挂起或循环的位置和原因。

  1. 确保使用调试符号编译程序(如果您使用 gcc 或类似的编译器,则需要 -g 选项)。
  2. 为避免在步进模式下遍历整个程序,您可以在您认为程序挂起时在 gdb 中按 Ctrl-C,然后输入命令 bt。它会告诉你你的程序在哪里。然后你可以输入命令cont,一段时间后中断程序执行,看看你是在不同的地方,还是在同一个地方……
  3. 如果您在第 2 步后仍然不知道问题的原因是什么,您可以kill 编程并在您确定为程序挂起/循环的位置之前设置断点 - -- 阅读关于 break 的 gdb 文档,了解如何设置断点。

这里是 CMU 托管的 gdb 教程链接:https://www.cs.cmu.edu/~gilpin/tutorial/

【讨论】:

  • 非常感谢您的回答!我以另一种方式解决了这个问题,但我一定会记住这一点!我发现我需要以另一种方式使用文件,甚至不涉及打开它们?!我会尽快发布另一个问题,所以请留意它:)
  • 使用调试器”真的是一个答案吗?
  • 这个问题可以有多种解释。当然我可以回答“你需要用 fscanf 替换 scanf”,但我认为在这种情况下,给出一个通用的方法来找出为什么程序没有做它应该做的事情,这更适合 SO 和问题的标题。
  • @Slimak -- 无论如何,我认为用fscanf() 替换scanf() 不会有帮助; OP 似乎已将输入从文件重定向到 stdin./a7 &lt; datafile
  • @exnihilo --- 我错过了&lt; --- 可能是因为当我测试程序时,当没有给出文件名作为唯一参数而不是挂起(挂起)时,它正确地出错了成为提出问题的原因。
猜你喜欢
  • 1970-01-01
  • 2023-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多