データ例とプログラム(クラス 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