前言
上一篇文章中我们具体解剖了ALNS类的具体代码实现过程,不过也留下了很多大坑。接下来的文章基本都是“填坑”了,把各个模块一一展现解析给大家。不过碍于文章篇幅等原因呢,也不会每一行代码都进行讲解,那些简单的代码就跳过了,相信大家也能一眼就看懂。好了,废话不多说,开始干活吧。
01 照旧总体概述
前面我们提到,ALNS中的重中之重就是Destroy和Repair方法了,在整一个ALNS框架中呢,涉及这俩货的有Destroy和Repair方法的具体实现、Destroy和Repair方法管理(包括各个Destroy和Repair方法权重分配、成绩打分、按权重选择哪个Destroy和Repair方法等操作)。所以在这次的ALNS代码中呢,这俩货的代码实现呢也分为两个模块:
- Destroy和Repair方法具体实现模块
- Destroy和Repair方法管理模块
下面我们将对其进行一一讲解,不知道大家小板凳准备好了没有。
02 Destroy和Repair方法具体实现
关于Destroy和Repair方法,由三个类组成,分别是AOperator、ADestroyOperator、ARepairOperator。它们之间的继承派生关系如下:
下面对其一一讲解。
2.1 AOperator
这是一个基础父类,它抽象了Destroy和Repair方法共有的一些方法和特征(成绩、权重、名称等等),然后Destroy和Repair方法再各自继承于它,实现自己的功能模块。成员变量已经注释清楚了,关于protected的一个成员noise噪声模式会在后面讲到。其他的方法也很简单就不做多解释了。
class AOperator
{
private:
//! Total number of calls during the process.
size_t totalNumberOfCalls;
//! Number of calls since the last evaluation.
size_t nbCallsSinceLastEval;
//! score of the operator.
double score;
//! weight of the operator.
double weight;
//! designation of the operator.
std::string operatorName;
protected:
//! Indicate if the operator is used in noise mode or not.
bool noise;
public:
//! Constructor.
AOperator(std::string name){
operatorName = name;
init();
}
//! Destructor.
virtual ~AOperator(){};
//! Initialize the values of the numbers of calls.
void init()
{
totalNumberOfCalls = 0;
nbCallsSinceLastEval = 0;
score = 0;
weight = 1;
}
//! reset the number of calls since last eval.
void resetNumberOfCalls()
{
nbCallsSinceLastEval = 0;
}
//! Simple getter.
//! \return the total number of calls to the operator since
//! the beginning of the optimization process.
size_t getTotalNumberOfCalls(){return totalNumberOfCalls;};
//! Simple getter.
//! \return the number of calls to this operator since the last
//! evaluation.
size_t getNumberOfCallsSinceLastEvaluation(){return nbCallsSinceLastEval;};
void increaseNumberOfCalls()
{
totalNumberOfCalls++;
nbCallsSinceLastEval++;
}
//! Simple getter.
double getScore() const
{
return score;
}
//! Simple getter.
double getWeight() const
{
return weight;
}
//! resetter.
void resetScore()
{
this->score = 0;
}
//! Simple setter.
void setScore(double s)
{
this->score = s;