• 代码 | 自适应大邻域搜索系列之(4)


    前言

    上一篇讲解了destroy和repair方法的具体实现代码,好多读者都在喊酸爽和得劲儿……今天这篇就讲点简单的,关于solution的定义和管理的代码实现,让大家回回神吧……哈哈。

    01 总体概述

    总所周知的是,每一个算法的最终目标都是求解出一个合理的满足心意的solution。因此对solution的定义和管理基本是每个算法都要涉及的。在本ALNS代码中呢,也对solution进行了一定的抽象和规范化,提供了一些标准化的接口,同样需要在具体使用中去重写这些接口。

    关于solution的处理方式总得来说也由两个模块组成:

    • 关于solution的定义:ISolution抽象类
    • 关于bestSolution的管理:IBestSolutionManager(抽象类)、SimpleBestSolutionManager(派生类)

    下面也对其一一进行讲解。

    02 ISolution抽象类

    该类只是对solution的进行一定的抽象定义,并没有具体实现各个接口,需要coder在后续的使用中重写编写这些接口。它应该具备的功能看代码就能理解了,注释也写得很详细。主要包括几个功能:获取目标值、获取目标惩罚值、解是否可行、获取每个solution独一无二的hash值等。
    具体代码也很简单:

    class ISolution
    {
    public:
    	virtual ~ISolution(){};
    	//! A getter for the value of the objective function.
    	//! 
    eturn the value of the objective function of this solution.
    	virtual double getObjectiveValue()=0;
    	//! 
    eturn a penalized version of the objective value if the solution
    	//! is infeasible.
    	virtual double getPenalizedObjectiveValue()=0;
    	//! A getter for the feasibility of the current solution.
    	//! 
    eturn true if the solution is feasible, false otherwise.
    	virtual bool isFeasible()=0;
    	//! A comparator.
    	//! 
    eturn true if this solution is "better" than the solution it is compared to.
    	virtual bool operator<(ISolution&)=0;
    	//! Compute the "distance" between solution.
    	//! This feature can be used as part of the ALNS to favor the
    	//! diversification process. If you do not plan to use this feature
    	//! just implement a method returning 0.
    	virtual int distance(ISolution&)=0;
    	//! This method create a copy of the solution.
    	virtual ISolution* getCopy()=0;
    	//! Compute a hash key of the solution.
    	virtual long long getHash()=0;
    };
    

    03 bestSolution的管理

    关于bestSolution的管理有两个类搞定,它们的关系如下:

    3.1 IBestSolutionManager

    IBestSolutionManager其实也是一个抽象类,它也只是起到提供接口的作用。其中isNewBestSolution(ISolution& sol)是判断sol是不是新的最优解。reloadBestSolution(ISolution* currSol, ALNS_Iteration_Status& status)则根据需要判断是否要将已知的最优解作为当前解。

    class IBestSolutionManager
    {
    public:
    	//! This method evaluate if a solution is a new best solution, and adds it to the
    	//! best solution pool in this case.
    	//! param sol the solution to be tested.
    	//! 
    eturn true if the solution is a new best solution, false otherwise.
    	virtual bool isNewBestSolution(ISolution& sol)=0;
    
    	//! Return a pointer to a best solution.
    	virtual std::list<ISolution*>::iterator begin()=0;
    
    	//! Return a pointer to a best solution.
    	virtual std::list<ISolution*>::iterator end()=0;
    
    	//! This function take care of reloading the best known
    	//! solution, as the current solution, if needed.
    	//! param currSol a pointer to the current solution.
    	//! param status the status of the current iteration.
    	//! 
    eturn a pointer to the current solution.
    	virtual ISolution* reloadBestSolution(ISolution* currSol, ALNS_Iteration_Status& status)=0;
    };
    

    3.2 SimpleBestSolutionManager

    SimpleBestSolutionManager是继承于IBestSolutionManager的,值得注意的是,它管理的不止是一个BestSolution,而是多个BestSolution的集合(这些BestSolution目标值相同,但是结构不同)。下面是.h文件的代码:

    class SimpleBestSolutionManager: public IBestSolutionManager {
    public:
    	SimpleBestSolutionManager(ALNS_Parameters& param);
    
    	virtual ~SimpleBestSolutionManager();
    
    	virtual bool isNewBestSolution(ISolution& sol);
    
    	//! Return a pointer to a best solution.
    	std::list<ISolution*>::iterator begin(){return bestSols.begin();};
    
    	//! Return a pointer to a best solution.
    	std::list<ISolution*>::iterator end(){return bestSols.end();};
    
    	//! This function take care of reloading the best known
    	//! solution, as the current solution, if needed.
    	//! param currSol a pointer to the current solution.
    	//! param status the status of the current iteration.
    	//! 
    eturn a pointer to the current solution.
    	virtual ISolution* reloadBestSolution(ISolution* currSol, ALNS_Iteration_Status& status);
    
    	//! Simple getter.
    	std::list<ISolution*>& getBestSols(){return bestSols;};
    private:
    	std::list<ISolution*> bestSols;
    
    	ALNS_Parameters* parameters;
    
    };
    

    再回过头来看看.cpp文件的实现代码,也很简单,讲讲两个函数的实现方式就好了。isNewBestSolution(ISolution& sol)做的可不只是简单判断这么简单:
    如果sol和最优解集合中的某个相同,那么返回false。
    如果sol的目标值>最优解集合中的解的目标值,返回false。
    如果sol的目标值<最优解集合中的某个解的目标值,那么将该最优解从集合中移除。
    最后如果没有返回false,将sol加入最优解集合。

    而reloadBestSolution(ISolution* currSol, ALNS_Iteration_Status& status)根据status的状态,返回最优解集合中最后一个解或者返回当前解。

    bool SimpleBestSolutionManager::isNewBestSolution(ISolution& sol)
    {
    	for(list<ISolution*>::iterator it = bestSols.begin(); it != bestSols.end(); it++)
    	{
    		ISolution& currentSol = *(*it);
    		if(currentSol<sol)
    		{
    			return false;
    		}
    		else if(sol<currentSol)
    		{
    			delete *it;
    			it = bestSols.erase(it);
    			if(it == bestSols.end())
    			{
    				break;
    			}
    		}
    		else if(currentSol.getHash() == sol.getHash())
    		{
    			return false;
    		}
    	}
    	ISolution* copy = sol.getCopy();
    	bestSols.push_back(copy);
    	return true;
    }
    
    ISolution* SimpleBestSolutionManager::reloadBestSolution(ISolution* currSol, ALNS_Iteration_Status& status)
    {
    	if(status.getNbIterationWithoutImprovementSinceLastReload() > 0 &&
    	   ((status.getNbIterationWithoutImprovementSinceLastReload() % parameters->getReloadFrequency()) == 0))
    	{
    		status.setNbIterationWithoutImprovementSinceLastReload(0);
    		delete currSol;
    		return bestSols.back()->getCopy();
    	}
    	else
    	{
    		return currSol;
    	}
    }
    

    04 小结

    好了,以上就是今天的内容,是不是特别简单呢?相信在克服之前两篇文章的读者来说,后面都是一马平川、一帆风顺了。哈哈。

  • 相关阅读:
    《简养脑》读书笔记
    如何用86天考上研究生
    Improving your submission -- Kaggle Competitions
    Getting started with Kaggle -- Kaggle Competitions
    入门机器学习
    《世界因你不同》读书笔记
    [转载]Python 包构建教程
    [转载] Pytorch拓展进阶(二):Pytorch结合C++以及Cuda拓展
    集合不能存放重复元素
    在jupyter notebook中绘制KITTI三维散点图
  • 原文地址:https://www.cnblogs.com/dengfaheng/p/10585139.html
Copyright © 2020-2023  润新知