如何实现一个快速高效的启发式算法?

本文探讨如何实现高效的启发式算法,强调在编写代码前进行充分思考,明确算法架构和解的表示。通过优化邻居解的计算方法,减少冗余,将时间复杂度从O(n)降至O(1),以提升算法性能。文章通过VRP问题实例,详细解释了如何消除计算冗余,降低运行时间,适用于大规模优化问题。
摘要由CSDN通过智能技术生成

一、前言

小伙伴们好,说起来已经好久好久好久没见了呢!之前一直忙着做其他事情去了(泛指学习一类),公众号已经落下好久好久了。今天来写点好玩的东西。

说起来,小编似乎就是做启发式算法起家的。当时记得老师是这么跟我说的,启发式算法这东西很简单,你不需要基础,有高中基础就够了(其实他想说的是初中……)。后来小编一直在学这个东西,做了三四年了,用启发式算法做过的大大小小的project已经不记得有多少了,所以还算得上有一点点经验。

因此今天就来写写,怎样实现一个比较高效的启发式算法吧~

二、何为高效?

说到这个词,相信大家一定不陌生。高效意思就是达到相同效果或者更好的效果时,使用的时间更短,所需要的资源更少。就拿小编来说,由于小编特别笨,学一样东西需要花一周的时间,而群里的小伙伴只需要一天的时间就能学会。那么这位小伙伴是要比我高效的。

同样的对于一个启发式算法而言,不同人实现出来,即使是使用同一编程平台达到同样的效果,运行时间也会千差万别,相差几倍甚至几十倍。这样说出来大家可能还没啥感觉,那么放一下我们之前做过的一些数值实验大家直观感受下吧~

这是某个Java实现的求解VRP类问题的算法代码,两个算法都达到了同样的效果,只不过绿色曲线对应的算法在计算过程中去除了相关冗余,可以看到运行时间直线下降。根据我们的统计,消除冗余计算后可使计算时间降低约83%,对于工业化生产而言,提升哪怕一个小数点都能带来巨大的收益,何止是83个百分点呢。怎么说呢,这简直是A small step forward,one step civiliazation

三、放码过来?

不要一上来就是写代码,不加思考就上手写代码,你只会搓一坨屎山出来,自己坑害自己。开始写代码之前一定要构思好算法的整体架构,解的表示方式,如何快速得到邻居解等。建议是思考的时间一定要占总时间的一半以上。

其实思路清晰写代码是非常快的,比如每次在写代码的时候我都会先写好注释,比如:

//1. 先获取所有可行点的信息

//2. 对点按照成本进行排序

//3. 贪心将各个点插入到解中

然后写的时候我只需要按照这个思路往下走就可以了,这就跟你写小学生作文一样,起床刷牙到公园看鲸鱼,一定要思路清晰。

四、邻居解如何计算?

到了今天的核心问题,我们都知道,邻域搜索过程中,邻居解与当前解相比往往只有细微的变化,因此迭代过程中绝大部分变量不需要重新计算,消除了冗余计算,可大大提高邻域搜索效率,降低运行时间。听不懂吗?没关系,我举例子,慢慢给你讲解。

下面是一个VRP问题(没有TW哦)的一个初始解 S 1 S_1 S1:

为了方便表示我们用 C ( x ) C(x) C(x)表示x的cost吧,其中x可以为一个解、解中的一条路径。 c i j c_{ij} cij表示边<i,j>的距离。对于初始解,计算它的cost,只能是从头到尾挨个遍历一下了。因此:

C ( S 1 ) = C ( r 1 ) + C ( r 2 ) + C ( r 3 ) + C ( r 4 ) C(S_1) = C(r_1) + C(r_2) + C(r_3) + C(r_4) C(S1)=C(r1)+C(r2)+C(r3)+C(r4)

其中各条路径的cost又可以表示为:

C ( r 1 ) = c 0 , 6 + c 6 , 4 + . . . + c 8 , 0 . . . . . . C ( r 4 ) = c 0 , 14 + c 14 , 18 + . . . + c 25 , 0 C(r_1) = c_{0,6} +c_{6,4}+ ... + c_{8,0} \\ ......\\ C(r_4) = c_{0,14} +c_{14,18}+ ... + c_{25,0} C(r1)=c0,6+c6,4+...+c8,0......C(r4)=c0,14+c14,18+...+c25,0

因此最后解的计算方式为:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值