C++ 有时允许复制粘贴编程吗?
我有一个名为C++ 有时允许复制粘贴编程吗?,c++,coding-style,C++,Coding Style,我有一个名为geneticcoperator的类,负责遗传程序中的变异和交叉算子。对于不同的变异我有不同的函数,对于变异我有一个公共函数,其中对于类型我有switch语句。在函数中,random()I列出染色体中要突变的基因的突变类型和数量 class GeneticOperator { public: enum MutationType { FUNCTION_MUTATION, ARGUMENTS_MUTATION, WORSTG
geneticcoperator
的类,负责遗传程序中的变异和交叉算子。对于不同的变异我有不同的函数,对于变异我有一个公共函数,其中对于类型我有switch语句。在函数中,random()
I列出染色体中要突变的基因的突变类型和数量
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;
}
ChromosomePtr GeneticOperator::突变(常量染色体和父染色体)常量
{
if(parent.getSize()随机();
开关(突变型)
{
病例功能变异:
返回函数(父级);
病例参数和突变:
返回参数(父级);
病例WORSTGENES_突变:
//尚未实施
打破
违约:
抛出“坏枚举类型”;
打破
}
返回空ptr;
}
染色体PTR GeneticOperator::函数突变(常量染色体和父染色体)常量
{
ChromosomePtr child=parent.copy();
对于(int i=0;igetType()
{
病例基因::末端基因:
我--;
打破
病例基因::功能基因:
int nArguments=parent.getGene(geneNumber)->getNArguments();
GenePtr randomGene=move(geneGenerator->getRandomFunctionGene(nArguments));
for(int k=0;kaddChild(parent.getGene(geneNumber)->getChild(k));
}
打破
}
}
返回儿童;
}
染色体PTR GeneticOperator::ArgumentsStation(常量染色体和父染色体)常量
{
ChromosomePtr child=parent.copy();
对于(int i=0;igetType()
{
病例基因::末端基因:
我--;
打破
病例基因::功能基因:
GenePtr randomGene=move(parent.getGene(geneNumber)->clone());
int nArguments=parent.getGene(geneNumber)->getNArguments();
for(int k=0;ksetChild(childGeneNumber,k);
}
打破
}
}
返回儿童;
}
functionMutation()
和argumentsStation()
看起来像复制粘贴编程
我怎样才能避免呢?我试图在这个函数中只返回GenePtr
,但是方法mutation()
不清楚
你有什么建议?至于你的问题的标题 有时允许复制粘贴编程吗? 不,是骨头上的错音1(嘿,这首歌押韵) 我怎样才能避免呢 避免复制/粘贴实现的通常方法是提供模板函数或类,这些模板函数或类会排除类型不特定的代码 特定类型的代码可以重构为特定类型的函数调用
1) 静态代码分析工具甚至做出了大量的努力来检测复制/复制修改的代码,并警告复制过程中可能出现的错误。
用最少的误报来检测这一点的真正好的工具是相当昂贵的,所以不要这样做
ChromosomePtr GeneticOperator::突变(常量染色体和父染色体,字符串类型)常量
{
ChromosomePtr child=parent.copy();
对于(int i=0;igetType()
{
病例基因::末端基因:
我--;
打破
病例基因::功能基因:
如果(类型=“函数”){
M(家长);
}else if(类型==“参数”){
M(父母);
}
打破
}
}
返回儿童;
}
复制粘贴的方法实际上只是被不必要的代码弄得乱七八糟。我消除重复的方法是添加一个函数,从父基因中获得一个随机函数基因。这也将澄清职能的目的
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();
}
ChromosomePtr GeneticOperator::functionMutation(常量染色体和父染色体)常量
{
对于(int i=0;igetNArguments();
GenePtr randomGene=move(geneGenerator->getRandomFunctionGene(nArguments));
for(int k=0;kaddChild(funcGene->getChild(k));
}
}
返回parent.copy();
}
染色体PTR GeneticOperator::ArgumentsStation(常量染色体和父染色体)常量
{
对于(int i=0;iclone());
int nArguments=funcGene->getNArguments();
for(int k=0;ksetChild(childGeneNumber,k);
}
}
返回parent.copy();
}
我希望我没有误解代码,但有时很难猜出发生了什么
这些函数还存在一些其他问题。据我所知,返回值与函数的实际用途不符。如果它们执行的是完全相同的操作,请使用一个函数调用另一个函数。如果他们有一些共同的部分,把共同的部分放在
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();
}