![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?e8efa67)
c言語を使い始めて、TSPについて勉強中で、遺伝的アルゴリズムの交叉(順序交叉)について以下のプログラムを作ってみたのですが、凄く遅いです。答えはきちんと出るのですが、循環交叉を取り入れたプログラムは5000ループでも1秒弱で出るのに対して20秒近くかかってしまいます。ループに無駄が多そうなのですが思いつきません。ヒントでも宜しいのでご教授下さい。
順序交叉とは、例えば
x[i] = 3,4,5,2,1とy[i] = 4,3,5,1,2(i = 0~)という数字が与えられたときtargetを2とすると
x[i] = 3,4, y[i] = 4,3まではそのまま受け継ぎ、3以降は相手方の数字を左から順番に使われていないものを取り入れていくものです。この場合だと、x[i] = 3,4,5,1,2 y[i] = 4,3,5,2,1となります。
#define a 5
int main(void)
{
int x[a] = {3, 4, 5, 2, 1}, y[a] = {4, 3, 5, 1, 2};
int target, i, j, k, l;
int x2[a], y2[a];
srand((unsigned)time(NULL));
target = rand () % a;
for (i = 0; i < target; i++) {
x2[i] = x[i];
y2[i] = y[i];
}
for (i = target; i < a; i++) {
x2[i] = 0;
y2[i] = 0;
}
j = 0;
k = 0;
while (k != a - target) {
for (i = 0; i < target + k; i++) {
for (l = 0; l < target + k; l++) {
if (x2[l] == y[j])
j++;
}
}
if (x2[target + k] != y[j]) {
x2[target + k] = y[j];
k++;
j++;
}
else
j++;
}
yについても同様の作業です
}
No.1ベストアンサー
- 回答日時:
パッと思いついたところだけ。
出現済みチェック(かな?)の二重ループ。jがインクリメントされなければ、次のiのループでもインクリメントされないので、ループしなくても良いかと。こんな感じ:
while (k != a - target) {
for (i = 0; i < target + k; i++) {
int prev_j = j; // jを記憶。
for (l = 0; l < target + k; l++) {
if (x2[l] == y[j])
j++;
}
printf( "j: %d->%d?n", prev_j, j ); //デバッグ用。
if ( prev_j == j ){break;} // jに変化無ければブレーク。
}
遺伝子が重複無く存在するような表現式なのだとしたら、以下のやり方でもいけるかも。
for (i = 0; i < target; i++) { // 交叉直前まで遺伝。
x2[i] = x[i];
}
for (i = 0; i < a; i++) { // 片親を作業領域にコピー。
y2[i] = y[i];
}
for ( j = 0; j < target; j++ ){
for ( i = 0; i < a; i++ ){
if ( x2[j] == y2[i] ){ y2[i] = 0; } // 既に遺伝済みのものは引き継がないよう片親側に0でマーク。
}
}
i = 0;
for( k = target; k < a; k++ ){ // 片親から残りを遺伝。
while ( y2[i] == 0 ){ i++; } // マークされている部分をスキップ。
x2[k] = y2[i++];
}
}
有難う御座いました。おかげで、循環交叉と同じ位のスピードで処理出来るようになりました。大変勉強になりました。また質問するようなことがあったら宜しく御願い致します。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) 【再々投稿】VBAのプログラムで動作しなくて困っています 8 2022/10/14 09:06
- Visual Basic(VBA) vba 重複データ合算 5 2023/07/05 18:55
- C言語・C++・C# カードシャッフルのブログラムを使ってc言語でブラックジャックをしたい 2 2022/04/12 15:13
- C言語・C++・C# C言語プログラム変更 2 2022/12/21 15:03
- Visual Basic(VBA) excel vbaでvlooupの変数がわかりません。 7 2022/05/30 09:35
- Visual Basic(VBA) vbaのエラー対応(実行時エラー7:メモリが不足しています) 4 2023/04/24 00:20
- Visual Basic(VBA) シート削除のマクロで「deleteメソッドは失敗しました」となります。助けてください! Sub 不要 6 2022/09/08 16:41
- Visual Basic(VBA) Excel-VBAでのファイルの開き方 4 2023/02/14 11:01
- C言語・C++・C# 10個の実数に対する降順ソート結果を出力するプログラムを作りたいのですが、以下のプログラムをどう直せ 1 2022/07/09 22:16
- Visual Basic(VBA) VBAのトグルボタンでのマクロについて質問です 3 2022/10/10 17:23
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
do-while文が禁止される理由
-
if文でスキップしたい場合は?
-
入力した数値を倍々するプログラム
-
break文でループを一気に抜ける...
-
for文while文の無限ループの違...
-
他言語で言うcontinue文
-
Excel VBAで年度をまたぐ期間の...
-
エクセルVBAで Do While (1)って?
-
UWSCにてある一定の動作を無限...
-
交叉について
-
C言語のPICプログラミングなん...
-
桁数を求めるプログラム。
-
線形探索(番兵法)のプログラ...
-
HTTPレスポンスの終端はどうわ...
-
ループを途中で抜けたいのですが。
-
C言語forループが完結した場合...
-
PAD図の書き方
-
While文の終わりにセミコロンが...
-
「指定されたキャストは有効で...
-
マイナスからプラスへ転じた時...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
break文でループを一気に抜ける...
-
ループを途中で抜けたいのですが。
-
入力した文字列から母音だけを...
-
do-while文が禁止される理由
-
入力した数値を倍々するプログラム
-
C言語forループが完結した場合...
-
if文の中にfor文なのか、for文...
-
プログラミングC言語についての...
-
エクセルVBAで Do While (1)って?
-
For文の終了値を関数にしても問...
-
エクセルでC言語のfor文と同じ...
-
Delphiで・・・
-
ループの特定入力終了
-
UWSCにてある一定の動作を無限...
-
C言語、自己参照構造体のプログ...
-
C言語 数字を削除する関数
-
Cプログラムが終了しない
-
Excel VBAで年度をまたぐ期間の...
-
プログラムで関数は使わない方...
-
VBScriptでSQLに接続し、CSV出...
おすすめ情報