遗传算法每次都给出相同的数据
Genetic Algorithm giving same data every time
我也在尝试在 java 中实现 GA 来求解方程(目前不重要)
我有一个 class 用于实现 Comparable 的染色体(按适合度排序)
和我自己的 IChromosome 接口。
我在这个 class 中提供了交叉、变异等功能:
有些事情是这样的:
public interface IChromosome
{
public int getSize();
public void setSize(int s);
public IGene[] getGenes();
public void setGenes(IGene[] genes);
public IGene getGene(int i);
public void setGene(int i , IGene val);
public double getFitness();
public IChromosome[] crossOver(IChromosome c2);
public IChromosome mutate();
}
我的 GA 程序的主要部分是这样的:
public class GeneticAlgorithm
{
final int populationSize;
int crossOverRate;// Probability in persent
int mutationRate;// Probability in persent
int elitismRate;// in persent
int TournamentNumber;//number of random Chromosomes to compete in Tournament
int repeatCount;
Chromosome [] currentGeneration;
Chromosome [] nextGeneration;
public GeneticAlgorithm(int populationSize, int crossOverRate, int mutationRate, int ElitismRate, int TournamentNumber)
{
this.populationSize = populationSize;
this.crossOverRate = crossOverRate;
this.mutationRate = mutationRate;
this.elitismRate = ElitismRate;
this.TournamentNumber = TournamentNumber;
repeatCount = 0;
currentGeneration = new Chromosome[populationSize];
nextGeneration = new Chromosome[populationSize];
for (int i = 0; i < populationSize; i++)
{
currentGeneration[i] =new Chromosome(Chromosome.getPolynomial().getSize());//Also randomize it; //size is from another class
}
}
private Chromosome[] select()
{
Chromosome[] temp = new Chromosome[TournamentNumber];
//choose populationSize random uniqe number
ArrayList<Integer> nums = new ArrayList<>();
for (int i = 0; i < populationSize; i++)
{
nums.add(i);
}
Collections.shuffle(nums);
for (int i = 0; i < TournamentNumber; i++)
{
temp[i]=new Chromosome(currentGeneration[nums.get(i)]);
}
Arrays.sort(temp);
Chromosome[] res = new Chromosome[2];
//choosing best Chromosomes
res[0] = new Chromosome(temp[TournamentNumber-1]);
res[1] = new Chromosome(temp[TournamentNumber-2]);
return res;
}
public void repeat()
{
repeatCount++;
Arrays.sort(currentGeneration,Collections.reverseOrder());
int elitism = (populationSize*elitismRate)/100;
for (int i = 0; i < elitism ; i++)
{
nextGeneration[i] = new Chromosome(currentGeneration[i]);
}
int cop = 0;//Cross Over Probability
int mp;//mutation Probability
Random rnd = new Random();
Chromosome [] sel;
Chromosome [] temp;
Chromosome ch1 , ch2;
for (int i = elitism; i < populationSize; i++)
{
cop = rnd.nextInt(100);
sel = new Chromosome[2];
sel = select();
if(cop <= crossOverRate)
{
temp = (Chromosome[]) ( sel[0].crossOver(sel[1]) );//tested , And I 'm sure cross over function working well
ch1 = temp[0];
ch2 = temp[1];
}
else
{
ch1 = new Chromosome(sel[0]);
ch2 = new Chromosome(sel[1]);
}
mp = rnd.nextInt(100);
if(mp< mutationRate)
{
ch1.mutate();
}
nextGeneration[i]= new Chromosome(ch1);
if(++i<populationSize)
{
nextGeneration[i]= new Chromosome(ch2);
}
}//for
//copiny current generation to nextGeneration
for (int i = 0; i < populationSize; i++)
{
currentGeneration[i] = new Chromosome(nextGeneration[i]);
}
}//repeat
}
一切看起来都很正常,但是经过几代之后(调用repeat()
)我所有的一代染色体都将成为保存值。
调试了很多次程序,都没有找到。
可能是什么问题?
我觉得你的算法早收敛了,如果其他都OK的话。
可能的解决方案是:
1- 将精英率设置为零;
2- 降低交叉率;
3-增加突变率。
另外如果要解决的问题很简单,GA自然早收敛。
我也在尝试在 java 中实现 GA 来求解方程(目前不重要)
我有一个 class 用于实现 Comparable 的染色体(按适合度排序) 和我自己的 IChromosome 接口。
我在这个 class 中提供了交叉、变异等功能: 有些事情是这样的:
public interface IChromosome
{
public int getSize();
public void setSize(int s);
public IGene[] getGenes();
public void setGenes(IGene[] genes);
public IGene getGene(int i);
public void setGene(int i , IGene val);
public double getFitness();
public IChromosome[] crossOver(IChromosome c2);
public IChromosome mutate();
}
我的 GA 程序的主要部分是这样的:
public class GeneticAlgorithm
{
final int populationSize;
int crossOverRate;// Probability in persent
int mutationRate;// Probability in persent
int elitismRate;// in persent
int TournamentNumber;//number of random Chromosomes to compete in Tournament
int repeatCount;
Chromosome [] currentGeneration;
Chromosome [] nextGeneration;
public GeneticAlgorithm(int populationSize, int crossOverRate, int mutationRate, int ElitismRate, int TournamentNumber)
{
this.populationSize = populationSize;
this.crossOverRate = crossOverRate;
this.mutationRate = mutationRate;
this.elitismRate = ElitismRate;
this.TournamentNumber = TournamentNumber;
repeatCount = 0;
currentGeneration = new Chromosome[populationSize];
nextGeneration = new Chromosome[populationSize];
for (int i = 0; i < populationSize; i++)
{
currentGeneration[i] =new Chromosome(Chromosome.getPolynomial().getSize());//Also randomize it; //size is from another class
}
}
private Chromosome[] select()
{
Chromosome[] temp = new Chromosome[TournamentNumber];
//choose populationSize random uniqe number
ArrayList<Integer> nums = new ArrayList<>();
for (int i = 0; i < populationSize; i++)
{
nums.add(i);
}
Collections.shuffle(nums);
for (int i = 0; i < TournamentNumber; i++)
{
temp[i]=new Chromosome(currentGeneration[nums.get(i)]);
}
Arrays.sort(temp);
Chromosome[] res = new Chromosome[2];
//choosing best Chromosomes
res[0] = new Chromosome(temp[TournamentNumber-1]);
res[1] = new Chromosome(temp[TournamentNumber-2]);
return res;
}
public void repeat()
{
repeatCount++;
Arrays.sort(currentGeneration,Collections.reverseOrder());
int elitism = (populationSize*elitismRate)/100;
for (int i = 0; i < elitism ; i++)
{
nextGeneration[i] = new Chromosome(currentGeneration[i]);
}
int cop = 0;//Cross Over Probability
int mp;//mutation Probability
Random rnd = new Random();
Chromosome [] sel;
Chromosome [] temp;
Chromosome ch1 , ch2;
for (int i = elitism; i < populationSize; i++)
{
cop = rnd.nextInt(100);
sel = new Chromosome[2];
sel = select();
if(cop <= crossOverRate)
{
temp = (Chromosome[]) ( sel[0].crossOver(sel[1]) );//tested , And I 'm sure cross over function working well
ch1 = temp[0];
ch2 = temp[1];
}
else
{
ch1 = new Chromosome(sel[0]);
ch2 = new Chromosome(sel[1]);
}
mp = rnd.nextInt(100);
if(mp< mutationRate)
{
ch1.mutate();
}
nextGeneration[i]= new Chromosome(ch1);
if(++i<populationSize)
{
nextGeneration[i]= new Chromosome(ch2);
}
}//for
//copiny current generation to nextGeneration
for (int i = 0; i < populationSize; i++)
{
currentGeneration[i] = new Chromosome(nextGeneration[i]);
}
}//repeat
}
一切看起来都很正常,但是经过几代之后(调用repeat()
)我所有的一代染色体都将成为保存值。
调试了很多次程序,都没有找到。
可能是什么问题?
我觉得你的算法早收敛了,如果其他都OK的话。
可能的解决方案是: 1- 将精英率设置为零; 2- 降低交叉率; 3-增加突变率。
另外如果要解决的问题很简单,GA自然早收敛。