class RiderStatusTracker: timestamp = -1 def __init__(self, wait_dict, serve_dict, finish_dict, cancel_dict): self.__logger = Logger("RiderStatusTracker") self.__wait_dict = wait_dict self.__serve_dict = serve_dict self.__finish_dict = finish_dict self.__cancel_dict = cancel_dict def checkRiderStatusIfTimeOut(self, rider): if RiderStatusTracker.timestamp - rider.getRequestTimeStamp( ) >= rider.getPatience(): rider.setStatus(CANCEL) self.__cancel_dict[rider.getID()] = rider zone_id = rider.getSrcZone() dir = rider.getDirID() group_id = rider.getGroupID() del self.__wait_dict[zone_id][dir][group_id][rider.getID()] if len(self.__wait_dict[zone_id][dir][group_id]) == 0: del self.__wait_dict[zone_id][dir][group_id] #cancel_dict[RiderStatusTracker.timestamp][rider.getSrcZone()] += 1 else: self.__logger.debug( RiderStatusTracker.timestamp, "updateRiderStatusWhenTimeOut", None, rider.getID(), "Cancel Time Should be: ", str(rider.getRequestTimeStamp() + rider.getPatience())) def updateRiderStatusAfterMatching(self, rider): rider.calcSat() rider.setStatus(SERVING) self.__serve_dict[rider.getID()] = rider def notifyRiderToFinishTrip(self, rider): if rider.getStatus() == SERVING: self.__finish_dict[rider.getID()] = rider rider.setStatus(FINISHED) del self.__serve_dict[rider.getID()] else: self.__logger.error(RiderStatusTracker.timestamp, "updateRiderStatusWhenInService", None, rider.getID(), "The status and dict not match.") raise Exception("The rider status and dict not match.") def updateRiderStatusWhenWait(self, rider, wait_rider_dict): if rider.getStatus() == WAITING: rider.tickWaitTime() wait_rider_dict[RiderStatusTracker.timestamp][ rider.getSrcZone()] += 1 else: self.__logger.error(RiderStatusTracker.timestamp, "updateDriverStatusWhenIdle", None, rider.getID(), "Rider Status is Wrong.") raise Exception("The rider status and dict not match.")
class DriverStatusTracker: timestamp = -1 def __init__(self, driver_dict): self.__logger = Logger("DriverStatusTracker") self.__driver_dict = driver_dict def updateDriverStatusAfterMatching(self, driver): driver.setStatus(INSERVICE) driver.calcTripRoute() driver.calcTripEffort() driver.notifyRiderPrice() driver.calcTripProfit() def updateDriverStatusWhenInService(self, driver, rider_tracker): for elem in driver.getTripRoute().copy(): if elem.getEventTime() <= DriverStatusTracker.timestamp: #handle rider on board curr_elem = driver.popTripRoute() if curr_elem.getEvent() == DROPOFF: rider = driver.getRider(curr_elem.getRiderID()) rider_tracker.notifyRiderToFinishTrip(rider) driver.removeRider(curr_elem.getRiderID()) #handle driver del self.__driver_dict[driver.getPos()][driver.getID()] self.__driver_dict[curr_elem.getZoneID()][driver.getID()] = driver driver.setPos(curr_elem.getZoneID()) if len(driver.getTripRoute()) == 0: driver.setStatus(IDLE) driver.setFinishTripTime(DriverStatusTracker.timestamp) def updateDriverStatusWhenIdle(self, driver, no_work_dict): if driver.getStatus() == IDLE: if driver.getFinishTripTime() != DriverStatusTracker.timestamp: driver.tickIdleTime() no_work_dict[DriverStatusTracker.timestamp][driver.getPos()] += 1 else: self.__logger.error(DriverStatusTracker.timestamp, "updateDriverStatusWhenIdle", driver.getID(), None, "Driver Status is Wrong.") raise Exception("The driver status and dict not match.")
class RequestList: timestamp = -1 def __init__(self): self.__logger = Logger("RequestList") #self.__logger.setLevel(logging.INFO) self.__logger.info(RequestList.timestamp, "__INIT__", None, None, "Create RequestList Object.") self.__items = [] def __str__(self): ret = "[" for i in range(0, len(self.__items)): ret = ret + str(self.__items[i]) + ", " ret = ret + "]" return ret def first_element(self): if self.is_empty(): self.__logger.error(RequestList.timestamp, "__INIT__", None, None, "No First element exists.") raise Exception("No First element exists.") return self.__items[0] def remove(self): item = self.__items.pop(0) self.__logger.info(RequestList.timestamp, "remove", None, None, str(item)) return item def is_empty(self): return len(self.__items) == 0 def __len__(self): return len(self.__items) def add(self, item): self.__logger.info(RequestList.timestamp, "add", None, None, str(item)) self.__items.append(item)
class Rider: timestamp = -1 def __init__(self, uID, sT, sZ, dZ, dP, pat, srcX, srcY, destX, destY): # logger in Dispatcher self.__logger = Logger('Rider') #self.__logger.setLevel(logging.DEBUG) self.__logger.info(Rider.timestamp, "__INIT__", None, None, "Create A Rider Object") self.__id = uID self.__request_timestamp = sT self.__srcZone = sZ self.__destZone = dZ self.__default_price = dP self.__price = math.inf self.__patience = pat self.__dirID = self.__assignDirID(srcX, srcY, destX, destY) self.__shortest_time = Graph.queryTravelCost(sZ, dZ) self.__arrival_timestamp = None self.__groupID = None self.__status = WAITING self.__wait_time = 0 self.__detour_time = -1 self.__sat = 0 if self.__default_price > 100: self.__logger.warning(Rider.timestamp, "__INIT__", None, self.getID(), str(self)) def __str__(self): ret = "{" + str(self.__id) + ', ' + str(self.__request_timestamp) + ", " + str(self.__srcZone) + ", " + str(self.__destZone) + ", " + \ str(self.__default_price) + ", " + str(self.__price) + ", " + str(self.__patience) + ", " + str(self.__dirID) +", " + \ str(self.__shortest_time) + ", " + str(self.__arrival_timestamp) + ", " + str(self.__groupID) + ", " +\ str(self.__status) + ", " + str(self.__wait_time) + ", " + str(self.__detour_time) + ", " + str(self.__sat) + "}" return ret #https://stackoverflow.com/questions/13226038/calculating-angle-between-two-vectors-in-python #The range is [-180, 180) def __calcDirection(self, srcX, srcY, destX, destY): p1 = [srcX, srcY] p0 = [destX, destY] p2 = p1 + np.array([1, 0]) v0 = np.array(p0) - np.array(p1) v1 = np.array(p2) - np.array(p1) angle = np.math.atan2(np.linalg.det([v0, v1]), np.dot(v0, v1)) return np.degrees(angle)*(-1) #Tansfer from [-180,180) to [0,360). #calculate DirID by dividing the DIR_THRESHOLD def __assignDirID(self, srcX, srcY, destX, destY): dir = self.__calcDirection(srcX, srcY, destX, destY) return int((dir+180)/DIR_THRESHOLD) def setDirID(self, dir): self.__dirID = dir def getDirID(self): return self.__dirID def setGroupID(self, grpID): self.__groupID = grpID def getGroupID(self): return self.__groupID def tickWaitTime(self): self.__wait_time += 1 def getWaitTime(self): return self.__wait_time def getShortestTime(self): return self.__shortest_time def calcDetourTime(self, time): self.__detour_time = time - self.__shortest_time def getDetourTime(self): return self.__detour_time def setArrivalTimestamp(self, time): self.__arrival_timestamp = time def getArrivalTimestamp(self): return self.__arrival_timestamp #prerequest: calc detour time first def calcPrice(self, n_shared): if self.__detour_time < 0: self.__logger.error(Rider.timestamp, "calcPrice", None, self.getID(), "Detour time is unreasonable.") raise Exception("Detour time is unreasonable.") self.__price = self.__default_price * math.exp(DETOUR_WEIGH * -self.__detour_time) if n_shared == 1: self.__price = self.__price * DISCOUNT_1 elif n_shared == 2: self.__price = self.__price * DISCOUNT_2 elif n_shared == 3: self.__price = self.__price * DISCOUNT_3 elif n_shared == 4: self.__price = self.__price * DISCOUNT_4 else: self.__logger.error(Rider.timestamp, "calcPrice", None, self.getID(), "Shared number is incorret.") raise Exception("Shared number is incorret.") def getPrice(self): return self.__price def getDefaultPrice(self): return self.__default_price def calcSat(self): if self.__detour_time < 0: self.__logger.error(Rider.timestamp, "calcSat", None, self.getID(), "Detour time is unreasonable.") raise Exception("Detour time is unreasonable.") elif self.__price > self.__default_price: self.__logger.error(Rider.timestamp, "calcSat", None, self.getID(), "Price is unreasonable.") raise Exception("Price is unreasonable.") else: self.__sat = (self.__default_price-self.__price)*SAT_PRICE - math.expm1(self.__detour_time) if self.__sat > 10000000: self.__logger.warning(Rider.timestamp, "calcPrice", None, self.getID(), "SAT is too large", str(self)) def getSat(self): return self.__sat def getID(self): return self.__id def getRequestTimeStamp(self): return self.__request_timestamp def getSrcZone(self): return self.__srcZone def getDestZone(self): return self.__destZone def getPatience(self): return self.__patience def setStatus(self, status): self.__status = status def getStatus(self): return self.__status
class ClusteringStrategy(ABC): timestamp = -1 def __init__(self, rider_waiting_dict): self.logger = Logger('ClusteringStrategy') # self.logger.setLevel(logging.DEBUG) self.logger.info(ClusteringStrategy.timestamp, "__INIT__", None, None, "Initialize ClusteringStrategy") self.__assign_gid_dict = {} self.__rider_dict = rider_waiting_dict # Assign Group ID for zone_id in range(1, 78): self.__assign_gid_dict[zone_id] = {} for dir_id in range(-1, 12): self.__assign_gid_dict[zone_id][dir_id] = 1 def showAssignGidDict(self): ret = "{" for zone_id in self.__assign_gid_dict.keys(): ret = ret + str(zone_id) + ": {" for dir_id in self.__assign_gid_dict[zone_id].keys(): ret = ret + str(dir_id) + ": [" + str( self.__assign_gid_dict[zone_id][dir_id]) + "], " ret = ret + "}, \n" ret = ret + "}" return ret def getGroupID(self, zone_id, dir_id): return self.__assign_gid_dict[zone_id][dir_id] def tickGroupID(self, zone_id, dir_id): self.__assign_gid_dict[zone_id][dir_id] += 1 def groupRiderByDir(self, rider, group_vulumn): # Rider's zone ID and dir ID zone_id = rider.getSrcZone() dir_id = rider.getDirID() group_id = self.getGroupID(zone_id, dir_id) # self.__rider_waiting_dict[rider.getSrcZone()][rider.getDirID()] is defaultdict(dict) # group_num is the dict if rider.getID( ) not in self.__rider_dict[zone_id][dir_id][group_id].keys(): self.__rider_dict[zone_id][dir_id][group_id][rider.getID()] = rider rider.setGroupID(group_id) else: self.logger.error(ClusteringStrategy.timestamp, "groupRiderByDir", None, rider.getID(), "Rider has been in the Pool") # check how many riders in the zone&direction&group_num to determine group id rider_num = len(self.__rider_dict[zone_id][dir_id][group_id]) # When the number of rider in group up to VEHICLE_CAPACITY if rider_num == group_vulumn: self.tickGroupID(zone_id, dir_id) @abstractmethod def cluster(self, rider): pass
class Driver: timestamp = -1 def __init__(self, id, pCurr): # logger in Dispatcher self.__logger = Logger('Driver') #self.__logger.setLevel(logging.DEBUG) self.__logger.info(Driver.timestamp, "__INIT__", None, None, "Create A Driver Object") self.__id = id self.__pos = pCurr self.__status = IDLE self.__riders = {} self.__trip_route = [] self.__trip_effort = 0 self.__trip_profit = 0 self.__idle_time = 0 self.__finish_trip_time = -1 def __str__(self): ret = "{" + str(self.__id) + ", " + str(self.__pos) + ", " + str( self.__status) + ", " + str(self.__trip_effort) + ", " ret = ret + str(self.__trip_profit) + ", " ret = ret + "Riders: " + self.showRidersOnBoard() + ", " ret = ret + "Route: " + self.showTripRoute() + "}" return ret def showRidersOnBoard(self): ret = "[" if len(self.__riders): for rider_id in OrderedDict( sorted(self.__riders.items(), key=lambda t: t[0])).keys(): ret = ret + rider_id + ", " ret = ret[0:len(ret) - 2] + "]" else: ret = ret + "]" return ret def showTripRoute(self): ret = "[" if len(self.__trip_route): for elem in self.__trip_route: ret = ret + str(elem.getZoneID()) + ", " ret = ret[0:len(ret) - 2] + "]" else: ret = ret + "]" return ret def getID(self): return self.__id def setRiders(self, riders): for rider_id, rider in riders.items(): self.__riders[rider_id] = rider def getRider(self, id): if id in self.__riders.keys(): return self.__riders[id] else: self.__logger.error(Driver.timestamp, "getRider", self.getID(), id, "Rider not in vehicle.") raise Exception("Rider not in vehicle.") def removeRider(self, id): if id in self.__riders.keys(): del self.__riders[id] else: self.__logger.error(Driver.timestamp, "removeRider", self.getID(), id, "Rider not in vehicle.") raise Exception("Rider not in vehicle.") def calcTripRoute(self): if len(self.__trip_route) == 0: route_strategy = RoutingInDistance(self.__riders, self.__trip_route) route_strategy.planRoute() else: self.__logger.error(Driver.timestamp, "calcTripRoute", self.getID(), None, "Trip route is empty.") raise Exception("Trip route is empty.") def popTripRoute(self): if len(self.__trip_route) > 0: return self.__trip_route.pop(0) else: self.__logger.error(Driver.timestamp, "popTripRoute", self.getID(), None, "Nothing to be poped.") raise Exception("Nothing to be poped.") def getTripRoute(self): return self.__trip_route #must calc route first def calcTripEffort(self): trip_time = 0 trip_effort = 0 pos = self.getPos() for elem in self.__trip_route: if Graph.queryTravelCost(pos, elem.getZoneID()) != 0: trip_effort = trip_effort + Graph.queryTravelCost( pos, elem.getZoneID()) else: trip_effort += 0.5 trip_time = trip_time + Graph.queryTravelCost( pos, elem.getZoneID()) elem.setEventTime(Driver.timestamp + trip_time) if elem.getEvent() == DROPOFF: rider = self.__riders[elem.getRiderID()] rider.setArrivalTimestamp(Driver.timestamp + trip_time) rider.calcDetourTime( trip_time ) #detour time is b/w the rerquest accepted and arrive at destination. pos = elem.getZoneID() if trip_effort < 0: self.__logger.warning(Driver.timestamp, "calcTripEffort", self.getID(), None, "Trip effort value is unresonable ") raise Exception("Trip effort value is unresonable ") else: self.__trip_effort += trip_effort def tickTripEffort(self): self.__trip_effort += 1 def getTripEffort(self): return self.__trip_effort def notifyRiderPrice(self): shared_number = len(self.__riders) for rider in self.__riders.values(): rider.calcPrice(shared_number) #must calc route effort and rider price first def calcTripProfit(self): trip_revenue = 0 if len(self.__riders) > 0: for rider in self.__riders.values(): if rider.getPrice() is not math.inf: trip_revenue += rider.getPrice() else: self.__logger.error(Driver.timestamp, "calcTripEffort", self.getID(), None, "Price value is unresonable ") raise Exception("Price value is unresonable ") self.__trip_profit += trip_revenue else: self.__logger.error(Driver.timestamp, "calcTripEffort", self.getID(), None, "No riders in vehicle.") raise Exception("No riders in vehicle.") def getTripProfit(self): return self.__trip_profit def setPos(self, zid): self.__pos = zid def getPos(self): return self.__pos def setStatus(self, status): self.__status = status def getStatus(self): return self.__status def tickIdleTime(self): self.__idle_time += 1 def getIdleTime(self): return self.__idle_time def setFinishTripTime(self, time): self.__finish_trip_time = time def getFinishTripTime(self): return self.__finish_trip_time
class Dispatcher: # Sync timestamp for logging timestamp = -1 def __init__(self): #logger in Dispatcher self.__logger = Logger('Dispatcher') self.__logger.setLevel(logging.DEBUG) self.__logger.info(Dispatcher.timestamp, "__INIT__", None, None, "Create A Dispatcher Object") #Storage for drivers and riders self.__driver_dict = {} self.__rider_wait_dict = {} self.__rider_serve_dict = {} self.__rider_finish_dict = {} self.__rider_cancel_dict = {} #Performance of driver and rider self.wait_rider={} self.no_work_driver={} self.idle_driver_before_match={} self.grp_in_4=0 self.grp_in_3=0 self.grp_in_2=0 self.grp_in_1=0 #Cluser Strategy self.__cluster_strategy = ClusteringByDir(self.__rider_wait_dict) #Matching Strategy self.__match_strategy = MatchingInQueue(self.__driver_dict, self.__rider_wait_dict, self.__rider_serve_dict) #Driver Status Tracker self.__driver_tracker = DriverStatusTracker(self.__driver_dict) #Rider Status tracker self.__rider_tracker = RiderStatusTracker(self.__rider_wait_dict, self.__rider_serve_dict, self.__rider_finish_dict, self.__rider_cancel_dict) #Driver Dict for zone_id in range(1,78): self.__driver_dict[zone_id] = {} #Rider Dict for zone_id in range(1,78): self.__rider_wait_dict[zone_id] = {} for dir_id in range(-1, 12): self.__rider_wait_dict[zone_id][dir_id] = defaultdict(dict) # for cycle in range(SIMULATION_CYCLE_START, SIMULATION_CYCLE_END): self.wait_rider[cycle] = [] self.no_work_driver[cycle] = [] for zone_id in range(0,78): self.wait_rider[cycle].append(0) self.no_work_driver[cycle].append(0) def showDriverDict(self, zone_id): ret = str(zone_id) + ": {" for driver_id in OrderedDict(sorted(self.__driver_dict[zone_id].items(), key=lambda t: t[0])).keys(): ret = ret + driver_id + ", " ret = ret + "}" return ret def getDriverFromDriverDict(self, zone_id, driver_id): for id, driver in self.__driver_dict[zone_id].items(): if id == driver_id: return driver return None def getDriverNumberOfZone(self, zone_id): return len(self.__driver_dict[zone_id]) def showRiderWaitDict(self, zone_id): ret = str(zone_id) + ": {" for dir_id in self.__rider_wait_dict[zone_id].keys(): ret = ret + str(dir_id) + ": {" for group_id in self.__rider_wait_dict[zone_id][dir_id].keys(): ret = ret + str(group_id) + ": [" for rider_id in OrderedDict(sorted(self.__rider_wait_dict[zone_id][dir_id][group_id].items(), key=lambda t: t[0])).keys(): ret = ret + str(rider_id) + ", " ret = ret + "], " ret = ret + "}, " ret = ret + "}" return ret def getRiderFromWaitDict(self, zone_id, dir_id, group_id, rider_id): for id, rider in self.__rider_wait_dict[zone_id][dir_id][group_id].items(): if id == rider_id: return rider return None def getGroupFromWaitDict(self, zone_id, dir_id, group_id): for id, group in self.__rider_wait_dict[zone_id][dir_id].items(): if id == group_id: return group return None def getRequestNumberOfZone(self, zone_id): total_num = 0 for dir_id in self.__rider_wait_dict[zone_id].keys(): for group_id in self.__rider_wait_dict[zone_id][dir_id].keys(): total_num += len(self.__rider_wait_dict[zone_id][dir_id][group_id]) return total_num def showRiderServedDict(self): ret = "{" for rider_id in OrderedDict(sorted(self.__rider_serve_dict.items(), key=lambda t: t[0])).keys(): ret=ret+str(rider_id)+", " ret=ret+"}" return ret def getRiderFromServedDict(self, rider_id): for id, rider in self.__rider_serve_dict.items(): if id == rider_id: return rider return None def showRiderFinishedDict(self): ret = "{" for rider_id in OrderedDict(sorted(self.__rider_finish_dict.items(), key=lambda t: t[0])).keys(): ret = ret + str(rider_id) + ", " ret = ret + "}" return ret def getRiderFromFinishedDict(self, rider_id): for id, rider in self.__rider_finish_dict.items(): if id == rider_id: return rider return None def showRiderCanceledDict(self): ret = "{" for rider_id in OrderedDict(sorted(self.__rider_cancel_dict.items(), key=lambda t: t[0])).keys(): ret = ret + str(rider_id) + ", " ret = ret + "}" return ret def getRiderFromCanceledDict(self, rider_id): for id, rider in self.__rider_cancel_dict.items(): if id == rider_id: return rider return None #put driver into Driver Dict at start def handleDriverIntoDict(self, driver): if isinstance(driver, Driver): if driver.getID() not in self.__driver_dict[driver.getPos()].keys(): self.__driver_dict[driver.getPos()][driver.getID()] = driver else: self.__logger.error(Dispatcher.timestamp, "handleDriverRequest", driver.getID(), None, "Driver has been in the Pool.") raise Exception("Driver has been in the Pool.") else: self.__logger.error(Dispatcher.timestamp, "handleDriverRequest", None, None, "Driver's type is wrong.") raise Exception("Driver's type is wrong.") def handleRiderIntoDict(self, rider): if isinstance(rider, Rider): self.__cluster_strategy.cluster(rider) else: self.__logger.error(Dispatcher.timestamp, "handleRiderRequest", None, None, "Rider's type is wrong.") raise Exception("Rider's type is wrong.") def matchRidertoDriver(self): for zone_id in self.__rider_wait_dict.keys(): for dir_id in self.__rider_wait_dict[zone_id].keys(): for group_id in self.__rider_wait_dict[zone_id][dir_id].copy().keys(): driver = self.__match_strategy.match(zone_id) if driver is not None: self.__logger.info(Dispatcher.timestamp, "matchRidertoDriver", driver.getID(), None, "Driver be Chosen to Serve Riders.") self.__logger.debug(Dispatcher.timestamp, "matchRidertoDriver", None, None, "Driver Zone ===> Rider Zone: ", str(driver.getPos()) + "===>" + str(zone_id)) # update driver status driver.setRiders(self.__rider_wait_dict[zone_id][dir_id][group_id]) self.__driver_tracker.updateDriverStatusAfterMatching(driver) self.__logger.debug(Dispatcher.timestamp, "matchRidertoDriver", driver.getID(), None, str(driver)) #update rider status if len(self.__rider_wait_dict[zone_id][dir_id][group_id]) == 4: self.grp_in_4 += 1 elif len(self.__rider_wait_dict[zone_id][dir_id][group_id]) == 3: self.grp_in_3 += 1 elif len(self.__rider_wait_dict[zone_id][dir_id][group_id]) == 2: self.grp_in_2 += 1 elif len(self.__rider_wait_dict[zone_id][dir_id][group_id]) == 1: self.grp_in_1 += 1 else: self.__logger.warning(Dispatcher.timestamp, "calcPoolingPerformanceInWaitDict", None, None, "Grp len is 0.") for rider in self.__rider_wait_dict[zone_id][dir_id][group_id].values(): self.__rider_tracker.updateRiderStatusAfterMatching(rider) self.__logger.debug(Dispatcher.timestamp, "matchRidertoDriver", driver.getID(), rider.getID(), str(rider)) del self.__rider_wait_dict[zone_id][dir_id][group_id] else: self.__logger.info(Dispatcher.timestamp, "matchRidertoDriver", None, None, "No Driver is available.") break def updateDriverInDict(self): for zone_id in self.__driver_dict.keys(): for driver in self.__driver_dict[zone_id].copy().values(): if driver.getStatus() == IDLE: self.__logger.info(Dispatcher.timestamp, "updateDriverStatus", driver.getID(), None, "Update Driver when IDLE.") self.__driver_tracker.updateDriverStatusWhenIdle(driver, self.no_work_driver) elif driver.getStatus() == INSERVICE: self.__logger.info(Dispatcher.timestamp, "updateDriverStatus", driver.getID(), None, "Update Driver Who is INSERVICE.") self.__driver_tracker.updateDriverStatusWhenInService(driver, self.__rider_tracker) self.__logger.debug(Dispatcher.timestamp, "updateDriverStatus", driver.getID(), None, str(driver)) else: self.__logger.error(Dispatcher.timestamp, "updateDriverStatus", driver.getID(), None, "Driver Status is Wrong.") raise Exception("Driver Status is Wrong.") def updateRidersInWaitDict(self): for zone_id in self.__rider_wait_dict.keys(): for dir_id in self.__rider_wait_dict[zone_id].keys(): for group_id in self.__rider_wait_dict[zone_id][dir_id].copy().keys(): for rider in self.__rider_wait_dict[zone_id][dir_id][group_id].copy().values(): if rider.getStatus() == WAITING: self.__rider_tracker.updateRiderStatusWhenWait(rider, self.wait_rider) self.__rider_tracker.checkRiderStatusIfTimeOut(rider) def countTotalDriverNumber(self): total_len = 0 for zone_id in self.__driver_dict.keys(): total_len = total_len + len(self.__driver_dict[zone_id]) return total_len def countDriverNumberEachZone(self): self.idle_driver_before_match[Dispatcher.timestamp] = [0] for zone_id in self.__driver_dict.keys(): cnt=0 for driver in self.__driver_dict[zone_id].values(): if driver.getStatus() == IDLE: cnt+=1 self.idle_driver_before_match[Dispatcher.timestamp].append(cnt) def countRiderNumberInWaitDict(self): total_len = 0 for zone_id in self.__rider_wait_dict.keys(): for dir_id in self.__rider_wait_dict[zone_id].keys(): for group_id in self.__rider_wait_dict[zone_id][dir_id].keys(): total_len = total_len + len(self.__rider_wait_dict[zone_id][dir_id][group_id]) return total_len def countRiderNumberInServeDict(self): return len(self.__rider_serve_dict) def countRiderNumberInFinishDict(self): return len(self.__rider_finish_dict) def countRiderNumberInCancelDict(self): return len(self.__rider_cancel_dict) def countCurrentTotalRiderNumber(self): return self.countRiderNumberInWaitDict() + self.countRiderNumberInServeDict() + self.countRiderNumberInFinishDict() + self.countRiderNumberInCancelDict() def calcAverageProfitOfDrivers(self): totalProfit = 0 for zone_id in self.__driver_dict.keys(): for driver in self.__driver_dict[zone_id].values(): totalProfit += driver.getTripProfit() return totalProfit / self.countTotalDriverNumber() def calcAverageIdleTimeOfDrivers(self): totalIdleTime = 0 for zone_id in self.__driver_dict.keys(): for driver in self.__driver_dict[zone_id].values(): totalIdleTime += driver.getIdleTime() return totalIdleTime / self.countTotalDriverNumber() def calcAverageTripEffortOfDrivers(self): totalTripEffort = 0 for zone_id in self.__driver_dict.keys(): for driver in self.__driver_dict[zone_id].values(): totalTripEffort += driver.getTripEffort() return totalTripEffort / self.countTotalDriverNumber() def calcAverageWaitTimeOfRiders(self): totalWaitTime = 0 riders = {**self.__rider_serve_dict, **self.__rider_finish_dict, **self.__rider_cancel_dict} for rider in riders.values(): totalWaitTime +=rider.getWaitTime() return totalWaitTime/(self.countRiderNumberInFinishDict()+self.countRiderNumberInServeDict()+self.countRiderNumberInCancelDict()) def calcAverageDetourTimeOfRiders(self): totalDetourTime = 0 riders = {**self.__rider_serve_dict, **self.__rider_finish_dict} for rider in riders.values(): totalDetourTime += rider.getDetourTime() return totalDetourTime/(self.countRiderNumberInFinishDict()+self.countRiderNumberInServeDict()) def calcAverageFareOfRiders(self): totalFare = 0 riders = {**self.__rider_serve_dict, **self.__rider_finish_dict} for rider in riders.values(): totalFare += rider.getPrice() return totalFare/(self.countRiderNumberInFinishDict()+self.countRiderNumberInServeDict()) def calcAverageDefaultFareRiders(self): totalDefaultFare = 0 riders = {**self.__rider_serve_dict, **self.__rider_finish_dict} for rider in riders.values(): totalDefaultFare += rider.getDefaultPrice() return totalDefaultFare/(self.countRiderNumberInFinishDict()+self.countRiderNumberInServeDict()) def calcAverageSatOfRiders(self): totalSat = 0 riders = {**self.__rider_serve_dict, **self.__rider_finish_dict, **self.__rider_cancel_dict} for rider in riders.values(): totalSat += rider.getSat() return totalSat/(self.countRiderNumberInFinishDict()+self.countRiderNumberInServeDict()+self.countRiderNumberInCancelDict())