![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?e8efa67)
遺伝的アルゴリズムをCで組み、Cygwinのgccコマンドでコンパイルしたのですが、実行するとエラーが出てしまいます。
gsb内で実行しwhereコマンドで異常箇所を探した場合のメッセージは以下の通りです。
#0 0x61016525 in stack_info::walk () from /usr/bin/cygwin1.dll
#1 0x7c859dcc in OutputDebugStringsA ()
from /cygdrive/c/WINDOWS/system32/kernel32.dll
#2 0x40010006 in ?? ()
#3 0x00000000 in ?? ()
プログラムは長いので載せられませんが、アルゴリズム中の染色体は二次元配列の遺伝子を含む構造体です。
遺伝子の配列に関わるノード数(chromo[timeslot][NODE]←このNODEです。プログラム冒頭で値をdefineで宣言しています)が30位なら世代数が比較的多くても動くのですが、これが50あたりになると世代数が低くてもエラーが出てしまいます。
printf関数で交叉や突然変異の結果を表示しているのですがちゃんと動作しているようです。
二台のパソコンどちらでやってもこのようなメッセージが出るので困っています。何が起こっているか見当がつく方、いらっしゃいましたら助言願います。
よろしくお願いいたします。
No.3ベストアンサー
- 回答日時:
わざわざソースを載せていただきありがとうございます。
こちらでも、足りない関数はありましたが、一応Cygwinで確認させていただきました。
こちらの、動作環境や足りない関数を適当に補ったため、
そちらでの結果を保証することはできませんが、一応気がついた点を伝えておきます。
1.
if(random < MUTATE){
....
next_p++;
}
if(...){
...
}
else{
next[next_p] = chromo[k];
...
}
上の文ですが、最初のif内でnext_pが増加されますが、
その後で、else内でnext[next_p]で配列を超えて参照する可能性がありました。
実際に、next[next_p]...の前に、
if(next_p >= POPULATION){
fprintf(stderr,"Overflow!\n");
}
などとやってみましたら、「Overflow!」が出力されました。
2.
for(k=0;k<POPULATION;k++);
chromo[k] = next[k];
の部分ですが、forの後に;が記述されておりました。
1はelseのみでなく、その前のifでもcrossoverで使われているようですね。
それと、2は直接は関係ないですが、気になったので。
あくまで、こちらの仮想的なソースの補足、および環境での動作ですので、
そちらでも同様に直るかどうか分かりませんが、参考までに。
ちなみに、ソースが完成されていないので、アルゴリズムの確認はしておりません。
ご指摘感謝致します。
どうやら1番の問題のせいだったようです。修正し関数等を調べた結果、ちゃんと交叉や突然変異も行われ、指定された世代数動くようになりました。
本当にありがとうございました。これでやっと試行段階に進めそうです。
No.2
- 回答日時:
もう1つ可能性があったので、追記させていただきます。
もしかして、その配列は自動変数(関数内で宣言)ではないでしょうか?
自動変数ですと、変数領域がスタック領域に確保されます。
しかし、スタック領域というものは比較的小さなものなので、
あまり多くの変数を使おうとしてしまうと、領域が確保できなくなることがあります。
今回、配列の大きさを変えてエラーが発生するとのことなので、これかもしれません。
一度、alloc系統でヒープ領域に変数を確保し、実行してみてください。
もしかしたら、これで上手くいくかもしれません。
それでも上手くいかない場合は、できればソースの一部で良いので見せてもらえればと思います。
回答のお礼の補足欄ですと、いくらか制限字数が多くなるようですし。
もちろん、載せたくないのであれば、かまいませんので^^;
この回答への補足
ソースを載せてみます。だいぶ省いていますが…
無線ネットワークの送信をTDMAスケジューリングする問題です。
C・Dmatrixは送信干渉を設定した行列の読み込み・生成の格納場所です。初期集団生成・突然変異(乱数で決定された遺伝子の1/0を逆手)も省略。…しても制限字数以上なのでmain関数も切りました…
/* ノード数 */
#define NODE 20
/* 世代数 */
#define GENERATION 10000
/* 現世代個体数 */
#define POPULATION 100
/* エリート選択個数 */
#define ELITE 2
/* 交叉率 */
#define CROSS 0.8
/* 突然変異率 */
#define MUTATE 0.02
/* timeslot最大値 */
#define TIME 60 /* 20node */
/* ペナルティ */
#define COST 100
/* Connectivity matrix */
int C[NODE][NODE];
/* Compatibility matrix */
int D[NODE][NODE];
/* Traffic demand vector */
int R[NODE] = {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4};
/* 染色体 */
struct chromosome{
int slot[TIME][NODE];
int cost; //コスト
int timeslot; //全タイムスロット数
}chromo[POPULATION], next[POPULATION];
/* 評価 */
int evaluate()
{
int time_num;
int flag1[NODE];
int hantei[POPULATION];
int i, j, k;
struct chromosome tmp; //コピー用
/* コスト計算 */
for(i = 0; i < POPULATION; i++){
time_num = 0;
for(j= 0; j < NODE; j++)
flag1[j] = 0;
/* timeslot loop */
for(time_num = 0; time_num < chromo[i].timeslot+1; time_num++){
/* 同時送信できないものが混ざっていたら+COST */
for(j = 0; j < NODE; j++){
if(chromo[i].slot[time_num][j] == 1){
for(k = 0; k < NODE; k++){
if(chromo[i].slot[time_num][k] & D[j][k] == 1)
chromo[i].cost += COST;
}
/* 送信回数調査 */
flag1[j]++;
}
}
}
/* 必要送信回数を満たしていなかったら+COST */
for(j = 0; j < NODE; j++){
if(R[j] != flag1[j])
chromo[i].cost += COST;
}
/* 最終タイムスロット分を足す */
chromo[i].cost += chromo[i].timeslot;
}
/* ソート */
for(i = 0; i < POPULATION-1; i++)
for(j = POPULATION-1; j > i ; j--)
if(chromo[i].cost > chromo[j].cost){
tmp = chromo[i];
chromo[i] = chromo[j];
chromo[j] = tmp;
}
}
/* 交叉 */
int crossover(int i, int next_p, int flag[])
{
int random2, random3; //乱数格納
int time_num, time_num2; //タイムスロット調べ
int j, k;
/* 出来た子供はNEXTPOPULATIONに格納 */
while(1){
select = (int)(rand() % POPULATION);
if(flag[select] == 0)
break;
}
/* 交叉点決定 */
/* 列(timeslot) */
if(chromo[i].timeslot <= chromo[select].timeslot){
random2 = (int)(rand() % chromo[i].timeslot);
time_num = chromo[i].timeslot;
}
else if(chromo[i].timeslot > chromo[select].timeslot){
random2 = (int)(rand() % chromo[select].timeslot);
time_num = chromo[select].timeslot;
}
/* 行(node) */
random3 = (int)(rand() % NODE);
/* 二次元一点交叉 */
next[next_p] = chromo[i];
next[next_p+1] = chromo[select];
for(j = time_num; j > random2; j--)
for(k = NODE-1; k > random3; k--){
next[next_p].slot[j][k] = chromo[select].slot[j][k];
next[next_p+1].slot[j][k] = chromo[i].slot[j][k];
}
return select;
}
main関数です。
/* main関数 */
int main(int argc, char *argv[])
{
double random;//乱数格納
int i, j, k;
int next_p, select;
int flag[POPULATION];
/* マトリクスファイル(connect)読み込み */
i = read_c(argv[1]);
if(i == -1)
return 1;
/* Dマトリクス作成 */
make_d();
/* 初期集団生成 */
srand((unsigned) time(NULL));
first();
//print();
i = 0;
while(1){
/* 設定された世代数を超えたら終了 */
if(i > GENERATION)
break;
/* POPULATION */
for(j = 0; j < POPULATION; j++)
flag[j] = 0;
/* 評価&ソート */
evaluate();
/* 遺伝的操作 */
for(k = 0, next_p = 0; next_p < POPULATION; k++){
/* エリート選択 */
if(k < ELITE){
next[next_p] = chromo[k];
flag[k]++;
next_p++;
}
else if(flag[k] == 0){
random = (double)rand() / RAND_MAX;
/* 突然変異 */
if(random < MUTATE){
mutation(k, next_p, chromo[k].timeslot);
flag[k] = 1;
next_p++;
}
/* 交叉 */
if(MUTATE <= random && random < CROSS+MUTATE && next_p != POPULATION-1){
flag[k] = 1;
select = crossover(k, next_p, flag);
flag[select] = 1;
next_p += 2;
}
/* 次世代へ持ち越し */
else{
next[next_p] = chromo[k];
flag[k] = 1;
next_p++;
}
}
}
/* 次世代→現世代 */
for(k = 0; k < POPULATION; k++);
chromo[k] = next[k];
i++;
}
printf("chromo 0 : %d\nchromo %d : %d\n", chromo[0].timeslot, POPULATION-1, chromo[POPULATION-1].timeslot);
return 0;
}
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Access(アクセス) アクセス where句を使用して複数条件抽出をするには 2 2022/08/29 13:24
- その他(プログラミング・Web制作) ラズパイ上の、pythonのエラーについて 1 2023/04/12 23:27
- 心理学 人間は優勢遺伝子を後世に残すために配偶者を無意識的に選ぶという説は本当だと思いますか? 8 2022/04/10 23:54
- 出会い・合コン 恋愛結婚って弊害が大きすぎませんか? 7 2022/04/10 16:17
- その他(ニュース・時事問題) コロナワクチンについて 3 2022/12/09 16:13
- C言語・C++・C# pythonのファイルの並びでの読み込みとリストについて 4 2022/04/13 03:52
- 生物学 シャトルベクターの大腸菌への形質転換 1 2022/07/02 23:19
- 生物学 減数分裂は子孫を残すときにも行う細胞分裂なのでしょうか? 4 2022/04/25 07:31
- 妊娠 出産経験のない女性は飲酒を全面禁止すべきではないでしょうか? 3 2022/04/12 17:27
- 英語 Recently, Parween et al. [40] performed a randomiz 2 2022/05/24 16:03
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
配列に複数の値があるか簡潔に...
-
Excel VBAでsub,dimは何の略?
-
アクセスできない保護レベルエ...
-
C言語のサフィックスについて
-
C#のループでtextboxに値を入れ...
-
他のフォームから別のフォーム...
-
演奏記号の・・・・
-
レコードセットにnullの場合
-
VBAでcallで呼び出したsubを終...
-
subsequentとnextの違いってな...
-
テキストボックスかラベル上の...
-
VB.NETでのイベントの途中終了
-
【C#】コンボボックスにおけるS...
-
零元のはいっている
-
構造体のコピー
-
VBAのフォーム カーソル移動
-
GetNextWindowがDLLファイルUse...
-
TreeViewのTag情報取得
-
プロシージャまたは関数の引数...
-
ユーザーフォームへのデータ入...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Functionの戻り値を配列にした...
-
Excel VBAでsub,dimは何の略?
-
xmlの値を配列に格納したいんで...
-
2次元配列のデータをファイルへ...
-
配列に複数の値があるか簡潔に...
-
xmlの値を配列変数に格納し...
-
ExcelVBAで他のファイル(proje...
-
三項でたとえば交換って
-
遺伝的アルゴリズム
-
VB6で配列を引数にするときの2...
-
VBA public変数はどのようなこ...
-
他のフォームから別のフォーム...
-
C#のループでtextboxに値を入れ...
-
エクセルVBAでテキストボッ...
-
VBAでcallで呼び出したsubを終...
-
VB.NETでのイベントの途中終了
-
C言語のサフィックスについて
-
ドラゴン曲線を再帰で書く
-
アクセスできない保護レベルエ...
-
VBAで入力数値について
おすすめ情報