package individuals;
//import tools.RandomNumberGenerator;
import java.util.BitSet;
import tools.RandomNumberGenerator;
public class GAIndividual implements Comparable<GAIndividual> {
protected BitSet m_Genotype;
protected int m_GenotypeLength;
/** Constructor **/
public GAIndividual(int genotypeLength) {
// TODO implement this
// This method should call initGenotype() to initialize the genotype
this.m_GenotypeLength = genotypeLength;
initGenotype();
}
private GAIndividual(GAIndividual toClone) {
this.m_Genotype = (BitSet) toClone.m_Genotype.clone();// allowed, has
// only native
// 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 GAIndividual}
*/
@Override
public Object clone() {
// Clone methoden... nein!
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 sum = 0;
for (int i = 0; i < m_GenotypeLength; i++) {
if (m_Genotype.get(i)) {
sum++;
}
}
return sum;
}
/**
* This method will return a string description of the GAIndividal notably
* the genotype: '0011000101'
*
* @return A descriptive string
*/
public String getStringRepresentation() {
// TODO implement this
// 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() {
// TODO implement this
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) {
assert b.length() == m_Genotype.length() : "Lengths intern ="
+ m_GenotypeLength + " input:" + b.length();
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() {
// TODO implement this
return m_GenotypeLength;
}
/**
* This method performs a simple one point mutation in the genotype (script
* 5.2.2). Please use the tools.RandomNumberGenerator
*/
public void mutate() {
m_Genotype.flip(RandomNumberGenerator.randomInt(0, m_GenotypeLength));
}
/**
* This method performs a simple one point crossover of two GAIndividuals
* (script 5.2.1). Please use the tools.RandomNumberGenerator
*
* @return An array of length 2 with the two resulting GAIndivuals
*/
public static GAIndividual[] crossover(GAIndividual ind1, GAIndividual ind2) {
assert ind1.m_GenotypeLength == ind2.m_GenotypeLength;
int splitPoint = RandomNumberGenerator.randomInt(0,
ind1.m_GenotypeLength);
GAIndividual ind1Clone = (GAIndividual) ind1.clone();
GAIndividual ind2Clone = (GAIndividual) ind2.clone();
for (int i = splitPoint; i < ind1Clone.m_GenotypeLength; i++) {
boolean saveBit = ind1Clone.m_Genotype.get(i);
ind1Clone.m_Genotype.set(i, ind2Clone.m_Genotype.get(i));
ind2Clone.m_Genotype.set(i, saveBit);
}
return new GAIndividual[] { ind2Clone, ind1Clone };
}
/**
* This method initializes the GA genotype randomly. Please use the
* tools.RandomNumberGenerator
*/
public void initGenotype() {
m_Genotype = new BitSet(m_GenotypeLength);
for (int i = 0; i < m_GenotypeLength; i++) {
m_Genotype.set(i, RandomNumberGenerator.randomBoolean());
}
// TODO implement this
}
@Override
public int compareTo(GAIndividual o) {
if (this.evaluateAsMaxiBits() > o.evaluateAsMaxiBits()) {
return 1;
} else if (this.evaluateAsMaxiBits() < o.evaluateAsMaxiBits()) {
return -1;
}
return 0;
}
}