我有一个名为 GeneticOperator
的类,它负责遗传程序中的变异和交叉运算符。我对不同的突变有不同的函数,对突变有一个公共(public)函数,其中我有类型的 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();
}
我希望我没有误解代码,但有时很难猜出发生了什么。
这些功能还存在一些其他问题。据我所知,返回值与函数的实际目的不符。
关于c++ - 有时允许复制粘贴编程吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35808420/