package twin;
//import tools.RandomNumberGenerator;
import java.util.BitSet;
import java.util.Random;
/**
* @author Maximus
*
*/
public class PBIndividualTwin implements Comparable<PBIndividualTwin> {
protected BitSet m_Genotype;
protected int m_GenotypeLength;
protected Random r = new Random();
/** Constructor **/
public PBIndividualTwin(double[] propVector) {
// This method should call initGenotype() to initialize the genotype
this.m_GenotypeLength = propVector.length;
initGenotype(propVector);
}
/**
* cloning constructor
*
* @param toClone
*/
private PBIndividualTwin(PBIndividualTwin toClone) {
this.m_Genotype = (BitSet) toClone.m_Genotype.clone();// allowed, has
// only native
// typed
// fields
this.m_GenotypeLength = toClone.m_GenotypeLength;
}
/**
* This method creates a deep copy of an individual. It should clone all
* objects contained by this object.
*
* @return An deep copy of this {@link PBIndividualTwin}
*/
@Override
public Object clone() {
PBIndividualTwin c = new PBIndividualTwin(new double[m_GenotypeLength]);
c.setGenotype((BitSet) this.m_Genotype.clone());
return c;
// return new GAIndividual(this);
}
/**
* This method evaluates the GAIndividual as a simple
* "maximize number of bits" problem. The fitness is the number of true bits
* in m_Genotype. Best fitness is reached if there are no false bits.
*
* @return The number of false bits (less is better!)
*/
public double evaluateAsMaxiBits() {
int zeros = 0;
for (int i = 0; i < m_GenotypeLength; i++) {
if (!m_Genotype.get(i)) {
zeros++;
}
}
return zeros;
}
/**
*
* @return best fitness ==0
*/
public double evaluateAsTwin() {
int f1 = 0;
int f2 = 0;
for (int i = 0; i < (m_GenotypeLength / 2); i++) {
if (m_Genotype.get(i)) {
f1++;
}
}
for (int i = (m_GenotypeLength / 2); i < m_GenotypeLength; i++) {
if (m_Genotype.get(i)) {
f2++;
}
}
return (m_GenotypeLength / 2) - Math.abs(f1 - f2);
}
/**
* This method will return a string description of the GAIndividal notably
* the genotype: '0011000101'
*
* @return A descriptive string
*/
public String getStringRepresentation() {
// this should return exactly the representation shown in the comment
// above:
// only 0 (for false bits) and 1 (for true bits) with no extra white
// space!
String representation = "";
for (int i = 0; i < m_GenotypeLength; i++) {
representation = m_Genotype.get(i) ? representation + "1"
: representation + "0";
}
return representation;
}
/**
* This method will allow the user to read the GA genotype
*
* @return BitSet
*/
public BitSet getGenotype() {
return m_Genotype;
}
/**
* This method will allow the user to set the current GA genotype. Should
* check if the length of the BitSet and the genotype length match.
*
* @param b
* The new genotype of the Individual
*/
public void setGenotype(BitSet b) {
this.m_Genotype = b;
}
/**
* This method allows the user to read the length of the genotype. This may
* be necessary since BitSet.length only returns the index of the last
* significant bit.
*
* @return The length of the genotype.
*/
public int getGenotypeLength() {
return m_GenotypeLength;
}
/**
* This method initializes the GA genotype randomly. Please use the
* tools.RandomNumberGenerator
*
* @param propVector
*/
public void initGenotype(double[] propVector) {
m_Genotype = new BitSet(m_GenotypeLength);
for (int i = 0; i < m_GenotypeLength; i++) {
if (r.nextDouble() < propVector[i]) {
m_Genotype.set(i);
}
}
}
@Override
public int compareTo(PBIndividualTwin o) {
// return ((Double) this.evaluateAsMaxiBits()).compareTo(o
// .evaluateAsMaxiBits());
return ((Double) this.evaluateAsTwin()).compareTo(o.evaluateAsTwin());
}
}