package src.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) {
m_GenotypeLength = genotypeLength;
initGenotype();
}
/**
* 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() {
GAIndividual c = new GAIndividual(m_GenotypeLength);
c.setGenotype((BitSet) this.m_Genotype.clone());
return c;
}
/**
* 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;
}
/**
* This method will return a string description of the GAIndividal notably
* the genotype: '0011000101'
*
* @return A descriptive string
*/
public String getStringRepresentation() {
String s = "";
for (int i = 0; i < m_GenotypeLength; i++) {
if (!m_Genotype.get(i)) {
s += '0';
} else {
s += '1';
}
}
return s;
}
/**
* 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) {
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 performs a simple one point mutation in the genotype (script
* 5.2.2). Please use the tools.RandomNumberGenerator
*/
public void mutate() {
int rand = RandomNumberGenerator.randomInt(1, m_GenotypeLength) - 1;
m_Genotype.flip(rand);
}
/**
* 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) {
if (ind1.getGenotypeLength() != ind2.getGenotypeLength()) {
System.err
.println("crossed individuals with different genotype length");
}
GAIndividual indA = (GAIndividual) ind1.clone();
GAIndividual indB = (GAIndividual) ind2.clone();
int rand = RandomNumberGenerator.randomInt(1, ind1.getGenotypeLength()) - 1;
for (int i = rand; i < ind1.getGenotypeLength(); i++) {
if (ind2.getGenotype().get(i)) {
indA.getGenotype().set(i);
} else {
indA.getGenotype().clear(i);
}
if (ind1.getGenotype().get(i)) {
indB.getGenotype().set(i);
} else {
indB.getGenotype().clear(i);
}
}
// System.out.println("______");
// System.out.println(ind1.getStringRepresentation());
// System.out.println(ind2.getStringRepresentation());
// System.out.println(rand);
// System.out.println(indA.getStringRepresentation());
// System.out.println(indB.getStringRepresentation());
GAIndividual[] crossed = { indA, indB };
return crossed;
}
/**
* 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++) {
if (RandomNumberGenerator.randomBoolean()) {
m_Genotype.set(i);
}
}
}
@Override
public int compareTo(GAIndividual o) {
return ((Double) this.evaluateAsMaxiBits()).compareTo(o
.evaluateAsMaxiBits());
}
}