/* 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.core.variable; import java.text.MessageFormat; import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; import org.moeaframework.core.PRNG; import org.moeaframework.core.Variable; /** * Decision variable for real values. */ public class RealVariable implements Variable { private static final long serialVersionUID = 3141851312155686224L; private static final String VALUE_OUT_OF_BOUNDS = "value out of bounds (value: {0}, min: {1}, max: {2})"; /** * The current value of this decision variable. */ private double value; /** * The lower bound of this decision variable. */ private final double lowerBound; /** * The upper bound of this decision variable. */ private final double upperBound; /** * Constructs a real variable in the range {@code lowerBound <= x <= * upperBound} with an uninitialized value. * * @param lowerBound the lower bound of this decision variable, inclusive * @param upperBound the upper bound of this decision variable, inclusive */ public RealVariable(double lowerBound, double upperBound) { this(Double.NaN, lowerBound, upperBound); } /** * Constructs a real variable in the range {@code lowerBound <= x <= * upperBound} with the specified initial value. * * @param value the initial value of this decision variable * @param lowerBound the lower bound of this decision variable, inclusive * @param upperBound the upper bound of this decision variable, inclusive * @throws IllegalArgumentException if the value is out of bounds * {@code (value < lowerBound) || (value > upperBound)} */ public RealVariable(double value, double lowerBound, double upperBound) { super(); this.value = value; this.lowerBound = lowerBound; this.upperBound = upperBound; if ((value < lowerBound) || (value > upperBound)) { throw new IllegalArgumentException(MessageFormat.format( VALUE_OUT_OF_BOUNDS, value, lowerBound, upperBound)); } } /** * Returns the current value of this decision variable. * * @return the current value of this decision variable */ public double getValue() { return value; } /** * Sets the value of this decision variable. * * @param value the new value for this decision variable * @throws IllegalArgumentException if the value is out of bounds * {@code (value < getLowerBound()) || (value > getUpperBound())} */ public void setValue(double value) { if ((value < lowerBound) || (value > upperBound)) { throw new IllegalArgumentException(MessageFormat.format( VALUE_OUT_OF_BOUNDS, value, lowerBound, upperBound)); } this.value = value; } /** * Returns the lower bound of this decision variable. * * @return the lower bound of this decision variable, inclusive */ public double getLowerBound() { return lowerBound; } /** * Returns the upper bound of this decision variable. * * @return the upper bound of this decision variable, inclusive */ public double getUpperBound() { return upperBound; } @Override public RealVariable copy() { return new RealVariable(value, lowerBound, upperBound); } @Override public String toString() { return Double.toString(value); } @Override public int hashCode() { return new HashCodeBuilder() .append(lowerBound) .append(upperBound) .append(value) .toHashCode(); } @Override public boolean equals(Object obj) { if (obj == this) { return true; } else if ((obj == null) || (obj.getClass() != getClass())) { return false; } else { RealVariable rhs = (RealVariable)obj; return new EqualsBuilder() .append(lowerBound, rhs.lowerBound) .append(upperBound, rhs.upperBound) .append(value, rhs.value) .isEquals(); } } @Override public void randomize() { setValue(PRNG.nextDouble(lowerBound, upperBound)); } }