質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

Q&A

解決済

1回答

1399閲覧

TSPのNN法のプログラムについての質問(C言語)

gqh

総合スコア3

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

0グッド

0クリップ

投稿2021/10/25 08:25

前提・実現したいこと

現在pythonで記述していたプログラムをCで書き直そうとしています.

書きたい内容としては,TSPのNN法のプログラムです.まず初めに都市をランダムに選択し,2都市目以降は一番近い都市を順に選択していくというアルゴリズムです.
流れとしては,
(1):ランダムに都市を選択
(2):まだ訪問していない都市の集合と選択した都市の集合を作成
(3):1つ前に訪問した都市から一番近い都市を探す
(4):見つけた近い都市をNN法の配列に代入
(3)~(4)を全部の都市訪問するまで繰り返すというプログラムです.

(1),(2)までは問題なく動いているのですが,なぜか(3)のfor文が3回しか行われていません.(出力のaの部分)
datalenは51,ex_lengthは50の値が入っているはずなのですが,for文が回りません.

また,pythonで記述した同じ内容のプログラムも記載しておきます.

(C言語には触れ始めたばかりで基礎的な知識も欠如しています.)

発生している問題・エラーメッセージ

##エラーは出ていません ##出力結果 ex_length 50 datalen 51 a 0 b 23 0 0 first:46 0 c 0 a 1 b 29 0 1 first:46 1 c 1 a 2

該当のソースコード

C

1ソースコード 2int NearestNeighbor(int datalen,int weight[datalen][datalen]){ 3 int totalcost_nn = 0; 4 int min = 0;//乱数最小値 5 int max = datalen - 1;//乱数最大値 6 int i,j,x; 7 printf("%d, %d, %d\n",totalcost_nn,min,max); 8 9 int nn_city; 10 srand((unsigned int)time(NULL)); 11 nn_city = (rand()%(max - min + 1)) + min;//はじめの都市をランダムに選択(1) 12 printf("first city %d\n",nn_city); 13 14 int nn_root[datalen];//(2) 15 int ex_root[datalen];//未訪問都市集合(2) 16 nn_root[0] = nn_city; 17 for(i = 0;i < datalen;i++){ 18 if(i != nn_city){ 19 ex_root[i] = i; 20 printf("%d ",ex_root[i]); 21 } 22 } 23 printf("\n%d",nn_root[0]); 24 25 int ex_length = datalen - 1; 26 printf("\nex_length %d",ex_length);//未訪問都市の数 27 printf("\ndatalen %d",datalen);//問題の全体の都市数 28 29 for(i = 0;i < datalen-1;i++){//一番近い都市を探す(3) 30 int min_len = 0;//一番近い都市までの距離 31 int min_num = 0;//一番近い都市の番号 32 for(j = 0;j < ex_length;j++){ 33 printf("\na %d",j); 34 if(j == 0 || min_len > weight[nn_root[i]][nn_root[j]]){//weightは全都市間の距離が格納された2次元配列 35 printf("\nb %d %d %d first:%d %d",weight[nn_root[i]][ex_root[j]],i,j,nn_root[i],ex_root[j]); 36 min_len = weight[nn_root[i]][ex_root[j]]; 37 min_num = ex_root[j]; 38 printf("\nc %d",min_num); 39 } 40 } 41 nn_root[i+1] = min_num;//一番近い都市をi+1都市目に追加 42 int s = 0; 43 for(i = 0;i < ex_length;i++){ 44 if(ex_root[i] == min_num ||s == 1){ 45 ex_root[i] = ex_root[i+1];//未訪問都市から選んだ都市を探して消す,それ以降の都市を一つずらす 46 s = 1; 47 } 48 } 49 ex_length = ex_length - 1;//未訪問都市集合の数を一つ減らす 50 } 51 52 for(i=0;i<datalen;i++){ 53 printf("%d ",nn_root[i]); 54 } 55} 56 57#pythonバージョン 58nn_root = [] 59ex_root = [] 60 x=np.random.randint(datalen)#ランダムに都市を選択 61 print('都市番号',x+1) 62 nn_root.append(x) 63 for i in range (datalen): 64  ex_root.append(i) 65 ex_root.remove(x) 66 print(len(ex_root)) 67 #NN法の経路作成 68 for i in range(datalen - 1): 69 min_len = 0 70 min_Num = 0 71 72 for j in range(len(ex_root)): 73 if j == 0 or min_len > weight[nn_root[i]][ex_root[j]]: 74 min_len = weight[nn_root[i]][ex_root[j]] 75 min_Num = ex_root[j] 76 nn_root.append(min_Num) 77 ex_root.remove(min_Num)

試したこと

ここに問題に対して試したことを記載してください。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

出力の最後に「Segmentation falut」と出ていないでしょうか。
C言語で配列の範囲外アクセスをすると、このエラーが出て実行が止まる場合が多いです。

とりあえず、誤っているのは以下の箇所です。(ほかにもありますが、とりあえず1つだけ)

c

1 for(i = 0;i < datalen;i++){ 2 if(i != nn_city){ 3 ex_root[i] = i; 4 printf("%d ",ex_root[i]); 5 } 6 }

実行後にex_rootに何が入っているか、改めてループを回して表示してみてください。

投稿2021/10/25 12:32

actorbug

総合スコア2429

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

gqh

2021/10/26 03:14

回答ありがとうございます. ex_rootの中身がおかしくなっていたので,未訪問都市は0,1で表すようなプログラムに変えてみたところできました. また,for文の中でint min_len = 0;と定義することで,for文が回ってくるたびに値を初期化してくれると思っていたのですが,最初の一回だけしか行われていないみたいなので,その部分も変更することでうまく動きました.
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問