Reputation: 2140
I have a class called Operators
that contains three static methods: crossover
, mutate
, bestOffSpring
. I call these methods in another class such as:
List<Cell> offSpring = Operators.crossover(parent1, parent2);
Cell bestOffSpring = Operators.bestOffSpring(offSpring);
Cell mutatedChild = Operators.mutate(bestOffSpring);
The problem that I am facing is when I just call the crossover
and bestOffSpring
, their results are produced correctly. However, when I call mutate
method, the results of the other two are not correct. In other words, the results of the crossover
and bestOffSpring
are affected by calling the mutate
method. I checked the logic of the three methods and I didn't find any mistake.
My question is does calling many static methods from one class affect their results?
Here is the code of the three methods:
public class Operators {
public static List<Cell> crossover(Cell parenta_,Cell parentb_)
{
BitSet parenta = parenta_.getChrom();
BitSet parentb = parentb_.getChrom();
Random rand = new Random();
int setLength = parenta.length();
//System.out.println("<"+setLength+">");
BitSet child1 = new BitSet(setLength);
BitSet child2 = new BitSet(setLength);
//One point splicing
int slicePoint = rand.nextInt(setLength); //rnd num between 0-70
System.out.print("<"+slicePoint+">");
BitSet a = (BitSet)parenta.clone();
a.clear(slicePoint,setLength);
BitSet b = (BitSet)parenta.clone();
b.clear(0,slicePoint);
BitSet c = (BitSet)parentb.clone();
c.clear(slicePoint,setLength);
BitSet d = (BitSet)parentb.clone();
d.clear(0,slicePoint);
//Combine start of p1 with end of p2
child1.or(a);
child1.or(d);
//Combine start of p2 with end of p1
child2.or(c);
child2.or(b);
//Return the children
//BitSet[] offspring = {child1, child2};
Cell child1_ = new Cell(child1);
Cell child2_ = new Cell(child2);
System.out.print("C1 = " + child1_.printBit());
System.out.print(", C2 = " + child2_.printBit() + " ");
List<Cell> offSpring = new ArrayList<>();
offSpring.add(child1_);
offSpring.add(child2_);
return offSpring;
}
public static Cell mutate(Cell original_){
BitSet original = original_.getChrom();
Double mProb = 0.4;
Random rand = new Random();
for(int m = 0; m < original.length(); m++)
{
//Small possibility a bit copied from parent to child is mutated
if(rand.nextDouble() <= mProb)
original.flip(m);
}
//Return the (possibly) strategy
Cell mutated = new Cell(original);
return mutated;
}
public static Cell bestOffSpring(List<Cell> offSpring){
int offSpringFit1 = offSpring.get(0).getFitness();
int offSpringFit2 = offSpring.get(1).getFitness();
if (offSpringFit1 > offSpringFit2)
return offSpring.get(0);
else
return offSpring.get(1);
}
}
Here is an example, the correct results of calling crossover and bestOffSpring are:
OffSpring are 100111 <4> and 111101 <5>, best is 111101
OffSpring are 101010 <3> and 111101 <5>, best is 111101
OffSpring are 101111 <5> and 110101 <4>, best is 101111
OffSpring are 110111 <5> and 110111 <5>, best is 110111
OffSpring are 101101 <4> and 110111 <5>, best is 110111
OffSpring are 101010 <3> and 111010 <4>, best is 111010
When the mutate method is called the results are:
OffSpring are 101101 <4> and 100110 <5>, best is 100110
OffSpring are 101010 <3> and 1100 <5>, best is 1100
OffSpring are 100111 <4> and 10101 <5>, best is 10101
OffSpring are 110111 <5> and 111100 <5>, best is 111100
OffSpring are 101100 <5> and 110101 <4>, best is 101100
OffSpring are 11101 <4> and 101010 <3>, best is 11101
The difference between the two results is that the two offsprings in the correct results have the right length (in each offspring how many 1's) and the best among them is selected correctly. While the later does not give the right length and then produce the wrong best offspring.
Upvotes: 0
Views: 73
Reputation: 2583
Side effects ...
if(rand.nextDouble() <= mProb)
original.flip(m);
...
One can presume that original_.getChrom()
returns the directly the underlying BitSet, so you end up flipping the bites of bestOffSpring
which in turn will affect the fitness function score after you run mutate()
.
To avoid the side effect just create a copy of the original Bitset
Bitset original = new Bitset(original_.getChrom().size());
original.or(original_.getChrom().size())
Check the Defensive programming tag
Upvotes: 1