I was writing my thesis and got to a problem that i can't solve. I am writing about Genetic Algorithms with steady-state selection.
The problem is that after some iteration duplicates shows up; my question is how to remove these duplicates.
How can i compare some specific elements from an object? I tried with the function Equals() but didn't figured out how to set her up.
Example: i want that this repeats until the new object isn't the same as existing objects in class population:
public void permutationRecombination(Chromosome parent1, Chromosome parent2, Chromosome child1, Chromosome child2)
{
int cLen = parent1.genes.Length;
do{
int recomPoint = ga.rng.Next(cLen - 1);
int poc1 = 0, poc2 = 0;
bool nadjen;
// prvi dio (kopiranje gena)
for (int i = 0; i <= recomPoint; i++)
{
child1.genes[i] = parent1.genes[i].Clone();
child2.genes[i] = parent2.genes[i].Clone();
}
// drugi dio (umetanje gena koji nedostaju redoslijedom iz drugog roditelja)
for (int i = recomPoint + 1; i < cLen; i++)
{
// prvo dijete
nadjen = false;
for (int j = poc1; j < cLen; j++) // trazi preostale gene iz jednog u drugom
{
for (int k = recomPoint + 1; k < cLen; k++)
{
if (parent2.genes[j].ToInteger() == parent1.genes[k].ToInteger()) //trazi
{
child1.genes[i] = parent2.genes[j].Clone();
poc1 = j + 1;
nadjen = true;
}
}
if (nadjen) break;
}
//drugo dijete;
nadjen = false;
for (int j = poc2; j < cLen; j++) // trazi preostale gene iz jednog u drugom
{
for (int k = recomPoint + 1; k < cLen; k++)
{
if (parent1.genes[j].ToInteger() == parent2.genes[k].ToInteger()) //trazi
{
child2.genes[i] = parent1.genes[j].Clone();
poc2 = j + 1;
nadjen = true;
}
}
if (nadjen) break;
}
}
if(child1.genes==parent1.genes) MessageBox.Show("postoje jednaki");
} while (child1.Equals(parent1) || child2.Equals(parent2) || child1.Equals(parent2) || child2.Equals(parent1));
}
Loading
VulpesPosted Mar 20, 2011, 4:15 PM
VulpesPosted Mar 21, 2011, 3:45 PM
The cases I thought were hanging the machine do in fact (eventually) work and the UI is simply locking up because the calculations are so CPU intensive and are running on the UI thread itself rather than a background thread.
Can you still find a particular setting where the chromosomes are all becoming null?
Mato MilicPosted Mar 21, 2011, 11:38 AM
the algorithm goes something like this
i changed your Method a little bit:
public override bool Equals(object obj)
{
if (object.ReferenceEquals(obj, null)) return false;
Chromosome chromosome = obj as Chromosome;
if (object.ReferenceEquals(chromosome, null)) return false;
for (int index = 0; index < chromosome.genes.Length; index++)
{
if (this.genes[index].ToInteger() != chromosome.genes[index].ToInteger()) return false;
}
return true; // all coresponding genes equal
}
i also added my final solution as attachement
it is not an expected behavior for chromosomes to become null, dont know why that is happening and when.
VulpesPosted Mar 21, 2011, 11:10 AM
On both occasions it gave me a list of 18 towns - one for each gene I imagine.
I tried some other combinations and sometimes the programming stopped responding without actually throw an exception.
It's difficult for me to figure this out without knowing much about the subject matter.
Is it in fact 'expected behavior' for all the chromosomes to sometimes become null before the iterations have completed? If it is, then you'll need to put in a 'null test' to stop the program from hanging though doing so will, of course, slow things down.
Mato MilicPosted Mar 20, 2011, 7:44 PM
i added your code to the chromosome class (just copied it there) but i removed the while statemant from permutationRecombination and changed in Population class the Elimincija method
public void Eliminacija(Population oldPopulation)
{
Chromosome parent1, parent2, eliminationChromosome1, eliminationChromosome2;
{
parent1 = oldPopulation.rouletteWheel();
do
{
parent2 = oldPopulation.rouletteWheel();
} while (parent1 == parent2);
do
{
eliminationChromosome1 = oldPopulation.eliminacijaJedinke();
} while (eliminationChromosome1 == parent1 || eliminationChromosome1 == parent2);
do
{
eliminationChromosome2 = oldPopulation.eliminacijaJedinke();
} while (eliminationChromosome2 == parent1 || eliminationChromosome2 == parent2 || eliminationChromosome2 == eliminationChromosome1);
//recombination
recombination(parent1, parent2, eliminationChromosome1, eliminationChromosome2);
//i added this; if the eliminationChromosome equals to any other chromosome in population
foreach (Chromosome c in population)
{
if (eliminationChromosome1.Equals(c)&&eliminationChromosome1.fitness!=c.fitness)
{
Gene tmpGene;
int gene1, gene2;
gene1 = ga.rng.Next(chromosomeSize);
do
{
gene2 = ga.rng.Next(chromosomeSize);
} while (gene1 == gene2);
tmpGene = eliminationChromosome1.genes[gene1];
eliminationChromosome1.genes[gene1] = eliminationChromosome1.genes[gene2];
eliminationChromosome1.genes[gene2] = tmpGene;
}
if (eliminationChromosome2.Equals(c)&&eliminationChromosome2.fitness!=c.fitness)
{
Gene tmpGene;
int gene1, gene2;
gene1 = ga.rng.Next(chromosomeSize);
do
{
gene2 = ga.rng.Next(chromosomeSize);
} while (gene1 == gene2);
tmpGene = eliminationChromosome2.genes[gene1];
eliminationChromosome2.genes[gene1] = eliminationChromosome2.genes[gene2];
eliminationChromosome2.genes[gene2] = tmpGene;
}
}
//mutation
oldPopulation.mutation();
//Calculate Fitness
oldPopulation.fitness();
oldPopulation.kumulativnaKazna();
}
but after some iterations al my Chromosomes get the value null ( for example when i set iterations to 100000 and "Velicina populacije(this is croatian-->that means population size) to 10 the algorithm stops because all chromosomes are null
can you please help me to figure out why that is happening?!
Mato MilicPosted Mar 20, 2011, 3:11 PM
i.e. this picture shows the structure of my classes... and the genes are value int
so if these values are the same for two chromosomes; it should generate again new childs:i meen if child.genes = { 123456789} and parent parent.genes={12345678}---> they have the same order of numbers so i need to avoid this
http://img843.imageshack.us/i/capturezo.png/[^]
VulpesPosted Mar 20, 2011, 12:44 PM
If you want two different objects whose fields have the same value to be regarded as equal, then you'll need to override Chromosome's Equals method and also its GetHashCode method as well.
See the notes and example in the MSDN docs (http://msdn.microsoft.com/en-us/library/bsc2ak47.aspx).