
ダイクストラ法を用いて最短経路を表示するプログラムなんですが
void daijkstra(int a)
{ //count[] この関数では定義していません(この外です)
int g, b, c, d, e, f;
//アクセス出来る点を探索.
for(b = 0, c = 0;b != ten;b++){
if(adj[a][b] == INT_MAX || a == b) continue;
else{
if(no_loop[b] != ten * hen){
count[c] = b;//アクセス出来た点を入力.
c++;
no_loop[b] = no_loop[b] + 1;
}
}
}
count[c] = -1;
for(d = 0;count[d] != -1; d++){
c = count[d];
if(place[c] == INT_MAX){
place[c] = adj[a][c] + place[a];
}
else{
g = adj[a][c] + place[a];
if(g < place[c]){
place[c] = g;
}
}
}
for(e = 0;count[e] != -1;e++){
f = count[e];
daijkstra(f);
}
return;
}
こういった感じに完成しました。
ですがSegmentation fault (core dumped)と表示されどうしても出来ない場合が時々あるんです.(main 関数でネットワークをランダムに生成しています。上記の関数だけでは情報が少ない場合はmainを載せます。)
スタックオーバーフロウが起きているのは確実なんですがそれを回避する術を知らないのでどうかご協力をお願いします.
ten * hen を1に変更すると2回目にアクセスした場合に2回目の方が短い場合更新できなくなるので1以上にして、ten * henは全ての点に全部の辺が付いていると考えた『これ以上はないはず』といういみがあります
A 回答 (3件)
- 最新から表示
- 回答順に表示
No.3
- 回答日時:
示してもらったURLの掲示板を見て、全体像がつかめました。
ここに載せたソースコードより、インデントが入ってて読みやすい。
さて、
> #define ARRAY_MAX 10000
と定義して、int型で
count[ARRAY_MAX], adj[ARRAY_MAX][ARRAY_MAX], place[ARRAY_MAX], no_loop[ARRAY_MAX], result[ARRAY_MAX], net_max[ARRAY_MAX]
を宣言してますね。さて、全部で何バイト使っているでしょか?
intが32bit=4Byteとして、
4 * (10000 * 10000 + 5 * 10000) = 何バイト?
400 MB くらいになるんでしょうか? だいぶ無茶してますね。
再帰云々の前に、メモリが確保できていない可能性を疑ってしまいます。確保できていないメモリにアクセスすれば、セグメンテーションフォルトになってもおかしく無いでしょう。何を目的としたプログラムか知りませんが、本当に 10000 も必要ですか?
そこで提案です。void daijkstra(int a)が正しく動作することを確認するために、
(1)まずはノードの数を3~5点程度の手計算で求められる数に絞って、
(2)乱数を使わず手作業でテスト用のネットワークを作って
関数の動作を確認してみましょう。
それから。
> printf("入力>>>>>");
> scanf(" %d", &ten);
(中略)
> for(a = 0, hen = 0;a != ten;a++){
セグメンテーションフォルト以前の問題ですが、これ危険なにおいがプンプンします。負の値を入力したらどうなると思いますか?
for文書くなら、
for(a=0, hen=0; a<ten; a++)
が普通だと思うんですけどね~。
> for(d = 0;count[d] != -1; d++){
これはOKですが、ループ内に無限ループを防ぐ仕組みを入れておくのが得策。というのは、先のhttp://okwave.jp/qa2625522.html でも指摘されていたとこ。
プロが書くプログラムは、コードの8割近くがエラー処理です。エラー処理が随所に埋め込まれていると、変な値が入っても見つけやすいので、不具合が出たときに発生場所を特定しやすくなります。エラー処理、埋め込みましょうね。
No.2
- 回答日時:
なんというか, この関数が正しいように思えない....
Dijkstra のアルゴリズムを実装するのに, なぜ DFS? 普通は BFS (一般には優先度付きキュー) を使うんじゃないかなぁ.
No.1
- 回答日時:
変数の意味が分かりません。
a,b,c,d,e,g,f,ten,hen,count,place等、それぞれの意味ととりうる値の範囲を書いてください。
かろうじてadjは接続行列っぽいなぁと意味が推測できましたが、変数は意味が推測しやすい名前にしましょう。そのほうがデバッグしやすいですよ。
> for(e = 0;count[e] != -1;e++){
> f = count[e];
> daijkstra(f);
> }
先の http://okwave.jp/qa2625522.html でも指摘されていたところが、まだ直っていないようですね。
この回答への補足
すいません。
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <time.h>
#define ARRAY_MAX 10000
int ten, hen;
int adj[ARRAY_MAX][ARRAY_MAX], place[ARRAY_MAX], no_loop[ARRAY_MAX], result[ARRAY_MAX], net_max[ARRAY_MAX];
void daijkstra(int );
int main (void)
{
int sum = 0, sub = 0;
//各要素を格納する
int length[ARRAY_MAX], begin[ARRAY_MAX], end[ARRAY_MAX];
int a, b, c, d, e, f, g, h, i, receive, net_kosuu;
double ran, kakuritu, re_result;
printf("確率は小数で入力して下さい.\n");
printf("入力>>>>>");
scanf(" %lf", &kakuritu);
printf("何個の点を対象としますか\n");
printf("入力>>>>>");
scanf(" %d", &ten);
printf("何個のネットワークを生成しますか\n");
printf("入力>>>>>");
scanf("%d", &net_kosuu);
srand((unsigned)time(NULL));
for(h = 0;h != net_kosuu;h++){
net_max[h] = -INT_MAX;
//辺にINT_MAXを入力する.
for(a = 0;a != ten;a++){
for(b = 0;b != ten;b++){
adj[a][b] = INT_MAX;
}
}
for(a = 0, hen = 0;a != ten;a++){
for(b = 0;b != ten;b++){
ran = (double)rand() / RAND_MAX;//0から1の値を生成.
if(a == b) continue;
if(kakuritu >= ran){
adj[a][b] = 1;
adj[b][a] = 1;
hen++;
}
}
}
//ネットワーク作成完了.
for(i = 0;i != ten;i++){
result[i] = -INT_MAX;
for(b = 0;b != ten;b++){
no_loop[b] = 0;
}
for(b = 0;b != ten;b++){
place[b] = INT_MAX; /*十分大きな値を入力する*/
} /*0番目は始点なので */
place[i] = 0; /* 0を入力する*/
daijkstra(i);
for(c = 0;c != ten;c++){
if(place[c] == INT_MAX) continue;
else if(result[i] < place[c]) result[i] = place[c];
}
}
for(d = 0;d != ten;d++){
if(net_max[h] < result[d]) net_max[h] = result[d];
}
}
for(a = 0, sum = 0;a != net_kosuu;a++)
{
if(net_max[a] == 0) sub++;
sum += net_max[a];
}
net_kosuu = net_kosuu - sub;
if(net_kosuu != 0)
{
re_result = (double)sum / net_kosuu;
printf("ネットワークの直径の平均値: %lf\n", re_result);
}
printf("ネットワーク不完全数 → %d", sub);
return EXIT_SUCCESS;
}
http://l.huu.cc/board/
↑の大工が私なんですが。。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# プログラミング c言語 4 2023/03/07 01:05
- Ruby 【JAVA】数字をひし形に出力するプログラムについて 2 2022/07/11 23:32
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
- C言語・C++・C# C言語 3 2022/11/09 13:27
- FX・外国為替取引 mql4のコンパイルエラー箇所の修正お願いします。 1 2023/03/15 16:14
- C言語・C++・C# このプログラミングの問題を教えて欲しいです。 キーボードから整数kを入力し、kが配列aの中に何個存在 2 2022/12/19 22:50
- PHP PHPでCookieを使った訪問回数について 1 2023/05/28 14:10
- PHP PHP MySql ページング 2 2022/09/20 06:38
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C#メール受信から件名、本文を...
-
ヒストグラム均等化処理プログラム
-
C言語プログラミング 漸化式に...
-
カードシャッフルのブログラム...
-
再起呼び出しの回数をカウント...
-
【C#】SQL文の中に変数を埋め込...
-
条件が多い場合
-
OpenGLの惑星プログラム
-
2次関数プログラムを描写する...
-
16bitで乱数を生成する方法
-
プログラミングに関して
-
C++で表を作成したいのです ...
-
OpenCVによる4値化について
-
異なるn個の整数からr個の整数...
-
C++ bmp 透過処理
-
3のつく数と3の倍数を表示 C言語
-
クリックされた地点が2点の線分...
-
当たり判定の処理がわかりません。
-
関数とビット列
-
デバッグビルドとリリースビル...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
おすすめ情報