绪论
没有过初赛,时间很急,有部分代码还没有完善,机器人碰撞的问题没有解决,还有船到虚拟点的代码没有写好,代码也很不成熟。
一、题目
每个选手有 5 艘轮船、10 个机器人。以向下为x轴正方向,向右为y轴正方向。地图规格200x200,轮船2x4,泊位4x4。机器人只有上下左右四个方向移动,发生碰撞20帧的时间停留。不考虑船的路径规划。
二、数据交互
Init函数,用于数据初始化
地图数据,泊位数据(包括id(1~10),坐标x,y,运输时间(1~1000),装载速度(1~5)),船容量
Input函数,用于每帧交互
判题器输入每帧的帧数(1~15000),当前帧数所对应的金钱,新增的货物数量(0~10),坐标,价值。机器人状态,坐标,船状态,去往泊位坐标
三、流程概述
1.物品生成
物品将会随机生成在地图的每一个区域,物品有着不同的价值,每个物品会在指定位置停留 20s(1000 帧)的时间,若生成后 1000 帧内未被搬运则在地图上消失
2.机器人出发拾取货物
流程思路
在进行每一帧的交互中,我们得知机器人的坐标及货物的坐标,而每帧地图上新增货物数量为0~10个,机器人有10个,我们考虑将机器人,货物,泊位三者进行匹配。我们先不考虑货物价值,还有泊位的装载速度,仅从距离出发,让机器人拾取最近货物,然后从货物坐标出发,匹配最近的泊位。所以就将总路程分成两段距离,为了简化代码,我们组以货物为中心计算距离,从而实现匹配
优点:将问题简化
我们只考虑距离,未考虑货物价值,泊位的装载速度。但是初步我们这样考虑先实现代码的成功运行,再在此基础在进行优化
缺点:未考虑机器人拾取货物的最短时间
机器人一帧只能运动一格,而每帧货物数量都在增加,到最后会出现机器人不会取最近的货物而是最先出现实际上更远的货物。
改进
可能按照原来的从机器人出发匹配货物,计算机器人到哪个货物距离最短从而实现移动的方法会可行高效一些。
从机器人角度出发,不仅考虑机器人到货物的距离,也考虑其价值,选择最优解,可以用距离和价值的比值来进行估量
代码实现
用A*寻路算法找到货物到机器人和货物到泊位的最短路径,记录下路径
3.机器人成功拾取货物
机器人执行get指令成功拾取货物后按照一开始储存的路径出发到离货物最近的泊位
问题:机器人碰撞
移动过程中,机器人可能会有部分路径是重合的,发生碰撞导致机器人在后面运行异常
4.机器人将货物运输到泊位
id, x, y, time, velocity 表示一个泊位。我们仅考虑距离,按照一开始匹配的泊位,从货物坐标出发,读取储存路径到达泊位
缺点
机器人和货物,泊位三者的匹配是一开始固定好了的,所以在运货的时候,可能会出现泊位里面的货物已满但是机器人还运动到泊位的情况
优化
拾取到货物之后再选择去哪个泊位,考虑运输时间和装载速度,同样可以用比值来衡量
5.船运行到泊位
我们有两种思路
planA:考虑货物价值
船初始化是在虚拟点,各个泊位到虚拟点的距离不同,也就是运输时间不一样,我们需要给船指令让其去往哪个泊位。需要考虑泊位中
planB:均分
按距离划分,因为船的航行速度是一样的,所以我们根据泊位的运输时间将两个泊位进行捆绑,将十个泊位分给五艘船,一艘船匹配两个泊位,这样可以保证两个泊位中的货物轮流被运走。
我们用排序的方法将相邻运输时间的泊位分为一组,可能id是不一样的,所以我们要新建一个数组来存储按运输时间来排序的泊位id,代码实现如下
int sorted[10];
void sort()
{
for (int i = 0; i < 10; i++) {
sorted[i] = i; // 使用数组下标作为初始的泊位序号
}
// 使用冒泡排序对泊位序号按照运输时间由短到长排序
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 9 - i ; j++) {
if (berth[sorted[j]].transport_time >
berth[sorted[j + 1]].transport_time) {
// 交换泊位序号
int temp = sorted[j];
sorted[j] = sorted[j + 1];
sorted[j + 1] = temp;
}
}
}
}
当从虚拟点出发,船航行至所匹配的泊位,我们只需要比较两个泊位中的货物数量,货物价值及装载速度,选择最好的那个进行装载。在装载过程中,每帧判断是否泊位中是否有货,船的容量是否已满。装载完毕之后,判断是否达到船容量,未达到则运行至第二个泊位,已达到就返回至虚拟点
优点:解决船的等待问题
缺点:有些泊位无货,资源浪费
有些泊位比较偏僻,附近货物数量不多,会闲置船
6.泊位将货物装卸至船上
每个泊位的装载速度不同
问题:无法确定船的货物数量,离开时间
船在装载货物的同时,泊位的货物数量也有可能在增加,不能简单地比较某时刻的泊位货物数量与船容量。不知道船什么时候装满,所以也无法确定什么时候发送指令
7.船出发到虚拟点
当船的货物数量达到船容量,发送ship指令返回虚拟点
8.产生价值
当装了货物的船到达虚拟点的瞬间产生价值
四、代码实现
代码比较长,就不发在这里了,以上就写一下我们小组的思路及探讨结果
初赛练习阶段赛题相关材料及配套软件(Windows版本)_2024华为软件精英挑战赛_华为软件精英挑战赛_华为云论坛 (huaweicloud.com)