データ例とプログラム(クラス Species は除く)
------------------------ケーススタディデータ------
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 幅 0 平均 0.0 標準偏差 1.0
エリート 2 方法 1 バイアス 0 ステップ 1
最大世代交代数 200
------------------------クラスFunction------------
/************************/
/* クラスFunctionの定義 */
/************************/
import java.io.*;
import java.util.Date;
import java.util.StringTokenizer;
class Function extends Species {
private double cv; // 2進数を10進数の変換する係数
private int max_gen; // 最大世代交代数
private int kosa_m; // 交叉方法
// =-1 : 交叉を使用しない
// =0 : 親のコピー
// =1 : 多点交叉
// =2 : 一様交叉
// =3 : 平均化交叉
private double kosa; // 交叉確率
private int k_point; // 交差点の数(負の時は,1から-point間のランダム)
private int k_vr; // =0 : 両親とも同じ位置で交叉
// =1 : 両親が異なる位置で交叉(遺伝子長は可変)
private int k_method; // 交叉の時の親の選択方法
// =-1 : ランダム
// =0 : 適応度をそのまま使用
// =1 : 最小値からの差(ただし,α以下の場合はα)
// =2 : 評価値に順位をつけ,減少率βで線形化
private double k_bias; // α,または,method=2の場合は初期値
private double k_step; // β
private int mute_m; // 突然変異方法
// =-1 : 突然変異を使用しない
// =0 : 対立遺伝子への置換
// =1 : 移動
// =2 : 逆位
// =3 : スクランブル
// =4 : 転座
// =5 : 重複
// =6 : 摂動
private double mute; // 突然変異率
private int wd; // 突然変異に使用する部分遺伝子長
private double m_mean; // 摂動の平均値
private double m_std; // 摂動の標準偏差
private int elite; // エリート選択で残す数
private int s_method; // ルーレット板の作成方法
// =0 : 適応度をそのまま使用
// =1 : 最小値からの差(ただし,α以下の場合はα)
// =2 : 評価値に順位をつけ,減少率βで線形化
private double s_bias; // α,または,s_method=2の場合は初期値
private double s_step; // β
private int out_d; // 表示間隔
private int out_lvl; // 出力レベル
// =0 : 最終出力だけ
// n>0 : n世代毎に出力(負の時はファイル)
private int out_m; // 出力方法
// =0 : すべてを出力
// =1 : 最大適応度の個体だけを出力
private String o_file; // 出力ファイル名
/***************************************/
/* コンストラクタ */
/* name1 : Species定義ファイル名 */
/* name2 : Function定義ファイル名 */
/* seed : 乱数の初期値 */
/***************************************/
Function (String name1, String name2, int seed) throws IOException, FileNotFoundException
{
super (name1, seed);
String line;
StringTokenizer dt;
BufferedReader in = new BufferedReader(new FileReader(name2));
line = in.readLine();
dt = new StringTokenizer(line, " ");
dt.nextToken();
out_lvl = Integer.parseInt(dt.nextToken());
dt.nextToken();
out_m = Integer.parseInt(dt.nextToken());
line = in.readLine();
dt = new StringTokenizer(line, " ");
dt.nextToken();
o_file = dt.nextToken();
dt.nextToken();
out_d = Integer.parseInt(dt.nextToken());
line = in.readLine();
dt = new StringTokenizer(line, " ");
dt.nextToken();
kosa_m = Integer.parseInt(dt.nextToken());
dt.nextToken();
kosa = Double.parseDouble(dt.nextToken());
dt.nextToken();
k_point = Integer.parseInt(dt.nextToken());
dt.nextToken();
k_vr = Integer.parseInt(dt.nextToken());
dt.nextToken();
k_method = Integer.parseInt(dt.nextToken());
dt.nextToken();
k_bias = Double.parseDouble(dt.nextToken());
dt.nextToken();
k_step = Double.parseDouble(dt.nextToken());
line = in.readLine();
dt = new StringTokenizer(line, " ");
dt.nextToken();
mute_m = Integer.parseInt(dt.nextToken());
dt.nextToken();
mute = Double.parseDouble(dt.nextToken());
dt.nextToken();
wd = Integer.parseInt(dt.nextToken());
dt.nextToken();
m_mean = Double.parseDouble(dt.nextToken());
dt.nextToken();
m_std = Double.parseDouble(dt.nextToken());
line = in.readLine();
dt = new StringTokenizer(line, " ");
dt.nextToken();
elite = Integer.parseInt(dt.nextToken());
dt.nextToken();
s_method = Integer.parseInt(dt.nextToken());
dt.nextToken();
s_bias = Double.parseDouble(dt.nextToken());
dt.nextToken();
s_step = Double.parseDouble(dt.nextToken());
line = in.readLine();
dt = new StringTokenizer(line, " ");
dt.nextToken();
max_gen = Integer.parseInt(dt.nextToken());
cv = 1.0 / (Math.pow(2.0, (double)max_len) - 1.0);
in.close();
}
/**************/
/* 全体の制御 */
/**************/
void Control() throws IOException, FileNotFoundException
{
int gen = 1, k1;
// 初期集団の発生
Init_std();
// 評価
Adap();
// 出力
System.out.println("***世代 " + gen + " 適応度 max " + max +
" (" + max_n + ") mean " + mean);
if (Math.abs(out_lvl) > 0)
Output(gen);
// 世代交代
for (gen = 2; gen <= max_gen; gen++) {
// 交叉
switch (kosa_m) {
case -1:
break;
case 0:
C_copy(2, max_ch/2, k_method, k_bias, k_step); // 親のコピー
break;
case 1:
C_point(kosa, k_point, k_vr, k_method, k_bias, k_step); // 多点交叉
break;
case 2:
C_uniform(kosa, k_method, k_bias, k_step); // 一様交叉
break;
case 3:
C_mean(kosa, k_method, k_bias, k_step); // 平均化交叉
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, s_method, s_bias, s_step);
// 出力
if (gen%out_d == 0)
System.out.println("***世代 " + gen + " 適応度 max " + max +
" (" + max_n + ") mean " + mean);
if (Math.abs(out_lvl) > 0) {
if (gen%Math.abs(out_lvl) == 0)
Output(gen);
}
}
gen--;
k1 = out_m;
out_m = 0;
System.out.println("***世代 " + gen + " 適応度 max " + max +
" (" + max_n + ") mean " + mean);
Output(gen);
out_m = k1;
}
/****************/
/* 適応度の計算 */
/****************/
void 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 += Math.pow(2.0, y);
y += 1.0;
}
x *= cv;
pi[i1] = Math.sin(3.0*x) + 0.5 * Math.sin(9.0*x) +
Math.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 Output(int gen) throws IOException, FileNotFoundException
{
double x, y;
int i1, i2, k = 0, pr;
String now;
PrintStream out = null;
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
if (out_lvl >= 0) {
System.out.print(" 出力先は(0:出力なし,n:画面にn個づつ,-1:ファイル)? ");
pr = Integer.parseInt(in.readLine());
}
else
pr = -1;
if (pr != 0) {
// 出力先の決定と評価値の出力
if (pr > 0)
out = System.out;
else {
Date newtime = new Date(); // 現在時刻の獲得
now = newtime.toString(); // 文字列への変換
out = new PrintStream(new FileOutputStream(o_file, true));
out.println("***世代 " + gen + " 適応度 max " + max +
" (" + max_n + ") mean " + mean + " 時間 " + now);
}
// 詳細出力
for (i1 = 0; i1 < size+max_ch; i1++) {
if ((pi_w[i1] > 1) && (out_m ==0 || out_m == 1 && i1 == max_n)) {
out.print(i1 + " allele");
for (i2 = 0; i2 < len[i1]; i2++)
out.print(" " + ind[i1][i2]);
x = 0.0;
y = 0.0;
for (i2 = len[i1]-1; i2 >= 0; i2--) {
if (ind[i1][i2] > 0)
x += Math.pow(2.0, y);
y += 1.0;
}
x *= cv;
out.println(" x " + x + " y " + pi[i1]);
if (pr > 0) {
k++;
if (k == pr) {
in.readLine();
k = 0;
}
}
}
}
if (pr < 0)
out.close();
}
}
}
------------------------クラスOpt(main)-----------
/********************************************************************/
/* f(x) = sin(3.0*x) + 0.5 * sin(9.0*x) + sin(15.0*x + 50) の最大値 */
/* coded by Y.Suganuma */
/********************************************************************/
import java.io.*;
import java.util.StringTokenizer;
public class Opt {
/****************/
/* main program */
/****************/
public static void main(String args[]) throws IOException, FileNotFoundException
{
int i1, n, seed[];
String i_file1[], i_file2[], line;
Function fn;
StringTokenizer dt;
BufferedReader in = new BufferedReader(new FileReader(args[0]));
// 入力ミス
if (args.length == 0) {
System.out.print("***error ファイル名を入力して下さい\n");
System.exit(1);
}
// 入力OK
else {
// 乱数の初期値と入力データファイル名の入力
n = Integer.parseInt(in.readLine());
seed = new int [n];
i_file1 = new String [n];
i_file2 = new String [n];
for (i1 = 0; i1 < n; i1++) {
line = in.readLine();
dt = new StringTokenizer(line, " ");
seed[i1] = Integer.parseInt(dt.nextToken());
i_file1[i1] = dt.nextToken();
i_file2[i1] = dt.nextToken();
}
in.close();
// 実行(乱数の初期値を変える)
for (i1 = 0; i1 < n; i1++) {
System.out.print("\n+++++ケース " + (i1+1) + "+++++\n");
// 入力と初期設定
fn = new Function (i_file1[i1], i_file2[i1], seed[i1]);
// 最適化
fn.Control();
}
}
}
}
対立遺伝子上限 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