/* * Copyright 2007-2013 * Licensed under GNU Lesser General Public License * * This file is part of EpochX * * EpochX 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. * * EpochX 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 EpochX. If not, see <http://www.gnu.org/licenses/>. * * The latest version is available from: http:/www.epochx.org */ package org.epochx.tools; /** * This class provides correct solutions to various benchmark problems that can be * used within fitness functions * * @since 2.0 */ public final class BenchmarkSolutions { private BenchmarkSolutions(){} /** * Calculates and returns the correct result of the target function used in the * cubic regression benchmark problem, for the given value of <code>x</code>. * * The target function of the cubic regression function is: x + x^2 + x^3 * * @param x the input value * @return the result of applying the function to the given value of <code>x</code> */ public static Double cubicRegression(Double x) { return x + x * x + x * x * x; } /** * Calculates and returns the correct result of the target function used in the * quartic regression benchmark problem, for the given value of <code>x</code>. * * The target function of the quartic regression function is: x + x^2 + x^3 + x^4 * * @param x the input value * @return the result of applying the function to the given value of <code>x</code> */ public static Double quarticRegression(Double x) { return cubicRegression(x) + x * x * x * x; } /** * Calculates and returns the correct result of the target function used in the * sextic regression benchmark problem, for the given value of <code>x</code>. * * The target function of the sextic regression function is: x^6 - (2 * x^4) + x^2 * * @param x the input value * @return the result of applying the function to the given value of <code>x</code> */ public static Double sexticRegression(Double x) { return Math.pow(x, 6) - (2 * Math.pow(x, 4)) + Math.pow(x, 2); } /** * Calculates and returns the correct result of the multiplexer benchmark problem * for the given input values. * * The first <code>n</code> elements of the input array are the address bits and the * remaining <code>m</code> bits are the data bits. The following must be true: * * <code>m = 2^m</code> * * If this will be called multiple times, it is more efficient to obtain the number * of address bits using {@link #multiplexerAddressBits(int)} and pass them to the * {@link #multiplexer(boolean[], int)} method. * * @param inputs an array of boolean inputs * @return the result of applying a correct multiplexer on the given inputs */ public static Boolean multiplexer(Boolean[] inputs) { int noAddressBits = multiplexerAddressBits(inputs.length); return multiplexer(inputs, noAddressBits); } /** * Calculates and returns the correct result of the multiplexer benchmark problem * for the given input values and the number of address bits. * * The first <code>n</code> elements of the input array are the address bits and the * remaining <code>m</code> bits are the data bits. The following must be true: * * <code>m = 2^m</code> * * @param inputs an array of boolean inputs * @param noAddressBits the number of address bits to expect in the inputs array * @return the result of applying a correct multiplexer on the given inputs */ public static Boolean multiplexer(Boolean[] inputs, int noAddressBits) { int dataPosition = 0; for (int i = 0; i < noAddressBits; i++) { if (inputs[i]) { dataPosition += Math.pow(2, i); } } return inputs[noAddressBits + dataPosition]; } /** * Calculates and returns the number of address bits are required for a given number of * input bits when solving the multiplexer problem. * * @param noBits the total number of input bits, including both address and data bits * @return the number of address bits * @throws IllegalArgumentException if the number of data bits is invalid, given the number * of address bits */ public static int multiplexerAddressBits(int noBits) { int noAddressBits = 0; int noDataBits = 0; do { noAddressBits++; noDataBits = (int) Math.pow(2, noAddressBits); } while (noAddressBits + noDataBits < noBits); if ((noAddressBits + noDataBits) != noBits) { throw new IllegalArgumentException("The number of data bits must be 2 to the power of the number of address bits"); } return noAddressBits; } /** * Calculates and returns the correct result of the majority benchmark problem * for the given input values. * * @param inputs an array of boolean inputs * @return the result of applying majority on the given input values */ public static Boolean majority(Boolean[] inputs) { int trueCount = 0; for (Boolean b: inputs) { if (b) { trueCount++; } } return (trueCount >= (inputs.length / 2)); } /** * Calculates and returns the correct result of checking for even parity in the * given input values. * * @param inputs an array of boolean inputs * @return true if there is an even number of true values in the input array */ public static Boolean evenParity(Boolean[] inputs) { int noTrues = 0; for (boolean b: inputs) { if (b) { noTrues++; } } return ((noTrues % 2) == 0); } /** * Calculates and returns the correct result of checking for odd parity in the * given input values. * * @param inputs an array of boolean inputs * @return true if there is an odd number of true values in the input array */ public static Boolean oddParity(Boolean[] inputs) { return !evenParity(inputs); } }