华为挑战赛初赛

华为挑战赛初赛

整体思路:

给每个小车指定一个目标,然后小车按照给定的目标执行。也就是分为两部分,一是建立一个目标分配机制,二是建立小车的自主导航和执行系统。

目标分配思路:

如果小车当前没有目标,则给此小车分配目标。如果小车有目标,则不进行分配。目标分配应该朝着能赚更多钱的方向,由于小车的属性是几乎一致的,所以主要是依据小车的位置以及当前运载货物的情况还有工作台的位置、所需原材料、出售产品进行销售。

可以让小车的目标只有两种类型:去目的地买东西,去目的地卖东西。

到底去哪个工作台买东西,去哪个工作台台卖东西?里面肯定有非常多的权衡。由于我水平有限,所以只得采用一些简单粗暴的策略。

首先考虑小车到工作台的距离,距离越近越该称为小车的目的地。最简单粗暴就是把小车到所有工作台(能跳过一些不算)的距离算出来,然后排序。

其次,考虑产品的供需问题。为了简单,我们让小车买东西和卖东西是独立的,也就是买东西的时候只考虑当前能不能卖,而不管买了之后能不能卖。卖东西也就更不需要管了。

对于买东西:有某样东西能卖,而且能买,就让小车去目的地买。那肯定有很多东西能买而且能卖的,不妨简单地以距离(到买东西目的的距离,就可以了大概)作为权重排序。

对于卖东西:能最近去哪卖就去哪里卖。

小车的自主导航和执行系统思路

为了简单起见,让小车只有两种运动,一是转,二是前进。

小车的目标可以拆分了两步:

  1. 到达目的地。以最快的速度,尽量避免碰撞地前往目的地。
  2. 在目的地执行操作(买或卖)。

主要的难题在第一步。为了简答起见,前进和转都是采用最大速度。通过与ChatGPT的深入对谈,应该采用基于规则的避障算法。“漏斗算法”是一个不错的选择,这个算法把小车当前的运动分为两个情况:往目的地前进和避障。

前进:小车转向目的地并前进。

避障:在小车前方划定一个漏斗形的区域,检测区域内有没有障碍物。可以划分为两个区域:左侧和右侧。左有障碍物就往右走(顺时针旋转前进),右有障碍物就往左走(逆时针旋转前进),左右都有障碍物往距离远的方向走。

第二步,检测到当前到达了目的地就进行相应的操作。

具体实现

目标分配:

由于小车只有4个,所以小车作为“查询对象”。

bool数组作为标志小车有没有目标。

若小车没有目标,则开始对该小车进行“计算”:

  1. 如果小车载有货物,那么找到买当前运载货物的工作台,并选择最近的一个作为目标,到目标后则卖东西,小车变成无目标状态。为了避免冲突,规定只有小车的目标是不能相同的。
  2. 如果小车没有货物,那么找到出售东西的工作台。然后筛选出其中能转卖的,选择最近的(有可能仅用到距离排序是不够的)一个作为目标,到达目标后则买东西,小车变成无目标状态。

若小车有目标,则跳过。

小车的自主导航和执行系统

漏斗算法把小车当前的运动分为两个情况:往目的地前进和避障。

  1. 往目的地前进:计算目的地在小车的哪个方向,也就是计算出小车与目的地连线与x轴正方向(正右方向的夹角),然后根据夹角的正负和大小确定旋转的方向。在旋转的同时也前进。
  2. 避障:实际上我们在计算的时候并不需要搞一个漏斗形的区域来检测,因为我们要躲避的障碍物实际是很少的,而且它们的位置也是知道的。所以可以大幅度地进行简化。一个简单的做法就是监视小车之间的距离。如果小车的距离过近了,就进行错开转向。错开转向可以分多种情况。

与目的地的距离足够小的时候,就进行相应的买卖操作。

调试

这部分是我陌生的,搞了很久还没搞成。I must have patience.

或者可以换种思路:手动生成数据调试。

采用这种方式初步完了调试,但还存在许多问题。

问题

  1. 小车无法识别边界
  2. 小车如果出现“买卖失败”无法处理,也就是输出了买卖的命令仍有可能买卖失败的情况。
  3. 在角度计算时有特殊的情况,在两个角度一正一负的时候,大于180度时的判断出现错误。大致有时候小车会无缘无故乱走撞墙,甚至拥挤在一起。

3.24:这些问题得到了一定的解决。

  1. 动态避障失效:不能单纯靠判断障碍物的位置来确定车的转向。这个问题可以设立更多的判断,如果假定小车都是动态的,可以分两种情况考虑:
    1. 障碍物小车是相对自己是横向行驶的;
    2. 障碍物小车相对自己是纵向行驶的。
  2. 停留在工作台:当执行完一个任务后,如果没有分配到新的目标,小车会停留在工作台,有可能会导致另外的小车无法正常进行任务。这个问题的话,可以让没有目标的小车也运动起来,比如可以让它回到中央,并在中央附近待命。
  3. 更合理和科学的目标分配权重。现在目标的权重完全是由于目的地的距离来决定的,如何建立更加完善的目标权重分配机制,分配更合理的目标。除了距离这个因素,赚的金币多少也是非常重要的因素。不同的物品有不同的回报率,回报越高的工作台应该有更高的权重。但是也会有更高的风险:没有充足的时间来将它卖出去。

正式赛

因素

观察正式赛的地图,发现主要的难点在于合理分配目标,而不是控制小车.

目标分配的合理主要体现在

  1. 如何让小车之间懂得分工合作
  2. 不同物品的生产和卖出是由关联的,如何体现这种关联性

目标权重的因素:

  1. 距离
  2. 赚差价
  3. 紧缺度
  4. 短缺度
  5. 拥挤度

距离就是小车距离目的地点的路径长度。

赚差价就是这个商品赚钱的程度,型号越高的产品就越赚钱。

紧缺度就是这个商品对于生产的紧缺程度,由于一些工作台生产产品需要多种原材料,如果它只缺1个原料就能生产了,就比较紧缺。紧缺度往往还和赚差价有关,因为高级的商品需要更多的原材料。

短缺度就是这个商品有多少个工作台需要,越多工作台需要(或者说越多工作台收购这个产品)就越短缺。

拥挤度就是目的工作台是否拥挤,如果小车都拥挤到某个区域,就容易造成碰撞,或者因躲避而加长运输的路径。

要想分配好目标,就要想办法搞出一个权重评判系统,对不同的目标作出排序,选择最好的目标。

首先要做的是如何计算这些因素。

距离的计算是容易的,赚差价可以算是固定的。

  1. 紧缺度:紧缺度取决于生产配方的工作台的原料格状态,而且这个因素对于买和卖有着不同的意义。对于4型工作台需要物品1和2,如果两个都缺,物品1和2的紧缺度是一样的(如果不考虑其他工作台),如果有1缺2,那么2的紧缺度更高。对于不同的工作台,可以采用一样的标准,特别地,对7型工作台当其生产配方缺少1个的时候会有最高的紧缺度,对于纯收购的工作台紧缺度最低。小车优先购买紧缺度高的物品,优先向紧缺度高的工作台出售物品。
  2. 短缺度:短缺度取决于能收购该物品的工作台数量。所以实际上短缺度对于卖东西没有明显的意义,或者也可以优先把东西卖给能生产短缺度更高的物品的工作台。买东西的时候优先买短缺度高的物品,这样能够更好地卖出去。
  3. 拥挤度:这个是比较难计算的,或者说还没想出计算量比较小的算法。有一个方法就是把地图划分为几个区域,比如9个区域,然后把工作台划分到对应的区域。如果某个区域越拥挤,就越不选择这个区域的工作台。

权重的计算

买东西的时候,工作台的权重W

$$
W=\frac{赚差价×紧缺度×短缺度}{距离×拥挤度}
$$

卖东西的时候,工作台的权重W

$$
W=\frac{赚差价×紧缺度×短缺度}{距离×拥挤度}
$$

虽然这两个公式是相同的,但是实际上各个因素有着不同的意义。比如赚差价,在买东西的时候是指工作台生产出来(售卖)的物品的赚差价程度;而在卖东西的时候是指工作台接受物品后能生产出来的物品的赚差价程度。

问题

  1. 发现紧缺度的效果不明显。工作台的紧缺度应该由两部分组成,一是目前原料格快满的程度,二是它生产的产品是很紧缺的。(发现是更新最大权值的时候搞错了而已)

  2. 提交的代码无法在华为的平台上正常运行!

    • 先检查所有下标
    • 检查语法

    经过细心的检查,已经成功发现了若干下标越界的情况并进行了修复,成功在平台上跑了!

  3. 小车的运动还不是很行。有时候会发生碰撞并黏在一起。在边界的处理过于简单,导致有时候比较低效。

    1. 如何实现靠近墙壁不减速,或者说自发离开墙壁附近?
  4. 合理的空闲位安排。

    image-20230325114206540

image-20230325114246007

image-20230325114346156

image-20230325114431492

准备放弃

3.35

只能说没法子了。只能当做玩一下了。😣


华为挑战赛初赛
http://thinkerhui.site/2023/03/25/自学研究/华为挑战赛初赛/
作者
thinkerhui
发布于
2023年3月25日
许可协议