华为2019挑战赛
华为软件精英挑战赛总结(初赛)
赛题:
评分标准:
思路:这是一个典型的动态负载均衡算法的设计,对于每一辆车来说,时间最短意味着路程最优,首先想到迪杰斯特拉来求出每一辆车的最优路径。
1 def Dijkstra(Map, start_point, end_point): 2 dict = defaultdict(list) 3 for StartPoint,EndPoint,RoadLength in Map: 4 dict[StartPoint].append((RoadLength,EndPoint)) 5 q, seen, mins = [(0, start_point, ())], set(), {start_point: 0} 6 while q: 7 (cost,v1,path) = heappop(q) 8 if v1 not in seen: 9 seen.add(v1) 10 path = (v1, path) 11 if v1 == end_point: 12 break; 13 for RoadLength, v2 in dict.get(v1, ()): 14 if v2 in seen: continue 15 prev = mins.get(v2, None) 16 next = cost + RoadLength 17 if prev is None or next < prev: 18 mins[v2] = next 19 heappush(q, (next, v2, path)) 20 return cost,path
这是一个利用栈来优化后的迪杰斯特拉算法,算法返回路径花费和具体路径。这样能求出每一辆车在地图上的花费和最优路径。
核心思想有了,可以来处理数据,我们利用pandas来进行数据的处理和储存,处理后的数据得出三个矩阵,分别为车辆,道路和交叉路口。
我们利用路网信息来构建交通地图:
1 def ConstructionMap(roadData): 2 Map = [] 3 for i in range(len(roadData)): 4 if (roadData[i][-1] == 1): 5 Map.append((str(roadData[i][-3]), str(roadData[i][-2]), roadData[i][1])) 6 Map.append((str(roadData[i][-2]), str(roadData[i][-3]), roadData[i][1])) 7 else: 8 Map.append((str(roadData[i][-3]), str(roadData[i][-2]), roadData[i][1])) 9 return Map
地图Map中,有一个判断语句,if (roadData[i][-1] == 1):,这句是判断道路是否为双向道路,如果是双向道路,则将信息添加到对称位置中。由此可见Map矩阵在存储双向道路时,为一个对称矩阵。每一条信息存储为道路的起始信息和道路长度。
路网构建好后,就来到了核心算法,为路网上的每一个车辆寻找最优路线,达到全局最优,在这里会出现思索的情况,要根据具体情况来判定,解除死锁。这是优化本题的关键。
1 def FindRoute(CarList, RoadList, Map): 2 carRoute = [] 3 for carNum in range(len(CarList)): 4 ShortestRoute_theory = Dijkstra(Map, str(CarList[carNum][1]), str(CarList[carNum][2])) 5 ShortestRoute_list = [] 6 ShortestRoute_list.append(int(ShortestRoute_theory[0])) 7 lengthSumarize = len(ShortestRoute_list) 8 carRouteTmp = [CarList[carNum][0]] 9 carRouteTmp.append(CarList[carNum][-1]+random.randint(0,3000)) 10 for i in range(1, lengthSumarize - 1): 11 for j in range(len(RoadList)): 12 if ((RoadList[j][-3] == ShortestRoute_list[lengthSumarize - i] and RoadList[j][-2] == ShortestRoute_list[lengthSumarize - i - 1]) or (RoadList[j][-2] == ShortestRoute_list[lengthSumarize - i] and RoadList[j][-3] == ShortestRoute_list[lengthSumarize - i - 1])): 13 carRouteTmp.append(RoadList[j][0]) 14 carRoute.append(tuple(carRouteTmp)) 15 return carRoute
我们将车列表,路列表和Map作为函数的输入,循环车列表,将列中的每辆车信息按照发车时间放入到路网中求解。但是,这样做就会出现死锁,因为在有限的路网信息中,随着车数量的增加会出现某条道路上的车循环等待的情况,这样导致系统无法继续下去。我们从死锁的原因入手,通过随机数延长汽车的发车时间来缓解死锁情况。最后求出每一辆车的最优路线和时间。