@Override public Solution[] evolve(Solution[] parents) { Solution result1 = parents[0].copy(); Solution result2 = parents[1].copy(); if (pprng.nextDouble() <= probability) { for (int i = 0; i < result1.getNumberOfVariables(); i++) { Variable variable1 = result1.getVariable(i); Variable variable2 = result2.getVariable(i); if (pprng.nextBoolean() && (variable1 instanceof RealVariable) && (variable2 instanceof RealVariable)) { evolve((RealVariable) variable1, (RealVariable) variable2, distributionIndex); } } } return new Solution[] {result1, result2}; }
/** * Evolves the specified variables using the SBX operator. * * @param v1 the first variable * @param v2 the second variable * @param distributionIndex the distribution index of this SBX operator */ public void evolve(RealVariable v1, RealVariable v2, double distributionIndex) { double x0 = v1.getValue(); double x1 = v2.getValue(); double dx = Math.abs(x1 - x0); if (dx > Settings.EPS) { double lb = v1.getLowerBound(); double ub = v1.getUpperBound(); double bl; double bu; if (x0 < x1) { bl = 1 + 2 * (x0 - lb) / dx; bu = 1 + 2 * (ub - x1) / dx; } else { bl = 1 + 2 * (x1 - lb) / dx; bu = 1 + 2 * (ub - x0) / dx; } // use symmetric distributions if (bl < bu) { bu = bl; } else { bl = bu; } double p_bl = 1 - 1 / (2 * Math.pow(bl, distributionIndex + 1)); double p_bu = 1 - 1 / (2 * Math.pow(bu, distributionIndex + 1)); double u = pprng.nextDouble(); // prevent out-of-bounds values if PRNG draws the value 1.0 if (u == 1.0) { u = Math.nextAfter(u, -1.0); } double u0 = u * p_bl; double u1 = u * p_bu; double b0; double b1; if (u0 <= 0.5) { b0 = Math.pow(2 * u0, 1 / (distributionIndex + 1)); } else { b0 = Math.pow(0.5 / (1 - u0), 1 / (distributionIndex + 1)); } if (u1 <= 0.5) { b1 = Math.pow(2 * u1, 1 / (distributionIndex + 1)); } else { b1 = Math.pow(0.5 / (1 - u1), 1 / (distributionIndex + 1)); } if (x0 < x1) { v1.setValue(0.5 * (x0 + x1 + b0 * (x0 - x1))); v2.setValue(0.5 * (x0 + x1 + b1 * (x1 - x0))); } else { v1.setValue(0.5 * (x0 + x1 + b1 * (x0 - x1))); v2.setValue(0.5 * (x0 + x1 + b0 * (x1 - x0))); } // this makes PISA's SBX compatible with other implementations // which swap the values if (pprng.nextBoolean()) { double temp = v1.getValue(); v1.setValue(v2.getValue()); v2.setValue(temp); } // guard against out-of-bounds values if (v1.getValue() < lb) { v1.setValue(lb); } else if (v1.getValue() > ub) { v1.setValue(ub); } if (v2.getValue() < lb) { v2.setValue(lb); } else if (v2.getValue() > ub) { v2.setValue(ub); } } }