1.前言

整个比赛历时70多天,是一场持久战,期间看了不少资料,实现了一些算法,现总结如下。

初赛的思路是启发式+费用流,启发式实现了遗传算法、模拟退火,费用流实现了连续最短路(spfa),zkw/primal-dual,网络单纯形(决赛写的),这些算法其实都不是自己手写的,是从网上的模板改造过来的。

初赛规模用退火还可以,到了复赛,服务器分等级,规模变得更大了,费用流的次数完全不能满足退火的需求,于是放弃找全局最优,直接贪心找局部最优。

决赛题目大变化,可怜我花了一周的时间整了个网络单纯形,后来才发现根本没有用上。决赛主要是想策略,对费用流的速度要求不是那么高。

2.小费用最大流问题求解算法

先说一下小费用最大流问题求解算法有哪些,从《网络优化》(谢金星 et al., 2009)一书中可以看到,求解该问题有如下这些方法:

  • 消圈算法
  • 最小费用路算法(连续最短路)
  • 原始-对偶算法
  • 瑕疵算法
  • 松弛算法
  • 网络单纯形算法

还有一个zkw算法不在这本书中,其实zkw用于比赛,效率非常高。

2.1最小费用路算法(连续最短路)

这算法的实现来自于《算法竞赛入门经典(第2版)(算法艺术与信息学竞赛)》(刘汝佳,2014)一书,当时正好在看这本书,就直接用这里的算法了,包括图的存储结构也用的这本书里面的,应该叫做前向星。

2.2 zkw/primal-dual

问题规模变大后,前面的算法速度已经跟不上了,就得去找新的算法,一开始就听说松弛和网络单纯形很快,但是觉得它们实现起来很麻烦,想找一个简单一点的,就发现了zkw(从入门到精通: 最小费用流的“zkw算法”),连续最短路是一条路一条路的增广,而zkw是多路增广,快了不少。

2.3网络单纯形算法

进决赛后,题目还没有定下来的时候,我们觉得应该看看网络单纯形,要是规模继续变大,zkw可能也跟不上,搜了搜网络单纯形的开源库,找到3个,分别测试了一下,时间上,如果zkw要30ms,网络单纯形可以10ms,还是有一定的价值实现。网络单纯形的大概原理可以看《网络优化》(谢金星 et al., 2009)。

不过要注意网络单纯形并不等同于线性规则里面的单纯形,可以看看《运筹学(第三版),清华大学出版社》。

我搜到的网络单纯形的3个开源库分别是:

  • MCFClass project (C++)
  • LEMON (C++)
  • NetworkX (python)

NetworkX可能是因为python的原因,速度非常慢,看它的源码和LEMON很像。

2.3.1 MCFClass project

进去需要翻墙,下载下来后在说明文档中有“How to Use It”,可以参照进行使用,注意需要将图存为它规定的格式,这里提供2个测试例子。一个是800点的图,服务器位置使用最优解的位置。一个是第三批练习用例里面的case0,这个例子有1200个点,5267条边,480个消费点,服务器位置是跑退火得到的位置。设置一个超级源点,连接所有服务器,设置一个超级源点,连接所有消费点。两个case可以在这里下载,数据格式在文档中可以查看。

所以,如果想要快速上手使用它,可按照如下步骤进行(以win, vs2013为例):

1.下载源码,下载我提供的case

2.新建一个vs工程,创建h文件和cpp文件,把下载下来的文件内容复制过去,或者直接替换(用c文件好像会出问题,不行就用cpp)

3.编译(release)

4.把下载的case放在release文件夹中,在当前文件夹中打开命令行,运行:

***.exe case**.txt

就可以看到结果了,结果会显示时间和最小费用。

2.3.2 LEMON

LEMON里面的最小费用流算法由(Király and Kovács, 2012)完成,可以参考他们的文章:Király, Z. and Kovács, P., 2012. Efficient implementations of minimum-cost flow algorithms. Computer Science.文章对他们的网络单纯形算法进行了介绍。

在windows下的安装方法,不出意外的话,按照里面提供的方法可以产生一个vs工程。LEMON同样需要使用它指定的数据格式,可以参照文档说明进行生成,这里提供一个我生成的case是1200点的图,服务器位置使用退火获得的(随意跑的?还是哪来的?忘了),设置一个超级源点,连接所有服务器,设置一个超级源点,连接所有消费点,case可以在这里下载。

所以,如果想要快速上手使用它,可按照如下步骤进行(以win, vs2013为例):

1.下载源码,在windows下安装(方法)

2.下载我提供的case(可以在这里下载),下载后放在...\lemon-1.3.1\build\demo下。

3.为了测试方便,我直接把lgf_demo.cc修改了,修改后的源码在这里,下载下来放到lgf_demo.cc中。

3.把lgf_demo设为启动项,在release模式下运行,就可以看到结果了。

注意:

  • LEMON实现了好几种搜索入弧的方式,默认的是BLOCK_SEARCH,说这个的效率高且稳定、实现起来比较简单,ALTERING_LIST可能效率高但不稳定,实现要复杂一些。
  • 存储边的时候采用了乱序存储,这样可以提高效率,我没有搞明白为什么,如果我不采样乱序存储速度确实会变慢。这里说的乱序就直接按照数据文件读取的时候边的顺序是1,2,3,4,5,6,7,8,9,10.那么存的时候就按一定的间隔存,比如间隔为2,那么存起来就是这样的:1,3,5,7,9,2,4,6,8,10.
  • 网络单纯形居然也有参数要调整,比如BLOCK_SEARCH的块大小,如果为1就退化成了FIRST_ELIGIBLE,如果太大或者直接是边数,那么就成了BEST_ELIGIBLE.

2.3.3 NetworkX

我感觉NetworkX里面的网络单纯形像是从LEMON里面提取出来后简化过的,测试发现花的时间很长,可能是因为python的缘故。

同样,如果想要快速上手使用它,可按照如下步骤进行(以win, python3为例,我用的anaconda):

1.按照文档说明进行安装

2.它也需要一定的数据格式,这里提供一个可以用的case(下载),是第三批高级case0,1200个点。

3.下载测试脚本

4.运行就可以看到结果

补充:

netcan指出还有ξ松弛,拍卖算法里的,不用退流,但无解的情况特别慢,提供流量和需求流量不一样得到的解也不对。

github:https://github.com/hubenjm/mincostflow

最小费用流算法不完全指南-2017华为软件精英挑战赛相关推荐

  1. 2017华为软件精英挑战赛参赛过程回顾与心得

    参赛队名:武长区 枪林弹雨 2017年4月26日,一波三折的复赛终于结束了,我们队最终没能进入决赛.虽然在意料之中,不过还是有些小失望.已经为这个比赛忙了一个月,突然之间不知道干什么好了,干脆写一写自 ...

  2. 2017华为软件精英挑战赛小结

    // 2017华为软件精英挑战赛小结 // 不说废话,直接上货!希望对目前的参赛者,或日后学习的人,提供一些参考和思路. #include <赛题说明.pdf>    //  见附录文件 ...

  3. 2017华为软件精英挑战赛决赛思路分享

    大家好,我是月光. 历时一个多月的软挑终于落下了帷幕,收获了一个还不错的名次.这个不错是对我们自己而言的,可能对于观众来说,记住的永远只会是第一名,而其他角色终会随比赛过去而被遗忘.其实本身我希望过的 ...

  4. 2017华为软件精英挑战赛解分析

    后经在复赛赛题上测试,效果并不好,只适合部分数据集,并且没有理论支持,放出来只为启发-- 以下方法初中级样例1s以内,高级样例10s内出最优解-- 不随机,无启发式,走优化的方法.采用反馈-迭代的方法 ...

  5. 2017华为软件精英挑战赛总结

    1.题目 本次赛题是一个视频服务器的CDN规划问题 赛题包_百度网盘 2.解题思 2.1 思路一 整数规划 主要是要把模型建出来 包含了 0-1变量->是否布置服务器 边变量-> 表示该边 ...

  6. 2017华为软件精英挑战赛系列一

    看到题目时,首先就是读懂它.以下就是我对题目的一些分析. 需要解决的问题 在满足所有的住户小区视频播放需求的基本前提下,如何选择视频内容存储服务器放置位置,使得成本最小. 本次赛题通用性描述 网络结构 ...

  7. 2017华为软件精英挑战赛txt数据的读取(MATLAB实现)

    path = 'case_example\case0.txt';fid = fopen(path,'r');caseData.nodEdgUserCount = zeros(1,3);b = fget ...

  8. 2017年华为软件精英挑战赛初赛解题思路

    2017年华为软件精英挑战赛初赛解题思路 题目链接:http://codecraft.huawei.com/  常规解题思路:网络流(最小费用最大流)+ 启发式搜索算法 + 算法性能优化 1. 最大流 ...

  9. 2018华为软件精英挑战赛-模拟退火算法

    2018年的华为软件精英挑战赛题目简介:给出华为云虚拟机过去的租借数量历史数据,用以训练模型并预测下一个时间段里的虚拟机租借数量,然后把这些预测得到的虚拟机装填进一定规格的物理机中,即分为预测和装填两 ...

最新文章

  1. input placeholder样式
  2. cmd系统命令不识别
  3. 让iframe可编辑
  4. HALCON 1D Measure 算子初识
  5. libcurl 多线程使用注意事项 - Balder~专栏 - 博客频道 - CSDN.NET
  6. go实现区块链[3]-遍历区块链与数据库持久化
  7. java里面的string类型,java中的String类型(不知道理解的好不,请教大神)
  8. Linux 远程和本地的一些解决方案
  9. 如何移除照片中不需要的东西?这三款Mac App软件不会让你失望!
  10. 聊聊V8引擎的垃圾回收
  11. 革新科技CIDE-EDA:实验1 3-8译码器
  12. 轮询小案例-扫码登录
  13. 【转】货币的未来取决于打破关于货币历史的虚构谎言
  14. 职位介绍之硬件工程师(提升宝典)
  15. 原生html单页应用,web单页应用
  16. 【老九】【C语言】CodeBlocks安装文档
  17. 小学计算机四年级教学计划,小学信息技术四年级第二学期教学计划
  18. 进程上下文与线程上下文
  19. android 游戏 育碧,育碧《勇敢的心:世界大战》登陆Android平台
  20. 突然被录取?多所院校发布研究生补录通知!

热门文章

  1. 编译原理 子集构造法实现
  2. Android--- Drawer and Tab Navigation with ViewPager
  3. HEXOFontmin
  4. 【考研英语】词汇积累(详细全面,2023最新版)
  5. 黑科技计算机玩游戏,别再嘲笑苹果电脑玩不了游戏!有了这项黑科技后比台式机还猛...
  6. Android实现应用数字角标
  7. matlab实现三分之一倍频程,三分之一倍频程程序
  8. 对List集合属性进行模糊查找
  9. 给定一个字符串s,找出s中最长的回文子串,你可以假设s的最大长度是1000。
  10. 自动生成用于测试和评估自动驾驶汽车的各种挑战性场景