2024华为软挑记录

本文讲述了作者参加华为软挑比赛的过程,从Python的A*算法遇到性能瓶颈,到使用C++优化路径规划,涉及避障算法改进和机器人协同策略。最后尝试了k-means聚类但效果不佳。
摘要由CSDN通过智能技术生成

在没有写总结的几周里,一方面在做华为的软挑,一方面在做今年的小挑,软挑初赛结束了五天了,很遗憾没有进入复赛,练习赛最后排在了15以内,但最终以西南赛区三等奖告一段落。或许还是被练习阶段的排名和分数蒙了眼,或许问题真的在迷宫的避障没有写好吧。现在已经快要忘记一些具体细节了,还是抓紧写下来,记录以下这次参赛的全过程。

2023年其实就看过华为软挑的赛题,2024年的赛题和2023年有很多相似之处,都设计路径规划和策略规划问题,但初赛好像要比去年的简单。想想23年的时候我还啥也不会,甚至一个判题器都研究了好久,这样比起来,今年还是有了很大的进步。赛题是智能港口,10个机器人,10个港口,5艘船,机器人要将地图上随机生成的货物运到港口,船负责将港口的货物运到虚拟点(初赛不考虑船的路径问题),因为船是慢速移动对象,而机器人是快速移动对象,所以以规划机器人为主。刚开始用的是我们比较熟悉的python,然后使用A*做路径规划,但是后来发现python太慢了,经常在计算路径的时候丢帧,然后就换了c++,使用c++速度明显上来了,基本不丢帧了,但机器人会有很强的沿着墙壁走的趋势,导致绕远路,浪费帧(机器人每帧只能走一格),后来给A*加了惩罚,让他去首先探索未知路径,这样用效果好了一点,但是还是感觉慢,又换了双向A*,对于某些地图有提升,总体感觉不明显。再后来我们想把所有的路径都提前存起来,初始化的时候就用bfs搜索整张地图,这一搜索就发现了盲点,bfs比A*速度快好多,而且搜出来一定是最短路径,于是就直接换成了bfs,分数大涨,果然最原始的就是最好的。

中间还有一次尝试,为了在A*的基础上搜索到真正的最短路径,用了平滑算法Bresenham,将A*规划出来的算法二次拉直,变成真正的最短路径。但是运算量过大,导致程序运行很慢。

再来说说避障的问题,避障应该是关键中的关键,正式赛的时候有一张图是迷宫,我们的避障算法吃了大亏。

思路1:机器人每一轮都会让当前自己的坐标加入地图(地图m)当中,如果要发生碰撞(i和j)了,如果当前机器人被重置之后另一个机器人不会再发生碰撞,则重置当前机器人,否则重置另一个机器人若两个机器人属于对撞,则同时重置两个,并根据地图m来重新规划路径,这样他就会规划出一条绕过发生碰撞机器人的路径;

问题:这个想法的最大问题就是机器人与机器人如果处于独木桥阶段,将会导致如果发生碰撞之后,重新规划的路径,由于另一个机器人的存在,而选择非常非常远的路径,而不是等待,让另一个机器人让开路了之后继续执行当前路径。

思路2:最基础的避障思路:

如果当前机器人的下一个位置等于其他机器人的当前位置(对撞和非对撞)

如果当前机器人的下一个位置等于其他机器人的下一个位置

以上这两种情况包含了所有的碰撞可能性,只要发生了碰撞,那就意味着必定会有至少一个机器人发生路径重新规划,那么当前帧就会变成无用帧,为了避免这个问题的发生,且要让这一帧走的路径有意义,那就会让当前机器人根据地图m来随机选择一个可行位置走(不超过地图,且不是障碍物)这样会让两个机器人拥有更多的避让空间,且如果是独木桥,其必然会后退,可以形成有效的独木桥避障。

问题:可能会让机器人多出很多不应该走的1帧,因为呆在原地不动可能是更优的选择,但是这种情况太难写了就没有写。

思路3:记录每个机器人上一帧发出的指令是什么,并让其在下一次执行的时候对比当前机器人的位置信息和上一帧记录下来的指令,并判断其是否相等,如果相等那就没有问题,如果不相等意味着,有未知的bug发生了,那就让当前机器人根据自己的目的地来重新规划路径。

思路4:由于机器人的目的地都是港口,而港口只有那么几个,很可能会发生几个机器人抢占一个港口的问题发生,所以机器人在选择港口目的地(港口为3*3的占地)的时候会选择3*3占地中间的任意一个格子作为目的地,用random来实现。

问题:选择3*3里面任意一个格子会导致机器人行走很多(最多(3-1)*2=4)无效路径,为了解决这个问题,需要找出港口和陆地紧邻的那几个格子,这样就不会有额外的深度。

机器人选择港口思路:

思路1: 机器人选择港口的最基础算法和选择货物的思路是一样的

思路2:将港口根据公式来排序(port.transport_time - 50 * port.loading_speed)取最优的5个,让船最开始去这5个港口。这主要是为了让船可以不用在多个港口之间往返,选择五个港口就好了。但是很明显,这样会有问题。

思路3:相邻很近的港口(可行距离小于20)会根据一定条件选择较优的那个(通常是往返时间)但是这个思路实际上用处不是特别大,只是理论上会有用。

机器人选择货物的思路:

思路1:首先计算机器人距离所有物品的欧氏距离,这很好计算,然后取欧氏距离最近的10个(这个数值是可以变化的,满足其计算时间小于15ms的时候越大越好,但是有性能上线)然后计算当前机器人到这几个货物的可行距离,然后根据可行距离算代价(dist - (0.5*good->val) - (id-good->birth_frame) * 0.01)代价最小的就是当前机器人最佳的货物,注意这里的可行距离要满足机器人到达之后货物任然存在这个条件。

问题:代价公式需要寻优算法来计算最佳的参数,例如这里代价函数意味着机器人更倾向于选择距离更小,价值更高,出生时间越久的货物,但是这几个参数是实时变化的,不同地图是不一样的,很难调参。

思路2:路径不为空且机器人手上没有货物 就认为他在去找东西的路上,如果当前机器人和其选中的货物着两个点组成的矩形中有更优的货物刷新出来了(代价函数计算,通常只会识别价值)那么就会去寻找这个更优的物品。

问题:问题就是这个思路并没有起到很大的作用,因为很少有这样优秀的物品出现,算法效果不大,而拿完物品之后不能丢,导致去寻找机器人和其选定港口这两点之间的更优物品无法实现,所以意义不是很大,但是逻辑上来说,应该是有用的,或许扩展这个矩形会让这个算法更优秀,但是依然需要调参,时间不够就没有尝试。

思路3:将地图中当前机器人无法到达的地方用障碍物填补掉,因为如果机器人或者货物刷新在这种地方,那就意味着其无效,其不可能到达港口,因此,为每一个机器人在初始化的时候配置一个可行区域,使用bfs,以这个机器人为起始点,在地图上蔓延开,能到达的地方为可行区,在选择货物和港口的时候判断他们在不在这个机器人的可行区中,在就继续计算。

最后来说说船,在初赛阶段,船是不需要规划路径的,只存在一个运动时间,船在运动时可以看作在海面消失,所以对于船来讲,只是一个时间上的规划,在有限的时间内,搬运回去尽可能多的货物。刚开始还是让船去了最近的五个港口,毕竟刚开始,还是以节省时间为主,拿完第一次去的港口的货物之后,根据一个估计的公式,判断要不要去下一个港口,或者是在当前港口等待,亦或者是返航售卖货物,这个公式是根据每个港口产生货物的速度估计的,而每个港口产生货物的速度是根据每个港口最近产生10个货物的时间来估计的,所以这个公式是,(港口产生货物的速度*(船在两个港口间移动的时间+船在下一个港口返程的时间-船在当前港口返程的时间))是否小于下一个港口目前的存货量+港口产生货物的速度*(船在两个港口间移动的时间+船在下一个港口返程的时间-船在当前港口返程的时间))主要就是判断下一个港口到底值不值得我过去,但其实这一长串公式也可以用估计的数值来代替,比如我就可以判断,当前船上可容量是否已经超过了船容量的80%,另一个港口的货物是否大于15个,如果是,就去另一个港口再搜刮一波。当然这个过程要注意,一定要让船能顺利返航卖掉最后一批东西,不然船还在回去卖的路上,游戏就结束了可就亏大了,所以在不足够返航+移动的时候就不要动了,老老实实呆在原地,再多拿几个货物再走。在剩余时间仅足够返航的时候,船就立刻返航。船上的货物有多少,以及港口的货物有多少都是要自己算的,判题器不会返回这些信息,数的准不准也非常重要。所以船虽然不需要规划路径,但是也是仅仅不需要规划路径,其他要考虑的还是挺多的,在最后船不能动了的阶段,我们为了拿到更多的货物,让机器人只取那几个港口送货了,这也是最后能尽可能再拿一些货物的办法。

我们的总体思路其实还挺简单,没有涉及到很复杂的算法,因为和队友两个人都不是计算机科班出身,很多规划算法并不懂,大多数时间都是在从细节出发,如果对于机器人的规划可以用上协同规划,多智能体规划,效果应该会好很多,包括之前看到上一届有些大佬用的就是ORCA群体避障算法,还有很多很多可以改进的地方,这次比赛收获很多,好像也让我有点喜欢上了做规划算法,挺好的,挺好的。奥对,说起来,我们后面还尝试了用聚类k-means把空地和港口聚类,分成几个块,不让机器人到处乱跑了,感觉也没啥效果哈哈哈哈,放个图纪念一下。

练习赛的时候有一张图分数特别高,所有人都特别高,上传时间段选好了我们也能直冲32w,大概也是因为这个就觉得32强应该差不多,果然比赛还是遵循了那个定律,现有的bug到了赛场会被无限放大。接下来要好好琢磨毕业和工作啦~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值