前提・実現したいこと
隣接行列が描かれたdatファイルを読み込んで、それをdot形式で描いた有向グラフが強連結であるか否かを判定するプログラムを作成しているのですが、強連結であるはずのグラフも「強連結ではありません」と出てしまいます。きちんと強連結のグラフに対して強連結と表示させるようにしたいです。find_path()の部分を作成したのですがどこか問題があるのでしょうか。
発生している問題・エラーメッセージ
強連結であるはずのグラフも「強連結ではありません」と表示されてしまう。
該当のソースコード
#include <stdio.h> #include <stdlib.h> #include <malloc.h> #define N 100 #define boolean int #define true 1 #define false 0 typedef boolean adjmatrix[N][N]; typedef int vindex; typedef struct edgecell{ vindex destination; struct edgecell *next; } edgecell; typedef edgecell * vertices[N]; typedef struct{ int vertex_num; int edge_num; vertices vtop; }graph; int read_adjacency_matrix(char *datafile, adjmatrix mat){ FILE *fp; int vertex_num; vindex src, dest; fp = fopen( datafile, "r" ); fscanf( fp, "%d\n", &vertex_num ); if( vertex_num > N ){ fprintf(stderr, "##### このプログラムが扱えるのは頂点数が%dまでのグラフです\n", N); exit(1); } for (src = 0; src < vertex_num; src++){ for(dest = 0; dest < vertex_num; dest++){ fscanf( fp, "%d\n", &mat[src][dest] ); } } fclose( fp ); return vertex_num; } void add_edge(graph *g, vindex src, vindex dest){ edgecell *edge = (edgecell *)malloc(sizeof(edgecell)); edge->destination = dest; edge->next = g->vtop[src]; g->vtop[src] = edge; } void translate_into_graph(adjmatrix mat, graph *g){ vindex i,j; for(i = 0; i < g->vertex_num; i++){ g->vtop[i] = NULL; } for(i = 0; i < g->vertex_num; i++){ for(j = 0; j < g->vertex_num; j++){ if (mat[i][j] == 1) add_edge(g, i, j); } } } void find_path(adjmatrix mat, graph *g){ vindex src = 0, dest = 0, dest2 = 0, x = 0, y = 0, z = 0; vindex A[g->vertex_num][g->vertex_num], B[g->vertex_num][g->vertex_num], C[g->vertex_num][g->vertex_num]; A[src][dest] = 0; B[src][dest2] = mat[src][dest]; C[dest2][dest] = mat[src][dest]; for(x = 0; x < g->vertex_num; x++){ for(src = 0; src < g->vertex_num; src++){ for(dest = 0; dest < g->vertex_num; dest++){ for(dest2 = 0; dest2 < g->vertex_num; dest2++){ A[src][dest] += B[src][dest2] * C[dest2][dest]; B[src][dest2] = A[src][dest]; } } } } for(y = 0; y < g->vertex_num; y++){ if(A[y][y] == 1){ z++; } } if(z == g->vertex_num){ printf("強連結です\n"); } else{ printf("強連結ではありません\n"); } } void print_graph(graph *g){ vindex v; printf("digraph G {\n"); printf(" size=\"14,10\"; node[fontsize=10,height=0.01,width=0.01]; edge[len=3.0];\n"); for(v = 0; v < g->vertex_num; v++){ edgecell *edge; for(edge = g->vtop[v]; edge != NULL; edge = edge->next){ printf(" %d -> %d;\n", v+1, edge->destination+1); } } printf("}\n"); } void free_graph(graph *g){ vindex v; for (v = 0; v < g->vertex_num; v++){ edgecell *edge, *next_edge; for(edge = g->vtop[v]; edge != NULL; edge = next_edge){ next_edge = edge->next; free( edge ); } } } int main( int argc, char *argv[] ){ char *datafile; adjmatrix a; graph g; if ( argc <= 1 ){ fprintf( stderr, "##### ファイルを指定してください\n"); return 1; } datafile = argv[1]; g.vertex_num = read_adjacency_matrix( datafile, a ); translate_into_graph( a, &g ); find_path( a, &g ); free_graph( &g ); return 0; }
補足情報(FW/ツールのバージョンなど)
C言語、Cygwin64
ご提示の例のデータはどのようなファイルになっているのでしょうか。
そして、そのファイルを処理する場合、 find_path 内においてそのデータが各変数内でどのように変化していき、どの行の段階でどの変数がどのような値になっているはずが、実際にはどのような値になっているのでしょうか。
datファイルの内容は、上の例は
10
0 0 1 1 0 0 0 0 0 0
0 0 0 0 1 0 0 0 0 0
0 0 0 0 1 1 0 0 0 0
0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 1 1 0 0
0 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 1 1
1 0 0 0 0 0 0 0 0 0
1 1 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0
下の例は
10
0 0 1 1 0 0 0 0 0 0
0 0 0 0 1 1 0 0 0 0
0 0 0 0 1 0 0 0 0 0
0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 1 0 1
0 0 0 0 0 0 0 0 1 0
1 1 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0 0
0 1 0 1 0 0 0 0 0 0
となっています。
最終的にどちらの例とも z = 10となるはずが、上の例は3、下の例は5となっています。
アルゴリズムは全く分からないのですが、2次元配列 C が値を入れずに使用していますが、式は合っているのでしょうか。
具体的にどういうことでしょうか?
計算毎に各配列の値を表示するようにして確認しては如何でしょうか。
回答1件
あなたの回答
tips
プレビュー