/ZhongXingHoldMoon

这是中兴捧月算法精英挑战赛通用软件赛道的解决方案,阶段一代码30.2分(全国第四名),阶段二代码50.21分(全国第32名)。该比赛要求设计一个流调度算法,将调度区中的流合理的分配各个端口,以最短时间发送全部流为目标。

Primary LanguageC++

简介

这是中兴捧月算法精英挑战赛通用软件赛道的解决方案,阶段一代码30.2分(并列第四名),阶段二代码50.21分(第32名)。该比赛要求设计一个流调度算法,将调度区中的流合理的分配各个端口,希望发生全部流的总时间越少越好。

阶段一(period_1)

算法流程如下图所示:

  1. 按进入设备时间给流数据递增排序;

  2. 按调度区时间(初始为0)取出流放入流调度区。调度区用链表存储数据,链表结点按发送所需时间递减排序,所需时间相同就按带宽递减排序,排在越前面,优先级越高;

  3. 调度器负责将调度区流分配给剩余容量最大的端口。

阶段1

阶段二(period_2)

主要新增条件:

  • 添加了流调度区和端口排队区流数量的限制;

  • 排队区达到最大限制后进入的流将被丢弃,丢弃的流按发送所需时间的2倍罚时。

针对这两个问题,该代码用了贪心+模拟的思路去解决。对三个部分进行了贪心,第一,希望在单位时间内,发送的带宽越大越好;第二,端口剩余带宽越小越好;第三,丢弃流的<流带宽/流发送所需时间>值越大越好。模拟采用了按给定规则排序的链表去模拟流调度区,大根堆模拟端口正在发送的流,队列模型各个端口的缓存区。算法的步骤可以概况为:

  1. 将全部流按进入设备时间递增排序;
  2. 定义两个时间变量以便于防止调度区流超限和控制流的丢弃。它们分别是调度区和排队区时间和用于判断端口中流是否发送完成的时间端口时间,它们初始化的时候都是最早进入设备的流的时间;
  3. 按当前流的发送时间取出流,存入按 <流带宽/流发送所需时间> 递减排序的链表中,该链表代表流调度区;
  4. 维护按可用带宽容量排序的端口大根堆,根的位置就是可用带宽容量最大的端口;
  5. 从2中的调度区链表的第一个元素开始搜索流,找到符合带宽要求的流将其分给剩余带宽最大的端口,若没有流符合要求,则通过更新端口时间去更新端口的剩余流。再重复第4步,直至当前调度区的流数量加上下一时刻进入调度区的流数量不超限,则退出。
  6. 更新调度区和排队区时间到下一个时刻,并重复第2步,直至所有流都被分配完毕。

阶段2