2019华为软件精英挑战赛初赛总结——思路及开源程序

刚参加完人生中第一个程序设计比赛,虽然没有进入复赛,但是还是感觉有所收获的。在这里把成果分享一下,也算给自己一个圆满的收尾。
初赛训练地图的调度时间是2000以内;比赛地图代码提交慢了,不过调度时间也比较长,将近10000,没有充足的时间来调试,所以输得心服口服。不过怎么我们队也是江大独苗嘛,也进过前20⁄(⁄ ⁄•⁄ω⁄•⁄ ⁄)⁄,争了口气!
代码贴在Git 2019HuaWei--JZE
这是一个车辆调度问题,文件资料我也贴在Git上了,大家可以自行钻研,这里就不解读了。


首先实现将道路(Road)通过路口(Cross)信息连接起来,获得地图完整的道路状况,如某条道路起点在那个路口,终点在哪个路口,前后各能通向哪里等。
道路信息显示

这里实现的逻辑如果从程序看上去,是比较复杂的,首先我们给出Road、Cross和Car的三个类定义:

class CROSS(object):
    def __init__(self,ID,road1,road2,road3,road4):
        self.ID = ID
        self.road1 = road1
        self.road2 = road2
        self.road3 = road3
        self.road4 = road4
   
class ROAD(object):
    left_road = None
    right_road = None
    stright_road = None
    back_left = None
    back_right = None
    back_stright = None
    all_right = 1
    def __init__(self,ID,length,speed_lim,channels,cross_begin,cross_end,isDuplex):
        self.ID = ID
        self.length = length
        self.speed_lim = speed_lim
        self.channels = channels
        self.cross_begin = cross_begin
        self.cross_end = cross_end
        self.isDuplex = isDuplex
        
class CAR(object):
    now_post = None
    def __init__(self,ID,start_loc,dest_loc,speed,start_time):
        self.ID = ID
        self.start_loc = start_loc
        self.dest_loc = dest_loc
        self.speed = speed
        self.start_time = start_time
        

然后读取训练地图的信息:

cars = pd.read_csv(r"C:\Users\Administrator\Desktop\JZE\1-map-training-1\car.txt",skipinitialspace = True)
roads = pd.read_csv(r"C:\Users\Administrator\Desktop\JZE\1-map-training-1\road.txt",skipinitialspace = True)
crosses = pd.read_csv(r"C:\Users\Administrator\Desktop\JZE\1-map-training-1\cross.txt",skipinitialspace = True)

然后创建三类对象链表,其中,在初始化Cross对象时进行Road道路信息写入

car_dict = {}
for car_info in cars.iterrows():
    car_dict[car_info[1][0].replace("(","")] = CAR(car_info[1][0].replace("(",""),car_info[1][1],car_info[1][2],car_info[1][3],car_info[1][4].replace(")",""))

road_dict = {}
for road_info in roads.iterrows():
    road_dict[road_info[1][0].replace("(","")] = ROAD(road_info[1][0].replace("(",""),road_info[1][1],road_info[1][2],road_info[1][3],road_info[1][4],road_info[1][5],road_info[1][6].replace(")",""))

cross_dict = {}
for cross_info in crosses.iterrows():
    the_cross = cross_info[1][0].replace("(","")
    fir = str(int(cross_info[1][1]))
    sec = str(int(cross_info[1][2]))
    thi = str(int(cross_info[1][3]))
    fot = str(int(cross_info[1][4].replace(")","")))
    if fir != "-1":
        if cross_info[1][0].replace("(","") == str(road_dict[fir].cross_begin):
            if (road_dict[fir].isDuplex == "1"):
                road_dict[fir].back_left = road_dict[sec] if sec != "-1" and ((road_dict[sec].isDuplex == "1") or str(road_dict[sec].cross_begin) == the_cross) else None
                road_dict[fir].back_stright = road_dict[thi] if thi != "-1" and ((road_dict[thi].isDuplex == "1") or str(road_dict[thi].cross_begin) == the_cross) else None
                road_dict[fir].back_right = road_dict[fot] if fot != "-1" and ((road_dict[fot].isDuplex == "1") or str(road_dict[fot].cross_begin) == the_cross) else None
                    
            else:
                road_dict[fir].back_left = None
                road_dict[fir].back_stright = None
                road_dict[fir].back_right = None
        else:
            road_dict[fir].left_road = road_dict[sec] if sec != "-1" and ((road_dict[sec].isDuplex == "1") or str(road_dict[sec].cross_begin) == the_cross) else None
            road_dict[fir].stright_road = road_dict[thi] if thi != "-1" and ((road_dict[thi].isDuplex == "1") or str(road_dict[thi].cross_begin) == the_cross) else None                
            road_dict[fir].right_road = road_dict[fot] if fot != "-1"  and ((road_dict[fot].isDuplex == "1") or str(road_dict[fot].cross_begin) == the_cross) else None
   ...
   ...
   ...
            
    cross_dict[cross_info[1][0].replace("(","")] = CROSS(cross_info[1][0].replace("(",""),road_dict[fir] if fir in road_dict else None,road_dict[sec] if sec in road_dict else None,\
                                                    road_dict[thi] if thi in road_dict else None,road_dict[fot] if fot in road_dict else None)
for index,item in road_dict.items():    #以列表返回可遍历的(键, 值) 元组数组
    print("当前道路:",item.ID,"\t直行:",item.stright_road.ID if item.stright_road != None else None,"\t左转:",item.left_road.ID if item.left_road != None else None,"\t右转:",item.right_road.ID if item.right_road != None else None,\
         "\t反直:",item.back_stright.ID if item.back_stright != None else None,"\t反左:",item.back_left.ID if item.back_left != None else None,"\t反右:",item.back_right.ID if item.back_right != None else None)
 

这里为了方便理解,上面程序只贴出对于路口一的判断来说明:
首先判断cross中的road1的起点是否为该cross。如果是,那么判断road1是否为双向:如果为双向,那么将该路口其他三条road分别作为road1的反向道路写入;如果是单向线,那么road1只能从起点通往终点,那么该路口的其他road就不能通过road1到达,即road1的反向三个路口为None。如果road1起点不是该cross(则该cross是road1终点),那么该cross的其他三条road边肯定是road1的前向三路口,且能到达。(大家好好琢磨一下赛制和规则,这里就好理解了)

我们画图来看一下:
Road信息图解

实现道路后,下面就是按照一个规则(算法)来实现道路分配,这里提一下,听说大佬们都用的退火做的,保持各赛区最低系统调度时间。我们这里就简单了一下,所以时间比较高。。。也不能说懒,就没花时间去钻研吧,所以唉。。。追悔莫及有点过,多多少少还是有遗憾的。
这里我是按照当前car所在cross和car终点两个位置来作比较得到car的行驶路线的,这样容易出现找不到终点一直徘徊的情况(因为不是越靠近终点的road就一定有条路通向终点,之后正式比赛更是如此)。所以如果出现这样的情况,我就让徘徊不前的路暂时关闭,然后倒退重新搜索;如果本轮搜索不到终点,即road全部被关闭,那么重新选择初始道路重新进行一轮道路规划(car的起点是cross,一个cross有多个road,所以car的起点也有多个)。
至于小车的出发时间,哈哈哈~我们就更偷懒了,抱着侥幸的心理我们是给了一个“像样”的随机策略来给小车安排出发时间的。
所以这两部分的代码,我就不贴出来献丑了,需要的画直接去2019HuaWei--JZEclone吧(如果觉得还行的话,可否给个给个星星呢(*>.<))
说明一下,Git上的代码是根据比赛要求的SDK进行编写的,如果你要本地跑的话,把读取文件的地方改一下就好。


上面的是初赛训练地图的程序,比赛地图的规模大了很多,而且cross信息也不像训练地图那么简单,所以程序也做了很大的修改,主要有如下两点:

1.正式赛cross标号不是越大越“远”,故需要将cross初始化的时候写上位置信息
比赛地图思路
2.根据新增的cross位置信息查找car最短路径,思路与训练赛相同。

决赛程序的调整和运行效率调整主要是我们队长负责的,我理解的差不多就这样啦,欢迎各位大佬交流讨论!
本篇属于原创,所以就不贴搬运工啦。


努力,奋斗

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容