【问题标题】:Creating adjacency matrix from graph从图创建邻接矩阵
【发布时间】:2018-12-03 03:10:24
【问题描述】:

我正在尝试从图形文件创建邻接矩阵。

我需要读入一个包含顶点数的文本文件,然后列出图形格式

例如:

5
0 3 2
1 0 2
1 2 2
1 4 1

第一列数字是源顶点的id,第二列是目标顶点的id,第三列是边的权重

所以这应该返回矩阵

0 2 0 2 0
2 0 2 0 1
0 2 0 0 0
2 0 0 0 0
0 1 0 0 0

到目前为止,我已经阅读了文本文件并获得了顶点的数量,但我不确定从这里开始做什么。

我当前的代码:

#include <stdio.h>
#include <stdlib.h>

int main (){

    printf("Enter the file contianing the graph\n");

    char filename[20];
    FILE *myFile;
    scanf("%s",filename);
    myFile = fopen (filename,"r");

    int number_of_nodes, number_of_edges;
    int source_id[100], target_id[100], weight[100];
    int matrix[100][100];
    int i;      
    if (myFile == NULL){
        printf("File not found! Exiting...\n");
        return -1;
    }
    else{
        fscanf(myFile, "%d", &number_of_nodes);
        printf("There are %d vertices.\n", number_of_nodes);
        for(i = 0; i < (sizeof (source_id) / sizeof ( source_id[0] )); i++)
        {
 if( fscanf(myFile, "%d %d %d", &source_id[i], &target_id[i], &weight[i]) != 3)
           break;

        }
        number_of_edges = i;  

        for (i = 0; i<99;i++){
        for (int j = 0; j< 99; i++){
        matrix[i][j]=0;
        }
        }

        for (i = 0;  i < number_of_edges; i++){
          int x = source_id[i];
          int y = target_id[i];
          matrix[x][y] = weight[i];
          matrix[y][x] = weight[i];
          }

          for (int y = 0; y < (number_of_nodes-1); y++){
            for (int x = 0; x < (number_of_nodes -1); x++){
              printf(matrix[x][y]);
              printf(" \n");
            } 
         } 

    }


    fclose(myFile);

    return 0;
}

【问题讨论】:

  • 文件第一行是节点数还是最大节点ID?如果是第一个,那么为什么是 4,而不是 5?为什么元素 [4,4] 被设置为 1?
  • 对不起,应该是5,我放错了4
  • 当然最好检查语句 fscanf(myFile,"%d,",&numberArray[i]); 的返回码。此 IO 操作有时可能会失败...
  • @KrassiEm 你这是什么意思/我该如何改进它?

标签: c


【解决方案1】:

由于您只发布了用于读取文件的代码,因此我将对此部分进行评论和改进。

首先,您可以更好地定义变量。在下面的代码中,我删除了您的numberArray,而是定义了一个number_of_nodes 和三个用于源、目标和权重的单独数组。这样以后可以更轻松地参考这些数据。

其次,由于您没有文件中的项目(边)的数量,因此您必须通过查看fscanf()的返回值来检查读取是否成功。它返回成功读取的元素数。在您的情况下,您一次读取 3 个数字,因此您可以将返回值与 3 进行比较。您还想在退出循环后存储 i 的值,以便稍后知道有多少实际读取边缘。

第三,使用scanf("%s") 与使用gets() (Why is it bad?) 一样糟糕。您可能应该考虑限制输入长度,例如使用scanf("%19s")。我没有在下面的代码中修复它,因为它不是直接问题,但应该在您以后的开发中考虑。

最后,为您的文件打开检查 +1。在继续之前确保之前的操作成功完成是一种很好的做法。

这是我的固定代码:

#include <stdio.h>
#include <stdlib.h>

int main() {
    printf("Enter the file contianing the graph\n");

    char filename[20];
    FILE *myFile;
    scanf("%s", filename);
    myFile = fopen(filename, "r");

    int number_of_nodes, number_of_edges;
    int source_id[100], target_id[100], weight[100];

    int i;
    if (myFile == NULL) {
        printf("File not found! Exiting...\n");
        return -1;
    }
    else {
        fscanf(myFile, "%d", &number_of_nodes);
        printf("There are %d vertices.\n", number_of_nodes);
        for (i = 0; i < (sizeof(source_id) / sizeof(source_id[0])); i++) {
            if (fscanf(myFile, " %d %d %d", &source_id[i], &target_id[i], &weight[i]) != 3)
                break;
        }
        number_of_edges = i;
    }

    fclose(myFile);

    return 0;
}

对于接下来要做什么,我会给你一些提示,而不是直接编写完整的代码。如果你明白了这一点,那就相对容易了。

您想创建一个“矩阵”,或者用 C 的话来说,一个数组数组。简单来说,应该是这样的

int matrix[100][100];

然后您可以初始化矩阵并将其重置为零:

// This is pseudo-code
for i = 0 to 99
  for j = 0 to 99
    matrix[i][j] = 0

然后根据您从文件中读取的内容,您可以将值分配给归零矩阵。请记住分配两个值(x 给 y 和 y 给 x)

for edge in edges
  x = edge.source
  y = edge.target
  matrix[x][y] = edge.weight
  matrix[y][x] = edge.weight

要打印出矩阵,只需逐行遍历即可。不要忘记在每一行之后打印一个换行符。

for y = 0 to (number_of_nodes - 1)
  for x = 0 to (same as above)
    print matrix[x][y] and a space
  print a newline

如果您能理解以上所有想法,那么您就可以开始了。

【讨论】:

  • 感谢您帮助解决我的问题,您能否告诉我如何创建矩阵/将顶点读入单独的数组?我不太确定如何看待这个问题
  • @mike 将边读取到单独的数组中已经在那个大块 C 代码中实现了。在 C 中创建矩阵也在第一行代码中。其余部分以伪代码形式提供,供您理解(而非复制)。希望你玩得开心。
  • edge.source 我应该如何编码,我在想 number_of_edges.source_id[ ] 但它给了我错误
  • @mike source_id[i] 其中i 是一个数字。
  • 所以我尝试尽我所能遵循伪代码,并在 OP 中更新了我的代码,但是,在打印出顶点数后出现分段错误,我得到了分段错误,我不确定是什么原因造成的
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多