def runOnce(self): db = DB() # Setting the start time boundary of request that we want startTime = datetime.datetime.combine(Fitness.yesterday, datetime.datetime.strptime(Fitness.firstMinute, Fitness.formatTime).time()) # Setting the end time boundary of request that we want endTime = datetime.datetime.combine(Fitness.yesterday, datetime.datetime.strptime(Fitness.lastMinute, Fitness.formatTime).time()) # Create index for the people going on the bus Fitness.request = db.grpReqByBusstopAndTime(startTime, endTime) self.createRequestIndex(Fitness.request) # Create index for the people going down the bus Fitness.requestOut = db.getReqCountByEndBusStop(startTime, endTime) self.createRequestIndexOut(Fitness.requestOut) #<--------------------------------Functions for new encoding including multiple line----------------------------------> busLines = set(db.busLine) for line in busLines: for x in db.timeSliceArray: start = datetime.datetime.combine(Fitness.yesterday,datetime.time(x[0], 0, 0)) end = datetime.datetime.combine(Fitness.yesterday, datetime.time(x[1], 59, 59)) requestBetweenTimeSlices = db.getTravelRequestBetween(start, end, line) for count in enumerate(requestBetweenTimeSlices, start=1): countingNoOfRequest = (count[0]) try: finalNoReqBetweenTimeSlice = countingNoOfRequest except: print("No requests found for the particular date you desire") Fitness.totalRequestsBusline[(line, start, end)] = finalNoReqBetweenTimeSlice
def evalIndividual(self, individual): ''' Evaluate an individual in the population. Based on how close the average bus request time is to the actual bus trip time. @param an individual in the population @return a summation of the difference between past past requests' average trip starting time and actual start time according to the evolving timetable. Lower values are better. ''' self.runOnce() # DONE Store the date on mongo as datetime # Store the requests of the previous day into a JSON file order them by date and KEEP IT during the whole iteration on memory # DONE Group by request query from the file to reduce the number of elements being processed # Use map function instead of LOOP # Multi thread the MAP functions # First, the randomly-generated starting times are sorted in order to check sequentially the number of requests for that particular trip individual = sorted(individual, key=itemgetter(2)) # Second, we loop trough the number of genes in order to retrieve the number of requests for that particular trip # DB calls can ve avoided by querying the whole Request Collection for a particular day # For the 1st trip, the starting time has to be selected db = DB() # Replace the dates here from yesterday's date request = [] dif = [] cnt = [] intialTripTime = "00:00" # TODO: Change to timedelta(1) yesterday = date.today() - timedelta(2) # The result here should be added into a file: the order is by hour, minute and initialBusStop # request = db.getTravelRequestSummary(datetime.combine(yesterday, datetime.strptime(Fitness.firstMinute, Fitness.formatTime).time()),datetime.combine(yesterday, datetime.strptime(Fitness.lastMinute, Fitness.formatTime).time())) for i in range(len(individual)): tripTimeTable = [] tripTimeTable = db.generateFitnessTripTimeTable(individual[i][0], individual[i][2]) # For each gene, the corresponding requests are returned for j in range(len(tripTimeTable)): request = [] if j==0: request = db.getTravelRequestSummary2(datetime.combine(yesterday, datetime.strptime(intialTripTime, Fitness.formatTime).time()),datetime.combine(yesterday, datetime.strptime(tripTimeTable[j][1], Fitness.formatTime).time()), tripTimeTable[j][0]) intialTripTime = tripTimeTable[j][1] else: request = db.getTravelRequestSummary2(datetime.combine(yesterday, datetime.strptime(tripTimeTable[j-1][1], Fitness.formatTime).time()),datetime.combine(yesterday, datetime.strptime(tripTimeTable[j][1], Fitness.formatTime).time()), tripTimeTable[j][0]) if len(request)>0: diff = 0 count = 0 for k in range(len(request)): diff = diff + self.getMinutes(self.timeDiff(tripTimeTable[j][1],str(int(request[k]["hour"])) + ":" + str(int(request[k]["minute"]))))*int(request[k]["count"]) count = count + int(request[k]["count"]) dif.append(diff) cnt.append(count) return sum(dif)/sum(cnt),
def insertWeather(self, address, apiKey, days): """ Calls API to get weather information """ db = DB() coordinates = self.getCoordinates(address) forecast = self.getWeatherHourly(self.callWeatherAPI(apiKey, coordinates[0], coordinates[1])) for data in forecast.data: if data.time.date() == self.setQueryDay(days): weather = {'icon': data.icon, 'time': data.time, 'temperature': data.temperature} db.insertWeather(weather)
def runOnce(self): db = DB() # Setting the start time boundary of request that we want startTime = datetime.datetime.combine(Fitness.yesterday, datetime.datetime.strptime(Fitness.firstMinute, Fitness.formatTime).time()) endTime = datetime.datetime.combine(Fitness.yesterday, datetime.datetime.strptime(Fitness.lastMinute, Fitness.formatTime).time()) # Create index for the people going on the bus Fitness.request = db.grpReqByBusstopAndTime(startTime, endTime) self.createRequestIndex(Fitness.request) # Create index for the people going down the bus Fitness.requestOut = db.getReqCountByEndBusStop(startTime, endTime) self.createRequestIndexOut(Fitness.requestOut) '''
def modifyTimeTable(self, trip): timetable = [] busId = [] busTrip = [] db = DB() for i in xrange(len(trip)): for j in trip[i][3]: busTrip.append([j["line"], j["_id"]]) busTrip = sorted(busTrip, key=itemgetter(0)) line = busTrip[0][0] busId.append(busTrip[0][1]) for i in xrange(1, len(busTrip)): if line != busTrip[i][0]: timetable = db.selectTimeTablebyBusTrip(busId) newTimetable = self.generateTimetable(timetable, busId) db.updateTimetable(newTimetable[0], newTimetable[1], newTimetable[2], newTimetable[3]) self.deleteBusTrip(newTimetable[3]) # notifyUsers(timetable2[1]) busId = [] line = busTrip[i][0] busId.append(busTrip[i][1]) timetable = db.selectTimeTablebyBusTrip(busId) newTimetable = self.generateTimetable(timetable, busId) db.updateTimetable(newTimetable[0], newTimetable[1], newTimetable[2], newTimetable[3]) self.deleteBusTrip(newTimetable[3])
def getAffectedTrip(self, weather, conditions): """ Looks trips on DB that are gonna be affected by the weather """ trip = [] db = DB() # Running trough the weather for i in weather: # Search for pre defined special weather conditions # This can be a function that evaluates temperature and time if self.evaluateWeather(i["icon"], i["temperature"], i["time"], conditions): # Query related trips between i["time"] and an hour later trips = db.selectBusTrip(i["time"]) # Append them on the trips array trip.append([i["icon"], i["temperature"], i["time"], trips]) return trip
def insertWeather(self, address, apiKey, days): """ Calls API to get weather information """ db = DB() coordinates = self.getCoordinates(address) forecast = self.getWeatherHourly( self.callWeatherAPI(apiKey, coordinates[0], coordinates[1])) for data in forecast.data: if data.time.date() == self.setQueryDay(days): weather = { 'icon': data.icon, 'time': data.time, 'temperature': data.temperature } db.insertWeather(weather)
def runOnce(self): db = DB() request = [] # DB calls can ve avoided by querying the whole Request Collection for a particular day getTravelRequests = db.getTravelRequest # Replace the dates here from yesterday's date yesterday = date.today() + timedelta(1) # The result here should be added into a file: the order is by hour, minute and initialBusStop request = db.getTravelRequestSummary(datetime.combine(yesterday, datetime.strptime(Fitness.firstMinute, Fitness.formatTime).time()), datetime.combine(yesterday, datetime.strptime(Fitness.lastMinute, Fitness.formatTime).time()))
def runOnce(self): db = DB() # Setting the start time boundary of request that we want startTime = datetime.datetime.combine( Fitness.yesterday, datetime.datetime.strptime(Fitness.firstMinute, Fitness.formatTime).time()) endTime = datetime.datetime.combine( Fitness.yesterday, datetime.datetime.strptime(Fitness.lastMinute, Fitness.formatTime).time()) # Create index for the people going on the bus Fitness.request = db.grpReqByBusstopAndTime(startTime, endTime) self.createRequestIndex(Fitness.request) # Create index for the people going down the bus Fitness.requestOut = db.getReqCountByEndBusStop(startTime, endTime) self.createRequestIndexOut(Fitness.requestOut) '''
def generateBusTrip(self, trip): fitness = Fitness() db = DB() line = 0 count = 0 chromosome = [] for tripInstance in trip: for busInstance in tripInstance[3]: if line != busInstance["line"] and count != 0: chromosome.append([line, capacity, self.calculateFrequency(count), startTime]) count = 0 if count == 0: capacity = busInstance["capacity"] startTime = busInstance["startTime"] line = busInstance["line"] count += 1 chromosome.append([line, capacity, self.calculateFrequency(count), startTime]) individual = fitness.genTimetable(chromosome) db.insertBusTrip2(individual)
def evalIndividualCapacity(self, individual): ''' Evaluates an individual based on the capacity/bus type chosen for each trip. @param: individual - a possible timetable for a bus line, covering the whole day. @return: a fitness score assigned in accordance with how close the requested capacity is to the availed capacity on the individual ''' individual.sort(key = itemgetter(2)) db = DB() requests = db.getRequestsFromDB() requests[:] = [request.time() for request in requests if request is not None] fitnessVal = 0 # assumed initial fitness value TODO: put as class variable for trip, item in enumerate(individual): nrReqs = [] if trip == 0: start = datetime.strptime('00:00', '%H:%M').time() end = datetime.strptime(individual[0][2], '%H:%M').time() nrReqs = [i for i in requests if i > start and i <= end] # Assign fitness values if len(nrReqs) == individual[trip][1]: fitnessVal += 0 elif len(nrReqs) < individual[trip][1]: fitnessVal += 1 else: fitnessVal += 1000000 else: start = datetime.strptime(individual[trip-1][2], '%H:%M').time() end = datetime.strptime(individual[trip][2], '%H:%M').time() nrReqs = [i for i in requests if i > start and i <= end] # Assign fitness values if len(nrReqs) == individual[trip][1]: fitnessVal += 0 elif len(nrReqs) < individual[trip][1]: fitnessVal += 1 else: fitnessVal += 1000000 return fitnessVal
def main(): # Generate the population pop = toolBox.toolbox.population(n=POPULATION_SIZE) hof = tools.HallOfFame(1) stats = tools.Statistics(lambda ind: ind.fitness.values) stats.register("avg", numpy.mean) stats.register("std", numpy.std) stats.register("min", numpy.min) stats.register("max", numpy.max) pop, log = algorithms.eaSimple(pop, toolBox.toolbox, cxpb=CROSS_OVER_PROB, mutpb=MUTATION_PROB, ngen=NO_OF_GENERATION, stats=stats, halloffame=hof, verbose=True) ## Evaluate the entire population #fitnesses = list(map(toolBox.toolbox.evaluate, pop)) #for ind, fit in zip(pop, fitnesses): # ind.fitness.values = fit # Iterate trough a number of generations # for g in range(NGEN): # print("-- Generation %i --" % g) # # Select individuals based on their fitness # offspring = toolBox.toolbox.select(pop, len(pop)) # # Cloning those individuals into a new population # offspring = list(map(toolBox.toolbox.clone, offspring)) # # Calling the crossover function # crossover(offspring) # mutation(offspring) # invalidfitness(offspring) # The Best Individual found best_ind = tools.selBest(pop, 1)[0] individual = sorted(best_ind, key=itemgetter(3)) individual = sorted(individual, key=itemgetter(0)) #print "InsertBusTrip and TimeTable......" print("Best individual is %s, %s" % (individual, best_ind.fitness.values)) print("Length of best individual: " + str(len(best_ind))) fitnessClass = Fitness() timetable = fitnessClass.genTimetable(best_ind) databaseClass = DB() #databaseClass.insertBusTrip(timetable) evaluate_timetable.eval(best_ind)
def generateBusTrip(self, trip): fitness = Fitness() db = DB() line = 0 count = 0 chromosome = [] for tripInstance in trip: for busInstance in tripInstance[3]: if line != busInstance["line"] and count != 0: chromosome.append([ line, capacity, self.calculateFrequency(count), startTime ]) count = 0 if count == 0: capacity = busInstance["capacity"] startTime = busInstance["startTime"] line = busInstance["line"] count += 1 chromosome.append( [line, capacity, self.calculateFrequency(count), startTime]) individual = fitness.genTimetable(chromosome) db.insertBusTrip2(individual)
def generateTimeTable(individual): databaseClass = DB() timetable = databaseClass.generateTripTimeTable(individual) databaseClass.insertTimeTable(timetable)
import numpy import toolBox from deap import tools from deap import algorithms from dbConnection import DB from operator import itemgetter from fitness import Fitness from dbConnection import DB # Variables MUTATION_PROB = 0.5 CROSS_OVER_PROB = 1 NO_OF_GENERATION = 2 POPULATION_SIZE = 10 fitnessClass = Fitness() databaseClass = DB() def main(): # Generate the population pop = toolBox.toolbox.population(n=POPULATION_SIZE) hof = tools.HallOfFame(1) stats = tools.Statistics(lambda ind: ind.fitness.values) stats.register("avg", numpy.mean) stats.register("std", numpy.std) stats.register("min", numpy.min) stats.register("max", numpy.max) pop, log = algorithms.eaSimple(pop, toolBox.toolbox, cxpb=CROSS_OVER_PROB, mutpb=MUTATION_PROB,
def evaluateNewIndividualFormat(individual): ''' Fitness function that evaluates and each individual in the population and assigns a fitness value to it which is the average waiting time for the individual (i.e a timetable) @param: individual - encoded individual which represents an timetable for mulitple lines. ''' individual = sorted(individual, key=itemgetter(3)) individual = sorted(individual, key=itemgetter(0)) # Second, we loop trough the number of genes in order to retrieve the # number of requests for that particular trip # For the 1st trip, the starting time has to be selected request = [] totalWaitingMinutes = [] cnt = [] db = DB() # ---------------------------------------------------- # Evaluate average time based on requests (& capacity) # ---------------------------------------------------- leftOver = [] l = len(db.timeSliceArray) - 1 startT = datetime.datetime.combine(Fitness.yesterday, datetime.time(db.timeSliceArray[l][0], 0, 0)) endT = datetime.datetime.combine(Fitness.yesterday, datetime.time(db.timeSliceArray[l][1], 59, 59)) firstSliceHr = datetime.datetime.combine(Fitness.yesterday, datetime.time(db.timeSliceArray[0][0], 0, 0)) for i in range(len(individual)): phenotype = db.generatePhenotype(individual[i][0], individual[i][3]) initialCrew = 0 leftOvers = 0 leftOversWaitTime = 0 firstHrOfTimeSlice, LastHrOfTimeSlice = fitnessClass.getTimeSlice(individual[i][3]) diffToFirstHrSlice = individual[i][3] - firstHrOfTimeSlice diffToFirstHrSlice = diffToFirstHrSlice.days * databaseClass.minutesDay + diffToFirstHrSlice.seconds / databaseClass.minutesHour diffToLastHrSlice = LastHrOfTimeSlice - individual[i][3] diffToLastHrSlice = diffToLastHrSlice.days * databaseClass.minutesDay + diffToLastHrSlice.seconds / databaseClass.minutesHour backTrips = round(float(diffToFirstHrSlice)/float(individual[i][2])) forwardTrips = round(float(diffToLastHrSlice)/float(individual[i][2])) noOfTrips = backTrips + forwardTrips + 1 for key in fitnessClass.totalRequestsBusline: if individual[i][0] == key[0] and (key[1] <= individual[i][3] <= key[2]): totalCapacityInSlice = noOfTrips * individual[i][1] initialCrew = fitnessClass.totalRequestsBusline[key] try: if (initialCrew >totalCapacityInSlice ): leftOvers = initialCrew - totalCapacityInSlice if (individual[i][3] + timedelta(minutes=individual[i][2]) > endT): timed = (endT - individual[i][3]) + timedelta(hours=db.timeSliceArray[0][0]) timed = (timed.days * databaseClass.minutesDay) + (timed.seconds / databaseClass.minutesHour) timed = timed * leftOvers leftOver.append([timed, leftOvers]) else: timed = (individual[i][2]) * leftOvers leftOver.append([timed, leftOvers]) except IndexError: print("Error") for j in range(len(phenotype)): # TODO: Fix trips that finish at the next day deprtTimeBusStop = phenotype[j][1] # Search on Fitness.request array for the all request made in a slice for a particular busStop and Line request = fitnessClass.searchRequest(firstHrOfTimeSlice, LastHrOfTimeSlice, phenotype[j][0], individual[i][0]) if len(request) > 0: waitingMinutes = 0 count = 0 for k in range(len(request)): requestTime = request[k]["_id"]["RequestTime"] # Senario 1 - When the request time made is after the starting time provided in the GENE # i.e people who can NOT make it. if requestTime > deprtTimeBusStop: difference = requestTime-deprtTimeBusStop difference = difference.days * databaseClass.minutesDay + difference.seconds / databaseClass.minutesHour noOfTimesToGoForwardOnClock = math.ceil(float(difference)/float(individual[i][2])) if noOfTimesToGoForwardOnClock == 1: newTripToTake = deprtTimeBusStop + timedelta(minutes=individual[i][2]) waitingTime = (newTripToTake - requestTime) waitingMinutes = waitingTime.days * databaseClass.minutesDay + waitingTime.seconds / databaseClass.minutesHour else: totalMinToGoForwardOnClock = noOfTimesToGoForwardOnClock * individual[i][2] newTripToTake = deprtTimeBusStop + timedelta(minutes=totalMinToGoForwardOnClock) waitingTime = (newTripToTake - requestTime) waitingMinutes = waitingTime.days * databaseClass.minutesDay + waitingTime.seconds / databaseClass.minutesHour # Senario 2 - When the request time made is before the starting time provided in the GENE # i.e people who can make it. else: difference = deprtTimeBusStop-requestTime difference = difference.days * databaseClass.minutesDay + difference.seconds / databaseClass.minutesHour noOfTimesToGoBackOnClock = math.floor(float(difference)/float(individual[i][2])) if noOfTimesToGoBackOnClock == 0: waitingTime = (deprtTimeBusStop - requestTime) waitingMinutes = waitingTime.days * databaseClass.minutesDay + waitingTime.seconds / databaseClass.minutesHour else: totalMinToGoBackOnClock = noOfTimesToGoBackOnClock * individual[i][2] newTripToTake = deprtTimeBusStop - timedelta(minutes=totalMinToGoBackOnClock) waitingTime = (newTripToTake - requestTime) waitingMinutes = waitingTime.days * databaseClass.minutesDay + waitingTime.seconds / databaseClass.minutesHour count = count + int(request[k]["total"]) waitingMinutes = waitingMinutes * request[k]["total"] totalWaitingMinutes.append(waitingMinutes) # The cnt array consists of the number of requests made for a particular request time # eg. 3 people made a request to leave at 4:30 cnt.append(count) totalLeftOverTime = 0 noOfLeftOvers = 0 for k in range(len(leftOver)): totalLeftOverTime += leftOver[k][0] noOfLeftOvers += leftOver[k][1] totalWaitingTime = sum(totalWaitingMinutes) + totalLeftOverTime averageWaitingTime = totalWaitingTime / (sum(cnt) + noOfLeftOvers) return averageWaitingTime,
def evaluateNewIndividualFormat(individual): """ Evaluate an individual's fitness as a candidate timetable for the bus network. An individual's fitness is evaluated based on the waiting time for passengers requesting buses for the lines represented in the individual. Shorter waiting times on average mean better solutions. The algorithm works by by first sorting the individual by starting times, grouped by the bus lines. Args: individual: an individual represented as [[lineID, Capacity, frequency, startTime]...] Return: a fitness score calculated as a cost to the bus company. """ totalWaitingMinutes = [] totalNumberRequests = [] leftOver = [] db = DB() # Order individual by starting slice time individual = sorted(individual, key=itemgetter(3)) # Order individual by bus line individual = sorted(individual, key=itemgetter(0)) # ------------------------------------------------------------ # Evaluate average time based on requests & bus capacity # ------------------------------------------------------------ # Get the starting time for the 1st slice firstSliceHr = datetime.datetime.combine(Fitness.yesterday, datetime.time(db.timeSliceArray[0][0], 0, 0)) # Initialize initial trip time initialTripTime = firstSliceHr print individual for i in range(len(individual)): # phenotype = db.generatePhenotype(individual[i][0], individual[i][3]) phenotype = db.generatePhenotype2(individual[i]) initialCrew = 0 leftOvers = 0 # ------------------------------------------------------ # Evaluate average time and capacity for each gene now # ------------------------------------------------------ for j in range(len(phenotype)): for k in range(len(phenotype[j])): # Define parameters for the first search initialTrip = initialTripTime lastTrip = phenotype[j][k][1] # This is a restriction, so the search is not incoherent if initialTrip > lastTrip: initialTrip = lastTrip - timedelta(minutes=individual[i][2]) # Search on requests from people going in and out of the bus request = fitnessClass.searchRequest(initialTrip, lastTrip, phenotype[j][k][0], individual[i][0]) requestOut = fitnessClass.searchRequestOut(initialTrip, lastTrip, phenotype[j][k][0], individual[i][0]) # TODO: Replace the length by the sum of the number of requests # Calculate the number of people that is left on the bus initialCrew = initialCrew + (len(request) - len(requestOut)) # Compare the crew against the capacity, if it is higher then the waiting time based on capacity is calculated if(initialCrew > individual[i][1]): # People that did not make it !! leftOvers = initialCrew - individual[i][1] # Total waiting time is number of people left times waiting time in minutes if i < len(phenotype[j])-1: # Send next gene and bus stop leftOversWaitTime = leftOvers * individual[i][2] else: # Heuristic, computation of this would result really expensive leftOversWaitTime = leftOvers * db.minutesHour leftOver.append([leftOvers,leftOversWaitTime]) # Assign the last trip value to the initial trip initialTripTime = phenotype[j][k][1] if len(request) > 0: waitingMinutes = 0 numberRequests = 0 for l in range(len(request)): waitingTime = phenotype[j][k][1] - request[l]["_id"]["RequestTime"] waitingMinutes = waitingMinutes + round(((waitingTime.total_seconds() % 3600) / databaseClass.minutesHour), 2) numberRequests = numberRequests + int(request[l]["total"]) totalWaitingMinutes.append(waitingMinutes) totalNumberRequests.append(numberRequests) # Summarize the results # Initialize total variable totalLeftOverTime = 0 #noOfLeftOvers = 0 # Loop trough leftovers array for z in range(len(leftOver)): # Summarize the waiting time for all the leftovers in every bus stop totalLeftOverTime += leftOver[z][1] #noOfLeftOvers += leftOver[z][0] # Summarize the waiting times based on requests and based on capacity totalWaitingTime = sum(totalWaitingMinutes) + totalLeftOverTime #averageWaitingTime = totalWaitingTime / (sum(totalNumberRequests) + noOfLeftOvers) return fitnessClass.calculateCost(individual, totalWaitingTime, 0),
def queryWeather(self, date): """ """ db = DB() return db.selectWeather(date)
def deleteBusTrip(self, busTrip): db = DB() for bt in busTrip: db.deleteBusTrip(bt)
class DynamicRoutes(): # --------------------------------------------------------------------------------------------------------------------------------------- # INDEX # --------------------------------------------------------------------------------------------------------------------------------------- # Class variables # Constructor # Create Graph # Generate Dynamic Routes # Store Dynamic Routes into Database # --------------------------------------------------------------------------------------------------------------------------------------- # Class variables # --------------------------------------------------------------------------------------------------------------------------------------- server = "130.238.15.114" port = 27017 database = "monad1" user = "******" password = "******" dbClass = DB() # --------------------------------------------------------------------------------------------------------------------------------------- # Constructor # --------------------------------------------------------------------------------------------------------------------------------------- def __init__(self): self.client = MongoClient("mongodb://" + self.user + ":" + self.password + "@" + self.server, self.port, maxPoolSize=200, connectTimeoutMS=5000, serverSelectionTimeoutMS=5000) self.db = self.client[DB.database] # --------------------------------------------------------------------------------------------------------------------------------------- # Create Graph # --------------------------------------------------------------------------------------------------------------------------------------- def creategraph(self): ''' create the Uppsala city graph from database of connected bus stops :return: graph ''' DG = nx.DiGraph() collections = self.client.monad1.RouteGraph.find() for col in collections: if col['_id'] not in DG: DG.add_node(col['orgBusName'], name = col['_id']) for c in col['connectedBusStop']: if c['_id'] not in DG: DG.add_node(c['busStop'], name = c['_id']) DG.add_weighted_edges_from([(col['orgBusName'], c['busStop'], c['distance'])]) DG.add_weighted_edges_from([(col['orgBusName'], c['busStop'], c['distance'])]) return DG # --------------------------------------------------------------------------------------------------------------------------------------- # Generate Dynamic Routes # --------------------------------------------------------------------------------------------------------------------------------------- def generateRoutes(self, DG, start_date, end_date): ''' generate dynamic routes for Uppsala city based on users requests between start and end date :param DG: city graph :param start_date: start date for requests :param end_date: end date for requests :return:list of routes which serve all requests all routes start from central station and end in central station ''' routes =[] routebusstopsdic ={} index = 0 routesid =[] tempids=[] bus_allocated = 0 busStops = self.client.monad1.BusStop.find() for stop in busStops: routebusstopsdic[stop['name']] = index index += 1 tmatrix = numpy.zeros((busStops.count(), busStops.count()), dtype=numpy.int) reqs = self.dbClass.getRequestsFromDB(start_date, end_date) for req in reqs: i = routebusstopsdic[self.dbClass.getBusStopName(req[1])] j = routebusstopsdic[self.dbClass.getBusStopName(req[2])] if i != j: tmatrix[j][i] += 1 else: tmatrix[j][i] = 0 maxnumber = max(map(max, tmatrix)) while maxnumber > 0: maxnumber = max(map(max, tmatrix)) indx = numpy.where(tmatrix == maxnumber) Start_bus_stop = [key for key, value in routebusstopsdic.iteritems() if value == indx[0][0]] End_bus_stop = [key2 for key2, value in routebusstopsdic.iteritems() if value == indx[1][0]] try: if Start_bus_stop[0]!=End_bus_stop[0]: bus_stops1 = nx.astar_path(DG, "Centralstationen", Start_bus_stop[0]) bus_stops2 = nx.astar_path(DG, Start_bus_stop[0], End_bus_stop[0], heuristic=None, weight='distance') bus_stops3 = nx.astar_path(DG, End_bus_stop[0], "Centralstationen") bus_stops = bus_stops1+bus_stops2 +bus_stops3 getin = 0 getout = 0 nbusstops = [bus_stops[0]] intrip = [] outtrip = [] for i in range(1, len(bus_stops)): if bus_stops[i-1] != bus_stops[i]: nbusstops.append(bus_stops[i]) routes.append(nbusstops) for i in range(0, len(nbusstops)): getin = 0 getout = 0 for j in range(i, len(nbusstops)): getin += tmatrix[routebusstopsdic[nbusstops[i]]][routebusstopsdic[nbusstops[j]]] intrip.append([nbusstops[i], nbusstops[j], getin]) for l in range(0, i+1): getout += tmatrix[routebusstopsdic[nbusstops[l]]][routebusstopsdic[nbusstops[i]]] buscapacity = 100 temp =[] bus_free=100 for k in range(0, len(intrip)): if intrip[k][2] > 0 and bus_free > 0: if bus_free >= intrip[k][2]: bus_free = bus_free - intrip[k][2] intrip[k][2] = 0 tmatrix[routebusstopsdic[intrip[k][0]]][routebusstopsdic[intrip[k][1]]] = 0 bus_allocated =bus_allocated + bus_free else: bus_free = 0 intrip[k][2] =intrip[k][2] - bus_free tmatrix[routebusstopsdic[intrip[k][0]]][routebusstopsdic[intrip[k][1]]] = tmatrix[routebusstopsdic[intrip[k][0]]][routebusstopsdic[intrip[k][1]]] - bus_free bus_allocated = bus_allocated + bus_free temp.append([intrip[k][1], bus_free]) if intrip[k][0] in temp: bus_free += temp[1] bus_allocated =100 - bus_free except:nx.NetworkXNoPath client = MongoClient() client = MongoClient('130.238.15.114',27017) for i in routes: for j in range(0, len(i)): temp = client.monad1.BusStop.find_one({"name": i[j]}) tempids.append(temp['_id']) routesid.append(tempids) tempids = [] return routesid # --------------------------------------------------------------------------------------------------------------------------------------- # store Dynamic Routes to database # --------------------------------------------------------------------------------------------------------------------------------------- def storeRoutesToDB(self,routes): '''store routes(a bus stop id list) from generateRoutes into DB, should be written to collection Routes for timebeing, it be stored into DynamicRoute for testing @param: routes: a list of new dynamic routes in list of bus stop id output: new route will be written into DynamicRoute ''' duration = 0 line = 1 trajectory = [] tmpList = [] todayDate = datetime.datetime.now() today = datetime.datetime(todayDate.year, todayDate.month, todayDate.day) todayRoute = self.dbClass.db.dynamicRoute.find({'date': today}) dictKey = ['interval', 'busStop'] if todayRoute.count() == 0: print 'todays route is writing......' for i in range(len(routes)): for j in range(len(routes[i])): if j == 0: tmpList.append(0) else: adjointBusStopList = [(self.dbClass.getBusStopLongitudeByID(routes[i][j]), self.dbClass.getBusStopLatitudebyID(routes[i][j])), \ (self.dbClass.getBusStopLongitudeByID(routes[i][j-1]), self.dbClass.getBusStopLatitudebyID(routes[i][j-1]))] adjointBusStopRoute = get_route(adjointBusStopList) interval = int(math.ceil(float(adjointBusStopRoute['cost'][1])/float(self.dbClass.minutesHour))) tmpList.append(interval) duration += interval tmpList.append(routes[i][j]) trajectoryDict = dict(zip(dictKey, tmpList)) tmpList = [] trajectory.append(trajectoryDict) objID = ObjectId() route = {"_id": objID, "trajectory": trajectory, "date": today, "duration": duration, "line": line} self.dbClass.db.DynamicRoute.insert_one(route) line += 1 duration = 0 tmpList = [] trajectory = [] def dynamicRoutesGenerator(self): DG = self.creategraph() #define a test date bound startdate = datetime.datetime(2015, 11, 11, 0, 0, 0) enddate = datetime.datetime(2015, 11, 12, 0, 0, 0) routes = self.generateRoutes(DG, startdate, enddate) self.storeRoutesToDB(routes)