0%

2024华为软件精英挑战赛游记

初赛正式赛35名,遗憾离场,略微可惜。

第一周

参加这个比赛也是心血来潮。 一方面想着现在已经大二了,保研之前要丰富一下自己的简历,另一方面我还从没参加过企业举办的大型赛事,而且去看了下历年的题目,都是用算法去解决实际问题,对我来说蛮有吸引力。所以拉上我们班一位同学就去参加了。(比赛要求三个人所以去网上又找了一个重邮研二的)

报了名之后就没管了,一直到赛题发布的那一天。

第一眼看到赛题感觉有点难蚌,我之前去看了22、23年的华为软挑真题,认为23年既然已经考过这种控制机器人移动做任务的题目,那么24年考这个的概率就不大了。24考的题应该更接近于22年这种调度问题。没成想,24年居然还是机器人移动(当然也是包括调度问题的)。

第一天,看了看题目,下午和队友在线上开了个会,每个人分别讲了讲自己对赛题的理解。大致确定下了本题核心任务:调度 + 控制。

调度即为考虑机器人搬哪些货物,去哪个泊位;船去哪个泊位,什么时候回家,什么时候转运。调度问题为了简单起见,都是选择的编码难度最容易的调度方式。即机器人选最贵的物品,机器人选有船要来且最近的泊位,船满了就走先不考虑转运情况。

控制即操控机器人在最短时间内走到目标点。因为地图数据规模不大,所以我们选用每一步每一个机器人bfs一遍的策略。

晚上,我根据上面的思路,写了一个文字框架以及如何维护关键参数的思路:

写完框架后就摆烂了几天,主要那几天刚好事特别多... ...

最后在周末的时候,拉着我同学,花了大概2个多小时,一起对着上面的文字框架实现了一个基本的代码框架。并确定好了分工,他负责最短路算法以及机器人的运动,我负责船以及泊位的调度部分。

(P.S. 考虑到因为第三个队友跟我们不在同一个学校,不方便同时维护一份代码,所以让他根据自己想法写一个版本,无需受我写的文字框架的约束。兵分两路策略。)

第二周

到了比赛第二个星期,首先星期一星期二熬大夜把我负责的部分写完了。然后周末同学把他负责的那一部分也写完了。可是不能跑,机器人跑了几百帧就卡死了。于是周末的两个晚上,继续熬大夜,修复代码中的小BUG。最后成功让代码跑起来了,第一次有分。

跑出分说明代码框架已经没问题了,但是仍然存在跑了几百帧后几个机器人撞一块再也不动的情况。说明碰撞部分还是存在BUG。

于是我改变了原先解决碰撞的策略,在原先只有等待机制的情况下,引入失控机制:

  1. 俩机器人即将碰撞时,其中一个机器人进行等待模式,另一个机器人继续动
  2. 俩机器人若在同一个地方死锁,其中一个机器人进入等待模式,另一个机器人进入失控模式
  3. 等待模式的机器人原地不动,失控模式的机器人乱走

最后解决了碰撞问题,确定了我们组的baseline代码,8w分。

第三周

最忙的一周。几乎每天都熬到3、4点。主要问题就是优化baseline。其实优化之处还是非常多的。我按照我们的代码版本顺序来讲讲每个版本优化了哪些地方吧。

  • v1.0

    • baseline版本
  • v2.0

    • 机器人挑选物品由原先的挑最贵的,变为挑val(物品价值) / dis(机器人与物品的最短距离)最大的
    • 机器人由原先的锁定泊位,改为了锁定泊位的具体坐标
  • v3.0

    • 我同学想出了一个“革命性”的优化,不用每一步都对每个机器人求最短路,只需在机器人每次改变目标点时或者碰撞后求一个最短路就好了。将时间由原先的几乎一半时间都掉帧,优化到了几乎不掉帧

    • 完善了失控机制,原地等待wait_max_tim帧后同样进入失控状态,解决死锁

    • 调整了失控策略,由原先的4个方向顺序去搜变为4个方向随机数去走,避免来回踱步

    • 新增更换目标机制,若机器人road_tim帧内没到达目标 ,则会更换目标,解决死锁

  • v3.5

    • 规范了v3.0的代码风格和缩进
    • 略微调整了参数
  • v4.0

    • 初始时令每个机器人去到离他自己最近的泊位,将十个机器人分配到十个泊位上,避免陷入局部最优解
    • 改变了机器人确定目标泊位的策略:由原先的去已blocked的最近泊位改为去最近的泊位
    • 增加了船转运的功能,如果超过最低容量且一定时间内没装载,则去别的泊位装货
  • v5.0

    • 每个泊位里新增了一个队列q,可以统计泊位上的货物情况
    • 优化了船挑选目标泊位的策略,由原先的去最大价值泊位变成去能取到最大价值的泊位
  • v6.0

    • 增加了泊位聚类功能,可设置距离阈值控制聚类范围(这是个负优化,悲)
    • 增加了船排队功能,可设置每个泊位最多等待船数

当写完这7个版本的代码后,还剩2天就正式赛了。此时的代码在练习赛排行榜处于44名。于是剩下两天试图继续优化代码,可是我们写了很多优化最后都是负优化并无很大提升。于是最后一天用ChatGpt写了一个python调参程序开始炼丹。

正式赛

正式赛在第三周的周六。上午队友交了一发13名。后面大家陆陆续续起床了,排名就被刷到20多名了。正式赛这一天我们继续改了改泊位的调度思路,可是没啥正优化。最后排名被刷到30名。最后几个小时没有啥思路了,于是对着两个地图开始炼丹。最后交了几发提升了几千分,封榜前,排名上升到了29名(笑。

周天晚8点多去看了看晋级名单,35名。看来差一点。

后记

第一次参加软挑,然后蛮有收获的。首先,第一次维护那么长(臭)的代码,接近1k行代码。极大了提高了我编码和debug能力。其次让我知道了面向对象的重要性。下次再写这种大型项目最好用面向对象。其次,团队之间的合作也是非常重要的,就像这次比赛有两个突破性的难点都是我同学大佬想出来的。

最后,希望大家身体健康,学业顺利!