代码 | 自适应大邻域搜索系列之(7) - 局部搜索LocalSearch的代码解析
前言
好了小伙伴们我们又见面了,咳咳没错还是我。不知道你萌接连被这么多篇代码文章刷屏是什么感受,不过,酸爽归酸爽。今天咱们依然讲代码哈~不过今天讲的依然很简单,关于局部搜索LocalSearch的代码。
01 总体概述
其实,LocalSearch在本算法中不是必须使用的,用户可以根据需要来选择是否启用这个功能。但是一般情况下,有了LocalSearch以后效果会好一点。而且本着服务读者的态度(我可以不用,但是小编你不能不讲),就讲讲这个模块吧。和之前讲的几个模块差不多,具体代码也是分成两个部分进行实现的:
- LocalSearch的定义
- LocalSearch的管理
LocalSearch的定义用了一个很简单的抽象类ILocalSearch用来提供接口的、而LocalSearch的管理用了ILocalSearchManager、SimpleLocalSearchManager两个类,其中ILocalSearchManager也是抽象类,而SimpleLocalSearchManager则是继承于ILocalSearchManager并实现了相应的接口。下面对他们进行一一讲解。
02 ILocalSearch
其实这个类只提供了两个纯虚函数作为接口,也是简单得不能再简单了,performLocalSearch用以执行一次LocalSearch操作,getName返回该LocalSearch的名字。
class ILocalSearch
{
public:
//! Perform a local search on the solution.
//! \return true if the solution is improved.
virtual bool performLocalSearch(ISolution& sol)=0;
//! \return the name of the local search operator.
virtual std::string getName()=0;
};
03 ILocalSearchManager
这个抽象类也非常简单,只有两个接口。useLocalSearch用以判断是否要使用LocalSearch,而startSignal开始信号,在启动整个算法的时候起到协调作用。
class ILocalSearchManager
{
public:
//! \param sol the solution to be improved.
//! \param status the status of the alns iteration.
//! \return true if the solution has been improved.
virtual bool useLocalSearch(ISolution& sol, ALNS_Iteration_Status& status)=0;
//! Indicate that the optimization process starts.
virtual void startSignal()=0;
};
04 SimpleLocalSearchManager
SimpleLocalSearchManager对LocalSearch进行了一定的扩充,加入了addLocalSearchOperator的操作,用以添加LocalSearch。值得注意的是,该LocalSearchManager管理的可以是多个LocalSearch。
class SimpleLocalSearchManager: public ILocalSearchManager {
public:
SimpleLocalSearchManager(ALNS_Parameters& parameters){param = ¶meters;};
virtual ~SimpleLocalSearchManager(){};
//! \param sol the solution to be improved.
//! \param status the status of the alns iteration.
//! \return true if the solution has been improved.
virtual bool useLocalSearch(ISolution& sol, ALNS_Iteration_Status& status);
//! Add a local search operator to the manager.
void addLocalSearchOperator(ILocalSearch& ls);
virtual void startSignal(){};
private:
//! A vector containing the local search operators managed by the current instance.
std::vector<ILocalSearch*> localSearchOperators;
//! Parameters of the ALNS.
ALNS_Parameters* param;
};
useLocalSearch和addLocalSearchOperator具体实现代码如下,相信对迭代搜索了解的同学,对下面的过程那是熟悉得不能再熟悉了,特别是improvement 变量的复位操作(如果有改进,那么接着搜索下去,直到最大迭代次数为止,如果没有改进就不搜索了。)addLocalSearchOperator就不需要讲解了吧~
bool SimpleLocalSearchManager::useLocalSearch(ISolution& sol, ALNS_Iteration_Status& status)
{
if(status.getNewBestSolution()!=ALNS_Iteration_Status::TRUE
|| status.getAcceptedAsCurrentSolution()!=ALNS_Iteration_Status::UNKNOWN)
{
return false;
}
else
{
status.setLocalSearchUsed(ALNS_Iteration_Status::TRUE);
bool improvement;
do
{
improvement = false;
for(size_t i = 0; i < localSearchOperators.size(); i++)
{
improvement = localSearchOperators[i]->performLocalSearch(sol)||improvement;
}
}while(improvement);
if(improvement)
{
status.setImproveByLocalSearch(ALNS_Iteration_Status::TRUE);
return true;
}
else
{
status.setImproveByLocalSearch(ALNS_Iteration_Status::FALSE);
return false;
}
}
}
void SimpleLocalSearchManager::addLocalSearchOperator(ILocalSearch& ls)
{
//TODO find out why the set.find() == set.end() does not work.
bool ok = true;
for(size_t i=0; i< param->getForbidenLsOperators().size() && ok; i++)
{
if(param->getForbidenLsOperators()[i] == ls.getName())
{
std::cout << "NO " << ls.getName() << std::endl;
ok = false;
}
}
if(ok)
{
localSearchOperators.push_back(&ls);
}
}
05 小结
差不多到此整个ALNS框架已经讲得差不多了,相信大家在看了这么多代码以后,心里早已经有了一个数了。下面几篇推文将为大家展现一个实例,怎么在该框架的基础上定制自己的代码求解相应的问题。为了演示,还是给大家实例一个TSP问题的求解过程哈。谢谢!
最后做个小小说明:整个系列所有的代码在 代码 | 自适应大邻域搜索系列之(1) - 使用ALNS代码框架求解TSP问题 这篇文章中都能找到代码文件。
代码 | 自适应大邻域搜索系列之(7) - 局部搜索LocalSearch的代码解析的更多相关文章
- 代码 | 自适应大邻域搜索系列之(2) - ALNS算法主逻辑结构解析
00 前言 在上一篇推文中,教大家利用了ALNS的lib库求解了一个TSP问题作为实例.不知道你萌把代码跑起来了没有.那么,今天咱们再接再厉.跑完代码以后,小编再给大家深入讲解具体的代码内容.大家快去 ...
- 代码 | 自适应大邻域搜索系列之(5) - ALNS_Iteration_Status和ALNS_Parameters的代码解析
前言 上一篇推文说了,后面的代码难度直线下降,各位小伙伴可以放去n的100次方心了.今天讲讲一些细枝末节,就是前面一直有提到的参数和一些状态的记录代码.这个简单啦,小编也不作过多解释了.大家直接看代码 ...
- 代码 | 自适应大邻域搜索系列之(3) - Destroy和Repair方法代码实现解析
前言 上一篇文章中我们具体解剖了ALNS类的具体代码实现过程,不过也留下了很多大坑.接下来的文章基本都是"填坑"了,把各个模块一一展现解析给大家.不过碍于文章篇幅等原因呢,也不会每 ...
- 代码 | 自适应大邻域搜索系列之(4) - Solution定义和管理的代码实现解析
前言 上一篇讲解了destroy和repair方法的具体实现代码,好多读者都在喊酸爽和得劲儿--今天这篇就讲点简单的,关于solution的定义和管理的代码实现,让大家回回神吧--哈哈. 01 总体概 ...
- 代码 | 自适应大邻域搜索系列之(6) - 判断接受准则SimulatedAnnealing的代码解析
前言 前面三篇文章对大家来说应该很简单吧?不过轻松了这么久,今天再来看点刺激的.关于判断接受准则的代码.其实,判断接受准则有很多种,效果也因代码而异.今天介绍的是模拟退火的判断接受准则.那么,相关的原 ...
- ElasticSearch 2 (15) - 深入搜索系列之多字段搜索
ElasticSearch 2 (15) - 深入搜索系列之多字段搜索 摘要 查询很少是简单的一句话匹配(one-clause match)查询.很多时候,我们需要用相同或不同的字符串查询1个或多个字 ...
- ElasticSearch 2 (13) - 深入搜索系列之结构化搜索
ElasticSearch 2 (13) - 深入搜索系列之结构化搜索 摘要 结构化查询指的是查询那些具有内在结构的数据,比如日期.时间.数字都是结构化的.它们都有精确的格式,我们可以对这些数据进行逻 ...
- 自适应大邻域搜索代码系列之(1) - 使用ALNS代码框架求解TSP问题
前言 上次出了邻域搜索的各种概念科普,尤其是LNS和ALNS的具体过程更是描述得一清二楚.不知道你萌都懂了吗?小编相信大家早就get到啦.不过有个别不愿意透露姓名的热心网友表示上次没有代码,遂不过瘾啊 ...
- 干货 | 自适应大邻域搜索(Adaptive Large Neighborhood Search)入门到精通超详细解析-概念篇
01 首先来区分几个概念 关于neighborhood serach,这里有好多种衍生和变种出来的胡里花俏的算法.大家在上网搜索的过程中可能看到什么Large Neighborhood Serach, ...
随机推荐
- gopacket 在 windows 上面遇到的问题
前阵子有个需求是使用 golang 抓包改包,我用到了 gopacket 这个包,但是出了一些小问题. 我按照网上的方法进行使用 OpenLive 抓包,发现并不行,报错 error open ada ...
- U盘安装Ubuntu14.04&配置远程win10远程连接
1.U盘安装Ubuntu:https://blog.csdn.net/baigoocn/article/details/26561473 2.win10远程访问Ubuntu系统:https://www ...
- element 右键菜单
右键菜单 这是一个右键菜单的组件 <template> <div id="dropMenu" :style="style" style=&qu ...
- vue-resource发送请求
<!DOCTYPE html> <html> <head> <title>vue-resource</title> <meta cha ...
- 从SAP社区上的一篇博客开始,聊聊SAP产品命名背后的那份情怀
最近Jerry在SAP社区上看到一篇博客:It's Steampunk now. 博客原文:https://blogs.sap.com/2019/08/20/its-steampunk-now/ 什么 ...
- c# 定义和调用索引器
- excel转sql代码
1. 首先一个标准的excel表格,如下: 2. 在同一行,后面一个单元格,英文输入法状态下输入以下:=CONCATENATE() =CONCATENATE("insert into tab ...
- 每日一题-——LeetCode(807)保持城市天际线
题目描述: 在二维数组grid中,grid[i][j]代表位于某处的建筑物的高度. 我们被允许增加任何数量(不同建筑物的数量可能不同)的建筑物的高度. 高度 0 也被认为是建筑物.最后,从新数组的所有 ...
- Kubernetes日志采集
Kubernetes日志打印方式 标准输出 docker标准输出日志stdout和stderr,使用docker logs或者kubectl logs查看最新的日志(tail). 如果想看到更多的日志 ...
- 软件测试_Loadrunner_性能测试_脚本录制_录制多server请求脚本
之前我们写过使用Loadrunner录制APP脚本的基本流程:软件测试_Loadrunner_APP测试_性能测试_脚本录制_基本操作流程,但是只能用于请求单一服务器端口适用 这次主要是写的多serv ...