算法(四)

1     算法描述

组委会正在为美团点评CodeM大赛的决赛设计新赛制。

比赛有 n 个人参加(其中 n 为2的次方),每个参赛者根据资格赛和预赛、复赛的成绩,会有不同的积分。比赛采取锦标赛赛制,分轮次进行,设某一轮有 m 个人参加,那么参赛者会被分为m/2 组,每组恰好 2 人,m/2 组的人分别比赛。我们假定积分高的人肯定获胜,若积分一样,则随机产生获胜者。获胜者获得参加下一轮的资格,输的人被淘汰。重复这个过程,直至决出冠军。现在请问,参赛者A最多可以晋级到第几轮(初始为第0轮)

2     算法分析

本章节的算法分析包括两个步骤:用例分析与逻辑分析。

2.1   用例分析

用例名称

2个参赛者

输入

参赛者A的积分:7

参赛者B的积分:2

分析步骤

A与B比赛,A的积分比B的积分高,所以A胜利,B被淘汰,参赛者A的积分:8

比赛结果

参赛者A最多参加第一轮

用例名称

4个参赛者

输入

参赛者A的积分:7

参赛者B的积分:2

参赛者C的积分:3

参赛者D的积分:6

分析步骤

第一轮:

A与最低积分者B比赛,A胜利B被淘汰,A的积分:8

CD比赛,D胜利C淘汰,D的积分:7

第二轮:

AD比赛,A胜利,D被淘汰,参赛者A的积分:9

比赛结果

参赛者A最多参加第二轮

2.2   逻辑分析

主流程算法逻辑

  • 每次比赛前对参赛者的积分排序

  • 分组比赛,让参赛者A与积分最少者比赛,A的积分最少则A在该轮次被淘汰

  • 分组比赛,其他参赛者按照积分次序与次积分低者比赛,积分高者胜利,积分低者失败,积分相同的参赛者索引值大的胜利

  • 统计晋升者的积分

  • 晋升轮次后,重复执行1的步骤

  • 比赛结束,统计输出A参加的轮次

分组算法逻辑

从最高积分者开始分组,2人一组,最后一名积分最低者与参赛者A比赛

积分算法逻辑

  • 参赛者的人数是2的n次方,每轮次淘汰掉一半的参赛者

  •  胜利者每次增加1积分并且直接进入下一轮次,失败者直接被淘汰

  • 积分的最大偏移量是n,也就是,假如参赛者开始的积分是1,则进入n轮次后,其积分是1+n

  • 假设参赛者中的初始最大积分数是M,则比赛中的最大积分= M+n

积分排序算法逻辑

  • Map-MultiThreadsSort-Reduce算法,其计算方式是:对积分列表分片-多线程执行分片排序-汇总分片排序结果-输出积分排序列表

  • 保持参赛者A在数组的索引0的位置

比赛算法逻辑

每轮次比赛后,按照数组的顺序移动A[n]中的胜利者到对应的主数组

3     算法目标

算法运行的目标是最小化系统资源开销(包括处理器资源开销与内存资源开销)以及最小耗时(算法运行时长)。

4     算法设计

4.1   数据结构设计

名称

参赛者数组积分列表

类型

一维数组

长度

参赛者的数量

描述

存储所有参赛者的积分数据

4.2   算法逻辑设计

4.2.1 genData输入数据

  1.   输入参赛者的积分列表,按照以上的数据结构标准化处理输入

  2.   积分排序sortRankFunc算法函数

4.2.2 mainFunc函数主流程设计

  1.    对输入的参赛者按照积分高低进行排序

  2.   对输入的参赛者按照积分相同的进行分组

  3.   对输入的参赛者按照积分的高低次序进行两两分组

  4.   比赛

  5.   胜利者积分+1,更新胜利者积分

  6.   移动胜利者到指定的积分队列

  7.   淘汰失败者,设置失败者的状态

  8.   产生新的比赛轮次的参赛者,参赛者A胜利则继续执行1步骤,参赛者A失败则结束比赛执行9步骤

  9.   输出参赛者A的轮次

4.2.3 sortRankFunc积分排序算法

该算法使用Java Lambda表达式并行流式计算与Map-Reduce分片排序,其流程如下所示:

  1.   确定积分分片的大小

  2.   对积分分片

  3.   并行计算每片积分列表的排序

  4.   汇总合并每片排序的积分列表

5     算法实现

5.1   程序语言

本程序分别使用Java语言。

5.2   程序示例

5.2.1 genData函数

5.2.2 getRandomData函数

5.2.3 mainFunc函数

5.2.4 sortRankFunc函数

5.2.5 mergeSort函数

5.2.6 sortPiece函数

5.2.7 insertSort函数

5.2.8 seperatePieces函数

5.2.9 normalCompute函数

5.2.10          saveRecourceCompute函数

5.2.11          testSort函数

5.2.12          testPiecesSort函数

6     算法验证

本算法验证测试使用代码覆盖率测试方法。

6.1   测试用例

用例描述

参赛人数2

执行次数:10

输入数列:随机数列

输出数:最大比赛轮次

输出值:由随机数列确定

覆盖函数:所有函数

用例描述

参赛人数128

执行次数:10

输入数列:随机数列

输出数:最大比赛轮次

输出值:由随机数列确定

覆盖函数:所有函数

用例描述

参赛人数1024

执行次数:10

输入数列:随机数列

输出数:最大比赛轮次

输出值:由随机数列确定

覆盖函数:所有函数

6.2   执行用例

测试用例通过率100%,代码覆盖率100%。

7     算法效率

7.1   时间复杂度

由代码可知该算法的时间复杂度等于O(N的多次方)。

7.2   空间复杂度

该算法使用一维数组,其空间复杂度是常数。

7.3   性能测试

输入数列长度

输出数列长度

耗时

1024*1024

14318毫秒

1024*1024*2

27939毫秒

由以上的性能测试可知,每增加一个数量级范围,耗时线性增长。

7.4   算法优化

已启动多线程并行的处理。

(未完待续)

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wangys2006

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值