しかし、このプログラムをコンパイルして実行すると、
48:
10101 : 13
11110 : 13
10100 : 13
10111 : 13
49:
10101 : 16
11110 : 16
11111 : 16
10111 : 16
max: 20.00 min: 6.00 avg: 12.96
のように、各個体ごとの1の数の合計が適応度として出力されます。
48:
10101 : 3
11110 : 4
10100 : 2
10111 : 4
49:
10101 : 3
11110 : 4
11111 : 5
10111 : 4
これを上のように、1行(5ビット)ごとの適応度(1の数)を出力させるにはどうしたらよいのでしょうか??
開発環境は、microsoft visual c++ 2010 です。
長々とすみません。よろしくお願いします。
以下にソースコードを添付します。
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#define N 5 // 遺伝子長
#define M 50 // 個体数
#define ml 4 //音符数
#define T 1000 // 世代数
#define Pc 0.30 // 交叉確率
#define Pm 0.10 // 突然変異確率
// 遺伝子型の定義
struct genotype {
int gene[ml][N]; // 遺伝子
float fitness; // 適応度
};
float evaluation(int *a); //適応度計算
void one_point_crossover(struct genotype *ind); //交叉
void mutation(struct genotype *ind); //突然変異
void roulette_selection(struct genotype *ind); //選択
int flip(float prob); //
void print_process(struct genotype *ind, int generation); //出力
int main(int argc, char *argv[]) {
int i; // 個体インデックス
int j; // 遺伝子座インデックス
int s; // 音符数インデックス
int t; // 世代インデックス
struct genotype individual[M]; // 個体
struct genotype erito; //エリート
// 乱数seedの設定
if(argc < 2) { // プログラムの引数が足りない場合
printf("Usage: %s [SEED_NUMBER]\n", argv[0]);
exit(1);
}
else {
srand(atoi(argv[1]));
}
// ステップ1 (0世代目)
for(i=0; i<M; i++) {
for(s=0; s<ml; s++){
for(j=0; j<N; j++) {
individual[i].gene[s][j] = flip(0.5);
}
individual[i].fitness = evaluation(individual[i].gene); // 個体の適応度計算
}
}
print_process(individual, 0); // 初期世代の個体群を表示
//0世代目のエリート選択
for(i=1;i<M;i++){
if(individual[0].fitness < individual[i].fitness){
individual[0] = individual[i];
}
erito = individual[0];
}
// ステップ2 (1~T世代)
for(t=1; t<=T; t++) {
// 交叉
one_point_crossover(individual);
// 突然変異
mutation(individual);
// 子個体の適応度値計算
for(i=0; i<M; i++) {
individual[i].fitness = evaluation(individual[i].gene);
}
// ルーレット選択
roulette_selection(individual);
individual[0] = erito; //エリート挿入
for(i=1;i<M;i++){
if(individual[0].fitness < individual[i].fitness){
individual[0] = individual[i];
}
erito = individual[0]; //更新
}
print_process(individual, t);
}
return(0);
} // End of main()
// 個体の適応度計算
float evaluation(int *a) {
int j; // 遺伝子座インデックス
int count = 0; // 遺伝子中の`1'の数
for(j=0; j<ml*N; j++) {
count += a[j];
}
return((float)count);
} // End of evaluation()
// 一点交叉
void one_point_crossover(struct genotype *ind) {
int i, ia, ib; // 個体インデックス
int s; //音符数インデックス
int j; // 遺伝子座インデックス
int c; // 交叉点
int test[M]; // 個体の利用フラグ
int temp[N]; // 遺伝子を入れ替えるための仮変数
int r; // 乱数値
for(i=0; i<M; i++) test[i] = 0;
ia = ib = 0;
for(i=0; i<M/2; i++) {
// 個体をランダムにペアリング (親個体ia,ibを選ぶ)
// 親iaを決定
for(; test[ia]==1; ia=(ia+1)%M);
test[ia] = 1;
r = rand() % (M-2*i) + 1;
// (iaとは異なる)親ibを決定
while(r>0) {
ib=(ib+1)%M;
for(; test[ib]==1; ib=(ib+1)%M);
r--;
}
test[ib] = 1;
// 個体iaとibの遺伝子を入れ替える
if(flip(Pc)) {
c = rand() % N;
for(s=0; s<ml; s++){
for(j=0; j<c; j++) {
temp[j] = ind[ia].gene[s][j];
ind[ia].gene[s][j] = ind[ib].gene[s][j];
ind[ib].gene[s][j] = temp[j];
}
}
}
}
} // End of one_point_crossover()
// 突然変異
void mutation(struct genotype *ind) {
int i; // 個体インデックス
int s; //音符数インデックス
int j; // 遺伝子座インデックス
for(i=0; i<M; i++)
for(s=0; s<ml; s++)
for(j=0; j<N; j++)
if(flip(Pm)) {
ind[i].gene[s][j] = (ind[i].gene[s][j] + 1) % 2;
}
} // End of mutation()
// ルーレット選択
void roulette_selection(struct genotype *ind) {
int h, i, j; // 個体インデックス
float total_fitness; // 適応度の合計値
float dart; // 矢
float wheel; // ルーレット・ホイール
struct genotype ind_new[M]; // 選択操作後の個体集合
// 適応度の合計値を計算
total_fitness = 0;
for(i=0; i<M; i++) total_fitness += ind[i].fitness;
// ルーレット・ホイールに従って次世代(ind_new[])を決定
for(i=0; i<M; i++) {
dart = (float)rand() / RAND_MAX;
h = 0;
wheel = ind[h].fitness / total_fitness;
while(dart > wheel && h < M-1) {
h++;
wheel += ind[h].fitness / total_fitness;
}
ind_new[i] = ind[h];
}
// 個体集合の更新
for(i=0; i<M; i++) {
ind[i] = ind_new[i];
}
} // End of roulette_selection()
// 引数`prob'の確率で1を返す
int flip(float prob) {
float x = (float)rand() / (float)RAND_MAX;
if(x<prob) return(1);
else return(0);
} // End of flip()
// 個体の中身や適応度値を画面に出力
void print_process(struct genotype *ind, int generation) {
int i; // 個体インデックス
int s; //音符数インデックス
int j; // 遺伝子座インデックス
float max_fit, min_fit, avg_fit; // 最大,最小,平均適応度
// 各個体の中身を出力
printf("\nGeneration: %d\n", generation);
for(i=0; i<M; i++) {
printf("%d:\n ", i);
for(s=0; s<ml; s++){
for(j=0; j<N; j++) {
if(ind[i].gene[s][j] == 0) printf("%c", '0');
else printf("%c", '1');
}
printf(" : %.0f\n", ind[i].fitness);
}
}
// 個体集団の最大,最小,平均適応度を求める
max_fit = min_fit = ind[0].fitness;
avg_fit = ind[0].fitness / M;
for(i=1; i<M; i++) {
if(max_fit < ind[i].fitness) max_fit = ind[i].fitness;
if(min_fit > ind[i].fitness) min_fit = ind[i].fitness;
avg_fit += ind[i].fitness / M;
}
printf("max: %.2f min: %.2f avg: %.2f\n", max_fit, min_fit, avg_fit);
}