// BinaryReal.java
//
// Author:
// Antonio J. Nebro <antonio@lcc.uma.es>
// Juan J. Durillo <durillo@lcc.uma.es>
//
// Copyright (c) 2011 Antonio J. Nebro, Juan J. Durillo
//
// This program 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.
//
// This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
package jmetal.encodings.variable;
import jmetal.core.Variable;
import jmetal.util.JMException;
import java.util.BitSet;
/** This class extends the Binary class to represent a Real encodings.variable encoded by
* a binary string
*/
public class BinaryReal extends Binary {
/**
* Defines the default number of bits used for binary coded variables.
*/
public static final int DEFAULT_PRECISION = 30;
/**
* Stores the real value of the encodings.variable
*/
private double value_;
/**
* Stores the lower limit for the encodings.variable
*/
private double lowerBound_;
/**
* Stores the upper limit for the encodings.variable
*/
private double upperBound_;
/**
* Constructor.
*/
public BinaryReal() {
super();
} //BinaryReal
/**
* Constructor
* @param numberOfBits Length of the binary string.
* @param lowerBound The lower limit for the encodings.variable
* @param upperBound The upper limit for the encodings.variable.
*/
public BinaryReal(int numberOfBits, double lowerBound, double upperBound){
super(numberOfBits);
lowerBound_ = lowerBound;
upperBound_ = upperBound;
decode();
} //BinaryReal
/**
* @param bits BitSet
* @param nbBits Number of bits
* @param lowerBound Lower bound
* @param upperBound Upper bound
*/
public BinaryReal(BitSet bits, int nbBits, double lowerBound, double upperBound) {
super(nbBits);
bits_ = bits;
lowerBound_ = lowerBound;
upperBound_ = upperBound;
decode();
} // BinaryReal
/**
* Copy constructor
* @param variable The encodings.variable to copy
*/
public BinaryReal(BinaryReal variable){
super(variable);
lowerBound_ = variable.lowerBound_;
upperBound_ = variable.upperBound_;
/*
numberOfBits_ = encodings.variable.numberOfBits_;
bits_ = new BitSet(numberOfBits_);
for (int i = 0; i < numberOfBits_; i++)
bits_.set(i,encodings.variable.bits_.get(i));
*/
value_ = variable.value_;
} //BinaryReal
/**
* Decodes the real value encoded in the binary string represented
* by the <code>BinaryReal</code> object. The decoded value is stores in the
* <code>value_</code> field and can be accessed by the method
* <code>getValue</code>.
*/
public void decode(){
double value = 0.0;
for (int i = 0; i < numberOfBits_; i++) {
if (bits_.get(i)) {
value += Math.pow(2.0,i);
}
}
value_ = value * (upperBound_ - lowerBound_) /
(Math.pow(2.0,numberOfBits_)-1.0);
value_ += lowerBound_;
} //decode
/**
* Returns the double value of the encodings.variable.
* @return the double value.
*/
public double getValue() {
return value_;
} //getValue
/**
* This implementation is efficient for binary string of length up to 24
* bits, and for positive intervals.
*
* @see jmetal.core.Variable#setValue(double)
*
* Contributor: jl hippolyte
*/
@Override
public void setValue(double value) throws JMException {
if (numberOfBits_ <= 24 && lowerBound_ >= 0) {
BitSet bitSet;
if (value <= lowerBound_) {
bitSet = new BitSet(numberOfBits_);
bitSet.clear();
} else if (value >= upperBound_) {
bitSet = new BitSet(numberOfBits_);
bitSet.set(0, numberOfBits_);
} else {
bitSet = new BitSet(numberOfBits_);
bitSet.clear();
// value is the integerToCode-th possible value, what is integerToCode?
int integerToCode = 0;
double tmp = lowerBound_;
double path = (upperBound_ - lowerBound_) / (Math.pow(2.0, numberOfBits_) - 1);
while (tmp < value) {
tmp += path;
integerToCode++;
}
int remain = integerToCode;
for (int i = numberOfBits_ - 1; i >= 0; i--) {
//System.out.println("i= " + i);
int ithPowerOf2 = (int) Math.pow(2, i);
if (ithPowerOf2 <= remain) {
//System.out
// .println(ithPowerOf2thValue + " <= " + remain);
bitSet.set(i);
remain -= ithPowerOf2;
} else {
bitSet.clear(i);
}
}
}
this.bits_ = bitSet;
this.decode();
} else {
if (lowerBound_ < 0)
throw new JMException("Unsupported lowerbound: " + lowerBound_
+ " > 0");
if (numberOfBits_>= 24)
throw new JMException("Unsupported bit string length"
+ numberOfBits_ + " is > 24 bits");
}
}// setValue
/**
* Creates an exact copy of a <code>BinaryReal</code> object.
* @return The copy of the object
*/
public Variable deepCopy() {
return new BinaryReal(this);
} //deepCopy
/**
* Returns the lower bound of the encodings.variable.
* @return the lower bound.
*/
public double getLowerBound() {
return lowerBound_;
} // getLowerBound
/**
* Returns the upper bound of the encodings.variable.
* @return the upper bound.
*/
public double getUpperBound() {
return upperBound_;
} // getUpperBound
/**
* Sets the lower bound of the encodings.variable.
* @param lowerBound the lower bound.
*/
public void setLowerBound(double lowerBound) {
lowerBound_ = lowerBound;
} // setLowerBound
/**
* Sets the upper bound of the encodings.variable.
* @param upperBound the upper bound.
*/
public void setUpperBound(double upperBound) {
upperBound_ = upperBound;
} // setUpperBound
/**
* Returns a string representing the object.
* @return the string.
*/
@Override
public String toString() {
return value_+"";
} // toString
} // BinaryReal