public void optimize() {
final int totalBits = getTotalBits(domains);
final double[] probVec = new double[totalBits];
Arrays.fill(probVec, 0.5);
bestCost = POSITIVE_INFINITY;
for (int i = 0; i < ITER_COUNT; i++) {
// N個の遺伝子を作成する
final boolean[][] genes = new boolean[N][totalBits];
for (boolean[] gene : genes) {
for (int k = 0; k < gene.length; k++) {
if (rand.nextDouble() < probVec[k])
gene[k] = true;
}
}
// コストを計算する
final double[] costs = new double[N];
for (int j = 0; j < N; j++) {
costs[j] = costFunc.cost(toRealVec(genes[j], domains));
}
// 最小・最大コストの遺伝子を探す
boolean[] minGene = null, maxGene = null;
double minCost = POSITIVE_INFINITY, maxCost = NEGATIVE_INFINITY;
for (int j = 0; j < N; j++) {
double cost = costs[j];
if (minCost > cost) {
minCost = cost;
minGene = genes[j];
}
if (maxCost < cost) {
maxCost = cost;
maxGene = genes[j];
}
}
// 最良コストの遺伝子と比較する
if (bestCost > minCost) {
bestCost = minCost;
bestGene = minGene;
}
// 最小・最大コストの遺伝子で確率ベクトルを更新する
for (int j = 0; j < totalBits; j++) {
if (minGene[j] == maxGene[j]) {
probVec[j] = probVec[j] * (1d - learnRate) +
(minGene[j] ? 1d : 0d) * learnRate;
} else {
final double learnRate2 = learnRate + negLearnRate;
probVec[j] = probVec[j] * (1d - learnRate2) +
(minGene[j] ? 1d : 0d) * learnRate2;
}
}
// 突然変異
for (int j = 0; j < totalBits; j++) {
if (rand.nextDouble() < mutProb) {
probVec[j] = probVec[j] * (1d - mutShift) +
(rand.nextBoolean() ? 1d : 0d) * mutShift;
}
}
}
}