データ例,プログラム( 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;
}
対立遺伝子上限 1 対立遺伝子下限 0 最大遺伝子長 15 最小遺伝子長(負の時は,最大遺伝子長で固定) -1 遺伝子の重複 1 個体の重複(同じ染色体の個体) 0 集団サイズ 20 子供 20
出力レベル(負はファイル) 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