Reputation: 921
I am not familiar much with the java List and arrayList .. i just need something to work smoothly to append and sort.
My algorithm is simple:
set a father string
add father to speciesList
mutate father to some new child
make this new child the future father
go to step 2
The definitions of ga_
and ga_struct
is given here
public class ga_struct {
public String gene;
public int fitness;
}
public class ga_{
public List<ga_struct> vector= new ArrayList<ga_struct>();
public void sortspecies()
{
Collections.sort(vector,new Comparator<ga_struct>() {
@Override
public int compare(ga_struct o1, ga_struct o2) {
int res;
if(o1.fitness<o2.fitness)
res=-1;
else if(o1.fitness>o2.fitness)
res=1;
else
res=0;
return res;
}
}
);
}
public ga_struct mutate(ga_struct parent)
{
Random r= new Random();
...... do some modification to the parent
return parent;
}
}
I have been doing this
ga_ newSpecies = new ga_();
Random r= new Random(10);
ga_struct father= new ga_struct();
father.gene="123";
newSpecies.vector.add(father);
for (int i = 1; i < 10; i++) {
ga_struct ng = new ga_struct();
ng=newSpecies.mutate(father);
ng.fitness=i;
newSpecies.vector.add(ng);
father=ng;
System.out.println(newSpecies.vector.get(i).gene+" with fitness factor "+newSpecies.vector.get(i).fitness);
}
newSpecies.sortspecies();
System.out.println("\ncurrent population\n");
for (int i = 0; i < 10; i++) {
System.out.println(newSpecies.vector.get(i).gene+" with fitness factor "+newSpecies.vector.get(i).fitness);
}
The mutator function just alter the String(gene)
one character at a time. I just mutated 9 new species from the "father" in the first loop. But.. I dont know why the output of the code is giving me this-
133 with fitness factor 1
433 with fitness factor 2
433 with fitness factor 3
443 with fitness factor 4
453 with fitness factor 5
553 with fitness factor 6
563 with fitness factor 7
563 with fitness factor 8
573 with fitness factor 9
current population
573 with fitness factor 9
573 with fitness factor 9
573 with fitness factor 9
573 with fitness factor 9
573 with fitness factor 9
573 with fitness factor 9
573 with fitness factor 9
573 with fitness factor 9
573 with fitness factor 9
573 with fitness factor 9
The first loop is proof that mutation is going slowly.. And i also added immediately after a mutation, then why is that later on all of them are just overwritten by the latest edition?
Upvotes: 3
Views: 395
Reputation: 20371
You're working with a single object everywhere, you never add a new ga_struct
instance to the list. Your mutate()
method appears to simply modify the parent
parameter and returns it - it's still the same object, just modified, which means it's modified everywhere.
public ga_struct mutate(ga_struct parent)
{
Random r= new Random();
...... do some modification to the parent
return parent;
}
You do create a new instance of ga_struct
but you immediately overwrite it by setting the reference to the mutated father
(which is still the same instance, just modified):
for (int i = 1; i < 10; i++) {
ga_struct ng = new ga_struct();
ng=newSpecies.mutate(father); //the new ga_struct is overwritten
ng.fitness=i;
newSpecies.vector.add(ng);
father=ng;
System.out.println(newSpecies.vector.get(i).gene+" with fitness factor "+newSpecies.vector.get(i).fitness);
}
Your output in this loop seems to work because you see the modifications to father
in the order they happen. However, what you're actually doing is just adding references to the same (modified) object over and over into the List
.
Thus, when you finally print them all out, you see 10 duplicate entries in the List
.
My suggestion is to change mutate()
to return a new instance of ga_struct
- you could either create a new object and set it's gene
field to be the mutated gene
field from parent
. Or you could clone
parent
and then change the clone's gene string. In either case, you will end up returning a new instance of ga_struct
which should fix the problem.
public ga_struct mutate(ga_struct parent)
{
Random r= new Random();
ga_struct mutant = parent.clone();
//or
//ga_struct mutant = new ga_struct();
//mutant.gene = parent.gene;
...... do some modification to the mutant
return mutant; //now you'll be returning a new object not just a modified one
}
Upvotes: 0
Reputation: 4086
First off, your object usage is a bit weird.
In mutate, you seem to be changing and returning the father.
This means your list will contain multiple references to the same instance.
to clarify:
public ga_struct mutate(ga_struct parent) //takes in reference to parent
{
Random r= new Random(); //modifies parent
...... do some modification to the parent
return parent; //return reference to parent
}
And in your main:
ga_ newSpecies = new ga_();
Random r= new Random(10);
ga_struct father= new ga_struct();//instantiate father
father.gene="123";
newSpecies.vector.add(father);
for (int i = 1; i < 10; i++) {
ga_struct ng = new ga_struct();//create new instance for child
ng=newSpecies.mutate(father);//set ng as reference to same instance as father, instance instantiated on previous line is discarded
ng.fitness=i;
newSpecies.vector.add(ng);
father=ng;
System.out.println(newSpecies.vector.get(i).gene+" with fitness factor "+newSpecies.vector.get(i).fitness);
}
Try Something more like this:
public ga_struct mutate(ga_struct parent)
{
ga_struct ng = new ga_struct();
ng.gene = father.gene;
Random r= new Random();
//do some modification to ng
return ng;
}
and in your main:
a_ newSpecies = new ga_();
Random r= new Random(10);
ga_struct father= new ga_struct();
father.gene="123";
newSpecies.vector.add(father);
for (int i = 1; i < 10; i++) {
ga_struct ng=newSpecies.mutate(father);
ng.fitness=i;
newSpecies.vector.add(ng);
father=ng;
System.out.println(newSpecies.vector.get(i).gene+" with fitness factor "+newSpecies.vector.get(i).fitness);
}
newSpecies.sortspecies();
System.out.println("\ncurrent population\n");
for (int i = 0; i < 10; i++) {
System.out.println(newSpecies.vector.get(i).gene+" with fitness factor "+newSpecies.vector.get(i).fitness);
}
Upvotes: 3
Reputation: 9777
You're not creating a new object, you've added the father object 9 times to the vector.
Essentially what you've got is
father -> obj@123
What your List object looks like is [ obj@123, obj@123, obj@123, ... ]
You're going to need to create new instances to record this. I would recommend implementing the "clone()" method to do this.
Upvotes: 1