/* Copyright 2009-2016 David Hadka * * This file is part of the MOEA Framework. * * The MOEA Framework is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or (at your * option) any later version. * * The MOEA Framework is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with the MOEA Framework. If not, see <http://www.gnu.org/licenses/>. */ package org.moeaframework.problem.BBOB2016; import org.moeaframework.core.variable.RealVariable; /* * The following source code is derived from the Coco Framework available at * <https://github.com/numbbo/coco> under the 3-clause BSD license. The * original code is copyright 2013 by the NumBBO/CoCO team. See the AUTHORS * file located in the Coco Framework repository for more details. */ public class BBOBUtils { /** * The lower bound returned by {@link #createTransformedVariable()}. */ private static double LOWER_BOUND = -100000.0; /** * The upper bound returned by {@link #createTransformedVariable()}. */ private static double UPPER_BOUND = 100000.0; /** * Overrides the lower and upper bounds returned by * {@link #createTransformedVariable()}. The bounds must be sufficiently * large, otherwise an exception may be thrown. * * @param lower the new lower bounds * @param upper the new upper bounds */ public static void setBounds(double lower, double upper) { LOWER_BOUND = lower; UPPER_BOUND = upper; } /** * All BBOB problems are defined with the domain [-5, 5], but the inner, * transformed functions are defined over the entire real domain. This * method returns a real decision variable bounded from * [@value LOWER_BOUNDS, @value UPPER_BOUNDS], which practically covers the * entire real domain. * * @return a real decision variable used by the BBOB inner functions */ public static RealVariable createTransformedVariable() { return new RealVariable(LOWER_BOUND, UPPER_BOUND); } public static double[] uniform(int N, long inseed) { /* generates N uniform numbers with starting seed */ long aktseed; int tmp; long[] rgrand = new long[32]; long aktrand; int i; double[] r = new double[N]; if (inseed < 0) { inseed = -inseed; } if (inseed < 1) { inseed = 1; } aktseed = inseed; for (i = 39; i >= 0; i--) { tmp = (int)Math.floor((double) aktseed / (double) 127773); aktseed = 16807 * (aktseed - tmp * 127773) - 2836 * tmp; if (aktseed < 0) { aktseed = aktseed + 2147483647; } if (i < 32) { rgrand[i] = aktseed; } } aktrand = rgrand[0]; for (i = 0; i < N; i++) { tmp = (int)Math.floor((double) aktseed / (double) 127773); aktseed = 16807 * (aktseed - tmp * 127773) - 2836 * tmp; if (aktseed < 0) { aktseed = aktseed + 2147483647; } tmp = (int)Math.floor((double) aktrand / (double) 67108865); aktrand = rgrand[tmp]; rgrand[tmp] = aktseed; r[i] = (double) aktrand / 2.147483647e9; if (r[i] == 0.0) { r[i] = 1e-99; } } return r; } public static double[] computeXOpt(long seed, int N) { double[] xopt = uniform(N, seed); for (int i = 0; i < N; i++) { xopt[i] = 8 * Math.floor(1e4 * xopt[i]) / 1e4 - 4; if (xopt[i] == 0.0) { xopt[i] = -1e-5; } } return xopt; } public static double computeFOpt(int function, int instance) { int rseed, rrseed; if (function == 4) { rseed = 3; } else if (function == 18) { rseed = 17; } else if (function == 101 || function == 102 || function == 103 || function == 107 || function == 108 || function == 109) { rseed = 1; } else if (function == 104 || function == 105 || function == 106 || function == 110 || function == 111 || function == 112) { rseed = 8; } else if (function == 113 || function == 114 || function == 115) { rseed = 7; } else if (function == 116 || function == 117 || function == 118) { rseed = 10; } else if (function == 119 || function == 120 || function == 121) { rseed = 14; } else if (function == 122 || function == 123 || function == 124) { rseed = 17; } else if (function == 125 || function == 126 || function == 127) { rseed = 19; } else if (function == 128 || function == 129 || function == 130) { rseed = 21; } else { rseed = function; } rrseed = rseed + (10000 * instance); double gval = gauss(1, rrseed)[0]; double gval2 = gauss(1, rrseed + 1)[0]; return fmin(1000., fmax(-1000., round(100. * 100. * gval / gval2) / 100.)); } public static double fmin(double a, double b) { return (a < b) ? a : b; } public static double fmax(double a, double b) { return (a > b) ? a : b; } public static double round(double x) { return Math.floor(x + 0.5); } public static double[] gauss(int N, long seed) { int i; double[] uniftmp = uniform(2 * N, seed); double[] g = new double[N]; for (i = 0; i < N; i++) { g[i] = Math.sqrt(-2 * Math.log(uniftmp[i])) * Math.cos(2 * Math.PI * uniftmp[N + i]); if (g[i] == 0.0) { g[i] = 1e-99; } } return g; } public static double[][] reshape(double[] vector, int m, int n) { double[][] B = new double[m][n]; for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { B[i][j] = vector[j * m + i]; } } return B; } public static double[][] computeRotation(long seed, int N) { double prod; double[] gvect = gauss(N * N, seed); double[][] B = reshape(gvect, N, N); for (int i = 0; i < N; i++) { for (int j = 0; j < i; j++) { prod = 0; for (int k = 0; k < N; k++) { prod += B[k][i] * B[k][j]; } for (int k = 0; k < N; k++) { B[k][i] -= prod * B[k][j]; } } prod = 0; for (int k = 0; k < N; k++) { prod += B[k][i] * B[k][i]; } for (int k = 0; k < N; k++) { B[k][i] /= Math.sqrt(prod); } } return B; } }