データ例,プログラム( species.h,MT.h は除く)
------------------------ケーススタディデータ------ 3 12345 data\species.fun data\data.fun 123 data\species.fun data\data.fun 1 data\species.fun data\data.fun ------------------------Species記述データ--------- 対立遺伝子上限 1 対立遺伝子下限 0 最大遺伝子長 15 最小遺伝子長(負の時は,最大遺伝子長で固定) -1 遺伝子の重複 1 個体の重複(同じ染色体の個体) 0 集団サイズ 20 子供 20 ------------------------Function記述データ-------- 出力レベル(負はファイル) 20 出力方法(0:すべて,1:最大) 0 出力ファイル名 result\kekka 表示間隔 1 交叉方法 1 交叉確率 1.0 点 2 位置 0 方法 1 バイアス 0 ステップ 1 突然変異方法 0 突然変異率 0.05 幅 1 平均 0.0 標準偏差 1.0 エリート 2 方法 1 バイアス 0 ステップ 1 最大世代交代数 200 ------------------------function.h---------------- /************************/ /* クラスFunctionの定義 */ /************************/ #include "species.h" class Function : public Species { double cv; // 2進数を10進数の変換する係数 int max_gen; // 最大世代交代数 int kosa_m; // 交叉方法 // =-1 : 交叉を使用しない // =0 : 親のコピー // =1 : 多点交叉 // =2 : 一様交叉 // =3 : 平均化交叉 double kosa; // 交叉確率 int k_point; // 交差点の数(負の時は,1から-point間のランダム) int k_vr; // =0 : 両親とも同じ位置で交叉 // =1 : 両親が異なる位置で交叉(遺伝子長は可変) int k_method; // 交叉の時の親の選択方法 // =-1 : ランダム // =0 : 適応度をそのまま使用 // =1 : 最小値からの差(ただし,α以下の場合はα) // =2 : 評価値に順位をつけ,減少率βで線形化 double k_bias; // α,または,method=2の場合は初期値 double k_step; // β int mute_m; // 突然変異方法 // =-1 : 突然変異を使用しない // =0 : 対立遺伝子への置換 // =1 : 移動 // =2 : 逆位 // =3 : スクランブル // =4 : 転座 // =5 : 重複 // =6 : 摂動 double mute; // 突然変異率 int wd; // 突然変異に使用する部分遺伝子長 double m_mean; // 摂動の平均値 double m_std; // 摂動の標準偏差 int elite; // エリート選択で残す数 int s_method; // ルーレット板の作成方法 // =0 : 適応度をそのまま使用 // =1 : 最小値からの差(ただし,α以下の場合はα) // =2 : 評価値に順位をつけ,減少率βで線形化 double s_bias; // α,または,s_method=2の場合は初期値 double s_step; // β int out_d; // 表示間隔 int out_lvl; // 出力レベル // =0 : 最終出力だけ // n>0 : n世代毎に出力(負の時はファイル) int out_m; // 出力方法 // =0 : すべてを出力 // =1 : 最大適応度の個体だけを出力 char o_file[100]; // 出力ファイル名 public: // コンストラクタ Function (char *, char *, long); // デストラクタ ~Function (); // 全体の実行制御 void Control(); // 適応度の計算 void Adap(); // 出力 void Output(int); }; ------------------------Functionのメンバー関数---- /********************************/ /* クラスFunctionのメンバー関数 */ /********************************/ #include "function.h" /***************************************/ /* コンストラクタ */ /* name1 : Species定義ファイル名 */ /* name2 : Function定義ファイル名 */ /* seed : 乱数の初期値 */ /***************************************/ Function::Function (char *name1, char *name2, long seed) : Species (name1, seed) { FILE *in; in = fopen(name2, "r"); fscanf(in, "%*s %d %*s %d", &out_lvl, &out_m); fscanf(in, "%*s %s %*s %d", o_file, &out_d); fscanf(in, "%*s %d %*s %lf %*s %d %*s %d %*s %d %*s %lf %*s %lf", &kosa_m, &kosa, &k_point, &k_vr, &k_method, &k_bias, &k_step); fscanf(in, "%*s %d %*s %lf %*s %d %*s %lf %*s %lf", &mute_m, &mute, &wd, &m_mean, &m_std); fscanf(in, "%*s %d %*s %d %*s %lf %*s %lf", &elite, &s_method, &s_bias, &s_step); fscanf(in, "%*s %d", &max_gen); cv = 1.0 / (pow(2.0, (double)max_len) - 1.0); fclose(in); } /****************/ /* デストラクタ */ /****************/ Function::~Function() { int i1; for (i1 = 0; i1 < size+max_ch; i1++) delete [] ind[i1]; delete [] ind; for (i1 = 0; i1 < max_len; i1++) delete [] edge[i1]; delete [] edge; delete [] pi; delete [] len; delete [] kou1; delete [] kou2; delete [] pi_w; delete [] s_w; delete [] ro; } /**************/ /* 全体の制御 */ /**************/ void Function::Control() { int gen = 1, k1; // 初期集団の発生 Init_std(); // 評価 Adap(); // 出力 printf("***世代 %d 適応度 max %f (%d) mean %f\n", gen, max, max_n, mean); if (abs(out_lvl) > 0) Output(gen); // 世代交代 for (gen = 2; gen <= max_gen; gen++) { // 交叉 switch (kosa_m) { case -1: break; case 0: C_copy(); // 親のコピー break; case 1: C_point(kosa, k_point); // 多点交叉 break; case 2: C_uniform(kosa); // 一様交叉 break; case 3: C_mean(kosa); // 平均化交叉 break; default: break; } // 突然変異 switch (mute_m) { case -1: break; case 0: M_alle(mute); // 対立遺伝子への置換 break; case 1: M_move(mute); // 移動 break; case 2: M_inv(mute, wd); // 逆位 break; case 3: M_scram(mute, wd); // スクランブル break; case 4: M_chg(mute, wd); // 転座 break; case 5: M_dup(mute, wd); // 重複 break; case 6: M_per(mute, wd, m_mean, m_std); // 摂動 break; default: break; } // 適応度 Adap(); // 淘汰 S_roul(elite); // 出力 if (gen%out_d == 0) printf("***世代 %d 適応度 max %f (%d) mean %f\n", gen, max, max_n, mean); if (abs(out_lvl) > 0) { if (gen%abs(out_lvl) == 0) Output(gen); } } gen--; k1 = out_m; out_m = 0; printf("***世代 %d 適応度 max %f (%d) mean %f\n", gen, max, max_n, mean); Output(gen); out_m = k1; } /****************/ /* 適応度の計算 */ /****************/ void Function::Adap() { double x, y; int i1, i2, n = 0; max = 0.0; max_n = -1; mean = 0.0; for (i1 = 0; i1 < size+max_ch; i1++) { if (pi_w[i1] == 1) { x = 0.0; y = 0.0; for (i2 = len[i1]-1; i2 >= 0; i2--) { if (ind[i1][i2] > 0) x += pow(2.0, y); y += 1.0; } x *= cv; pi[i1] = sin(3.0*x) + 0.5 * sin(9.0*x) + sin(15.0*x+50.0); pi_w[i1] = 2; } if (pi_w[i1] > 0) { mean += pi[i1]; n++; if (max_n < 0 || pi[i1] > max) { max = pi[i1]; max_n = i1; } } } mean /= n; } /*****************************/ /* 結果の出力 */ /* gen : 現在の世代番号 */ /*****************************/ void Function::Output(int gen) { double x, y; int i1, i2, k = 0, pr; char *now; time_t aclock; FILE *out; if (out_lvl >= 0) { printf(" 出力先は(0:出力なし,n:画面にn個づつ,-1:ファイル)? "); scanf("%d", &pr); } else pr = -1; if (pr != 0) { // 出力先の決定と評価値の出力 if (pr > 0) { out = stdout; getchar(); } else { time(&aclock); now = ctime(&aclock); out = fopen(o_file, "a"); fprintf(out, "***世代 %d 適応度 max %f (%d) mean %f 時間 %s\n", gen, max, max_n, mean, now); } // 詳細出力 for (i1 = 0; i1 < size+max_ch; i1++) { if ((pi_w[i1] > 1) && (out_m ==0 || out_m == 1 && i1 == max_n)) { fprintf(out, "%d allele", i1); for (i2 = 0; i2 < len[i1]; i2++) fprintf(out, " %d", ind[i1][i2]); x = 0.0; y = 0.0; for (i2 = len[i1]-1; i2 >= 0; i2--) { if (ind[i1][i2] > 0) x += pow(2.0, y); y += 1.0; } x *= cv; fprintf(out, " x %f y %f\n", x, pi[i1]); if (pr > 0) { k++; if (k == pr) { getchar(); k = 0; } } } } if (pr < 0) fclose(out); } } ------------------------main---------------------- /********************************************************************/ /* f(x) = sin(3.0*x) + 0.5 * sin(9.0*x) + sin(15.0*x + 50) の最大値 */ /* coded by Y.Suganuma */ /********************************************************************/ #include "function.h" /****************/ /* main program */ /****************/ int main(int argc, char *argv[]) { long *seed; int i1, n; char **i_file1, **i_file2; FILE *in; Function *fn; // 入力ミス if (argc <= 1) { printf("***error ファイル名を入力して下さい\n"); exit(1); } // 入力OK else { // ファイルのオープン in = fopen(argv[1], "r"); if (in == NULL) { printf("***error ファイル名が不適当です\n"); exit(1); } // 乱数の初期値と入力データファイル名の入力 fscanf(in, "%d", &n); // データの数 seed = new long [n]; i_file1 = new char * [n]; i_file2 = new char * [n]; for (i1 = 0; i1 < n; i1++) { i_file1[i1] = new char [100]; i_file2[i1] = new char [100]; fscanf(in, "%ld %s %s", &seed[i1], i_file1[i1], i_file2[i1]); } fclose(in); // 実行(乱数の初期値を変える) for (i1 = 0; i1 < n; i1++) { printf("\n+++++ケース %d+++++\n", i1+1); fn = new Function (i_file1[i1], i_file2[i1], seed[i1]); fn->Control(); } } return 0; }