我有一个名为GeneticOperator
的类,该类负责遗传程序中的突变和交叉算子。对于不同的突变,我有不同的功能,对于突变,我有一个公共功能,其中我有关于type的switch语句。在功能random()
中,我指定了突变类型和染色体中要突变的基因数量。
class GeneticOperator
{
public:
enum MutationType
{
FUNCTION_MUTATION,
ARGUMENTS_MUTATION,
WORSTGENES_MUTATION //not implemented yet
};
enum CrossoverType //not implemented yet
{
ONEPOINT_CROSSOVER,
TWOPOINT_CROSSOVER,
UNIFORM_CROSSOVER,
BESTGENE_CROSSOVER
};
public:
GeneticOperator();
//GeneticOperator(const GeneGenerator* geneGenerator,
// int maxNGene);
ChromosomePtr mutation(const Chromosome& parent) const;
private:
void random();
ChromosomePtr functionMutation(const Chromosome& parent) const;
ChromosomePtr argumentsMutation(const Chromosome& parent) const;
private:
const GeneGenerator* geneGenerator_;
MutationType mutationType_;
CrossoverType crossoverType_;
int nMutatedGene_;
int maxNMutatedGene_;
};
功能:
ChromosomePtr GeneticOperator::mutation(const Chromosome &parent) const
{
if (parent.getSize() < maxNMutatedGene_)
{
throw "Za malo genow w chromosomie";
}
this->random();
switch(mutationType_)
{
case FUNCTION_MUTATION:
return functionMutation(parent);
case ARGUMENTS_MUTATION:
return argumentsMutation(parent);
case WORSTGENES_MUTATION:
//not implemented yet
break;
default:
throw "Bad enum type";
break;
}
return nullptr;
}
ChromosomePtr GeneticOperator::functionMutation(const Chromosome &parent) const
{
ChromosomePtr child = parent.copy();
for(int i = 0; i < nMutatedGene_; i++)
{
GenePtr newGene = nullptr;
int geneNumber = rand() % (parent.getSize() - 1);
switch(parent.getGene(geneNumber)->getType())
{
case Gene::TERMINAL_GENE:
i--;
break;
case Gene::FUNCTION_GENE:
int nArguments = parent.getGene(geneNumber)->getNArguments();
GenePtr randomGene = move(geneGenerator_->getRandomFunctionGene(nArguments));
for(int k = 0; k < nArguments; k++)
{
randomGene->addChild(parent.getGene(geneNumber)->getChild(k));
}
break;
}
}
return child;
}
ChromosomePtr GeneticOperator::argumentsMutation(const Chromosome& parent) const
{
ChromosomePtr child = parent.copy();
for(int i = 0; i < nMutatedGene_; i++)
{
GenePtr newGene = nullptr;
int geneNumber = rand() % (parent.getSize() - 1);
switch(parent.getGene(geneNumber)->getType())
{
case Gene::TERMINAL_GENE:
i--;
break;
case Gene::FUNCTION_GENE:
GenePtr randomGene = move(parent.getGene(geneNumber)->clone());
int nArguments = parent.getGene(geneNumber)->getNArguments();
for(int k = 0; k < nArguments; k++)
{
int childGeneNumber = rand() % geneNumber;
randomGene->setChild(childGeneNumber, k);
}
break;
}
}
return child;
}
functionMutation()
和argumentsMutation()
看起来像复制粘贴编程。我该如何避免呢?我试图在此函数中仅返回
GenePtr
,但是方法mutation()
不清楚。您有什么建议?
最佳答案
复制粘贴的方法实际上只是杂乱无章的代码。我消除重复的解决方案是添加一个功能,以便从亲本基因中获得随机功能基因。这也将阐明职能的目的。
GenePtr GeneticOperator::getRandomFuncGene(const Chromosome &parent) const
{
while(true)
{
int geneNumber = rand() % (parent.getSize() - 1);
if (parent.getGene(geneNumber)->getType())
{
return parent.getGene(geneNumber);
}
}
}
使用新方法并消除混乱之后,旧函数如下所示:
ChromosomePtr GeneticOperator::functionMutation(const Chromosome &parent) const
{
for(int i = 0; i < nMutatedGene_; i++)
{
GenePtr funcGene = getRandomFuncGene(parent);
int nArguments = funcGene->getNArguments();
GenePtr randomGene = move(geneGenerator_->getRandomFunctionGene(nArguments));
for(int k = 0; k < nArguments; k++)
{
randomGene->addChild(funcGene->getChild(k));
}
}
return parent.copy();
}
ChromosomePtr GeneticOperator::argumentsMutation(const Chromosome& parent) const
{
for(int i = 0; i < nMutatedGene_; i++)
{
GenePtr funcGene = getRandomFuncGene(parent);
GenePtr randomGene = move(funcGene->clone());
int nArguments = funcGene->getNArguments();
for(int k = 0; k < nArguments; k++)
{
int childGeneNumber = rand() % geneNumber;
randomGene->setChild(childGeneNumber, k);
}
}
return parent.copy();
}
我希望我不会误解代码,但是很难猜测有时会发生什么。
这些功能还存在其他一些问题。据我了解,返回值与该函数的实际用途不符。