Santa's Workshop Tour 2019 圣诞老人的复仇 比赛回顾总结 MIP+邻域搜索+python

1 比赛概述

这是一个非常非常有意思的比赛,是一个最优化问题,可以学到一些规划算法!下面我们进入正题:


圣诞老人开放了他的工作室,有5000个家庭可以在100天内(每个家庭有不同的人数),选择一天去参观他的工作室。每个家庭都递给圣诞老人一个喜好表,告诉圣诞老人他们第一想要在哪一天去参观,第二想要在哪一天参观……因为每一天能参观的人数有上限,所以并不是每一个家庭都可以在最想要的那一天去参观。

我们要注意的是:

  • 每天能参观的人数应为125~300之间
  • 圣诞老人需要补偿那些不能按照第一志愿去参观的家庭:
    在这里插入图片描述
  • 圣诞老人不仅仅需要补偿那些家庭,还需要花钱打扫他的工作室:
    在这里插入图片描述如何安排着5000个家庭,使得圣诞老人的花费最少呢?

2 思想分享

我们先进性尝试了随机搜索stochastic search,然后使用了最大流算法max flow algorithm:最好的随机算法的结果和最大流算法的结果 仅仅有六个家庭分配的日期不同。


Family: 261 83 - 67
Family: 779 67 - 7
Family: 798 35 - 45
Family: 2926 1 - 35
Family: 3215 25 - 83
Family: 4716 45 - 1
Same: 4994
261号家庭从83日去参观变成了67日去。这里面67日是距离圣诞节前的第67天,下面皆是如此
然后我们发现了两个循环:
35-45-1-35
25-83-67-7
意思是35天去的一个家庭45天去,45天去的家庭1天去,1天取得家庭35天去这样的循环

2.1 数据分析

就算这是一个规划问题,而不是一个大数据预测的特征工程,作者也进行了数据分析!
作者分析了根据最大流算法的结果,然后发现了一下特征:

  1. 绝大多数家庭都可以在top6的偏好中选到日期(就是我们之前已经讲了,每个家庭有10个可选择的日期,依次偏好下降)
  2. 作者比较了 每一天与前一天的参观的人数(不是家庭)的绝对差值。
    在这里插入图片描述
    发现这是一个简单的凸边形,所以可以增加一个特外的限制条件:
    if (number(d) >= 126), then (number(d)-number(d-1)) <= a-b*number(d)
    number(d)是在d天去的人数,然后a和b是预设的参数
  • 作者然后使用了3M variable model以及Large Neighborhood Search最大邻域搜索
  • 这里要提出一点,基于这个问题建立的MIP基本上都是保持一个假设:就是基本每一天去的人数不改变,然后在此基础上进行优化,然后最大邻域搜索,就是限制每天取得人数接近初始设置的人数即可。
  • 作者增加了限制每个家庭只能选择前六个偏好的日期,以及限制了一个gap的最大值。然后找到了了最优的方案。

3 相关知识

3.1 MIP

如果对混合整数规划不了解的朋友可以看下这个:

混合整数规划MIP+python(ortool库)实现 附代码
我喜欢第一个,用ortool实现得MIP,下面得感觉比较麻烦哈哈

混合整数规划MIP/线性规划LP+python(cplex库)实现 附代码

3.2 neighborhood search邻域搜索

这一篇关于局部搜索的博文是我转载的,需要的可以看一看,但是我看完感觉收获不大
局部搜索 邻域搜索

3.3 最大流问题

讲解 最大流问题+最小花费问题+python(ortool库)实现

4 实现代码剖析

代码过于复杂,但是基本原理就是使用MIP来求解,以及各种限制条件。如果需要探讨,可以私聊我要代码。但是感觉关键是看代码背后代表了什么知识就够了。

发布了47 篇原创文章 · 获赞 4 · 访问量 2278

猜你喜欢

转载自blog.csdn.net/qq_34107425/article/details/104044172