def main(): """ Method used for testing the performance and the correctness of the implemented A* and BFS algorithms along with the parsers. Comment / Uncomment code to test different features of the software. """ # Load the information of the city train_parser = CityInfoParser() train_parser.loadFile(CITY_INFO_PATH) train_parser.parse() train_parser.setDistances() train_info = train_parser.info distances = train_parser.distances # Load the information of the troleibus (distances are the same as the train) bus_parser = CityInfoParser() bus_parser.loadFile(TROLEI_BUS_INFO_PATH) bus_parser.parse() bus_info = bus_parser.info # Load the information of the train costs matrix_parser = AdjacencyMatrixParser() matrix_parser.loadFile(MA_PATH) matrix_parser.parse() train_costs = matrix_parser.values matrix_parser.closeFile() # Load info of the troleibus costs matrix_parser.loadFile(TROLEI_BUS_MA_PATH) matrix_parser.parse() bus_costs = matrix_parser.values matrix_parser.closeFile() # Open an instance of cost manager to provide custom results # in some cases. costs_manager = CostsManager() ######################################## # Add both the bus and the train info on the same matrix # costs_aux = copy.deepcopy(train_costs) # for x in enumerate(costs_aux): # print(x) costs = costs_manager.combineCosts(train_info, bus_info, train_costs, bus_costs) # print(pprint.pformat(enumerate(costs))) # for x in enumerate(costs): # print(x) # print(costs == costs_aux) # # Count differences (debug) # count = 0 # for i in range(len(costs)): # for j in range(len(costs[i])): # if (costs[i][j] != costs_aux[i][j]): # count += 1 # print("Count: ", count) # return # Set transfer costs really high so they are ignored # costs_manager.setTransferCost(info_parser.info, costs, 999) ######################################### # Walking costs costs = costs_manager.setWalkingCostsWithDistances( costs, distances, multiplier = WALK_MULTIPLIER ) # Set up the A* algorithm search = SearchStrategies() search.setCosts(costs) search.setHeuristic(distances) search.setIgnore(0) # Run the algorithm # way = search.aStar(1, 24, start_at=1) way = search.BFS(1, 24, start_at=1) print 'Result:', way
def run(self): """ Takes the options (input from the user) and processes it in order to give a customizable output, which is later on moved to a textctrl widget. """ # Get the state of the check boxes walking_selected = self.walking_cb.GetValue() subway_selected = self.subway_cb.GetValue() trolleybus_selected = self.trolleybus_cb.GetValue() # Get the state of the radio boxes minimize_stations = self.stations_rb.GetValue() minimize_transfers = self.transfers_rb.GetValue() minimize_cost = self.costs_rb.GetValue() # Get the origin selected - if no origin selected -> error selected = self.choice_origin.GetCurrentSelection() if selected == -1: return self.error("No origin selected.") origin = self.list_origin[selected] origin_id = self.stationStringToId(origin) # Get the destiny selected - if no destination is selected -> error selected = self.choice_destiny.GetCurrentSelection() if selected == -1: return self.error("No destiny selected.") destiny = self.list_destiny[selected] destiny_id = self.stationStringToId(destiny) #### Use the logic obtained to run the algorithm ## Error checking # Check if the user selected at least one of the check boxes if not (walking_selected or subway_selected or trolleybus_selected): return self.error("Please select some vehicle.") # If we selected trolleybus, check for a valid destiny and origin if trolleybus_selected and not subway_selected and not walking_selected: trolleybus_ids = self.gettrolleybusIdList() found = False for id in origin_id: if id in trolleybus_ids: found = True if not found: return self.error("This origin isn't possible when we use trolleybus.") found = False for id in destiny_id: if id in trolleybus_ids: found = True if not found: return self.error("Unreachable destiny via trolleybus.") # Check if the user selected the same origin and destiny if origin_id == destiny_id: return self.output_text.ChangeValue("You are already there.") ## /Error checking ## Use selected options to manage the data to run the algorithm # Load the information of the city train_parser = CityInfoParser() train_parser.loadFile(CITY_INFO_PATH) train_parser.parse() train_parser.setDistances() train_info = train_parser.info distances = train_parser.distances # Load the information of the trolleybus (distances are the same as the train) bus_parser = CityInfoParser() bus_parser.loadFile(TROLEI_BUS_INFO_PATH) bus_parser.parse() bus_info = bus_parser.info # Load the information of the train costs matrix_parser = AdjacencyMatrixParser() matrix_parser.loadFile(MA_PATH) matrix_parser.parse() train_costs = matrix_parser.values matrix_parser.closeFile() # Load info of the trolleybus costs matrix_parser.loadFile(TROLEI_BUS_MA_PATH) matrix_parser.parse() bus_costs = matrix_parser.values matrix_parser.closeFile() # Open an instance of cost manager to provide custom results # in some cases. costs_manager = CostsManager() if subway_selected and trolleybus_selected: costs = costs_manager.combineCosts(train_info, bus_info, train_costs, bus_costs) elif subway_selected: costs = train_costs elif walking_selected and not subway_selected and not trolleybus_selected: costs = self.makeWalkingMatrix(distances) elif walking_selected and trolleybus_selected: costs = self.expandBusMatrix() else: costs = bus_costs if walking_selected and (subway_selected or trolleybus_selected): costs = costs_manager.setWalkingCostsWithDistances( costs, distances, multiplier = WALK_MULTIPLIER ) if minimize_transfers: if subway_selected: costs_manager.setTransferCost(train_parser.info, costs, 999) elif trolleybus_selected: costs_manager.setTransferCost(bus_parser.info, costs, 999) # Set up the algorithm search = SearchStrategies() search.setCosts(costs) search.setHeuristic(distances) search.setIgnore(0) # Run the algorithm # If we only selected walking option, let the user go directly to their destination if walking_selected and not trolleybus_selected and not subway_selected: result = [destiny_id[0] - 1, origin_id[0] - 1] # substract -1 to normalize, enumeration starts with n=1 # Select the optimum way in case we have stations with same name (multiple IDs station) elif minimize_stations: result_list = [] for id in origin_id: for id2 in destiny_id: result_list.append(search.BFS(id, id2, start_at = 1)) bird = len result_list.sort(key=bird) # The key is the bird result = result_list[0] else: result_list = [] for id in origin_id: for id2 in destiny_id: print(id, id2) result_list.append(search.aStar(id, id2, start_at = 1)) bird = len result_list.sort(key=bird) result = result_list[0] # We process the result in order to display a nice output to the user # We do that because the algorithms return a boring list of numbers. self.output_text.Clear() walking_costs = self.makeWalkingMatrix(distances) # Helper method to calculate the optimum way of traversing from two # stations id given the actual options. def wayCheck(id1, id2): """ Helper function. Returns 1, 2 or 3 depending on whether the optimum way of going from id1 to id2 is by train (subway), bus or walking. @id1 (int): station_id1 @id2 (int): station_id2 """ # id1, id2 = id1-1, id2-1 patata = False if id2>id1: id1,id2=id2,id1 if walking_selected: costCaminant = walking_costs[id1-1][id2-1] if trolleybus_selected: ola=False busList = self.gettrolleybusIdList() if id2==18: ola=True id2,id1=id1,38 print busList print id1 , id2 ,id1 in busList and id2 in busList if id1 in busList and id2 in busList: patata = True sorted_dict_keys = bus_parser.info.keys() sorted_dict_keys.sort() for n, i in enumerate(sorted_dict_keys): if id1 == i: break for n2, j in enumerate(sorted_dict_keys): if id2 == j: break if n2>n: n2,n = n,n2 costBus = bus_costs[n][n2] if ola: id1,id2=id2,18 if subway_selected: if id1==38: xx,yy=17,id2-1 if xx<yy: xx,yy=yy,xx if train_costs[xx][yy]!=0 and train_costs[37][id2-1]==0: id1=18 if id1<id2: id2,id1=id1,id2 costsubway = train_costs[id1-1][id2-1] if subway_selected and not trolleybus_selected and not walking_selected: #100 return 1 elif not subway_selected and trolleybus_selected and not walking_selected: #010 return 2 elif not subway_selected and not trolleybus_selected and walking_selected: #001 return 3 elif subway_selected and not trolleybus_selected and walking_selected: #101 if costsubway==0: return 3 x = min(costsubway,costCaminant) if x==costsubway: return 1 elif x==costCaminant: return 3 else: raise ValueError() elif subway_selected and trolleybus_selected and not walking_selected and patata: #110 if costsubway==0: return 2 elif costBus==0: return 1 else: x = min(costsubway,costBus) if x==costsubway: return 1 elif x==costBus: return 2 else: raise ValueError() elif subway_selected and trolleybus_selected and not walking_selected and not patata: return 1 elif not subway_selected and trolleybus_selected and walking_selected and patata: #011 if costBus==0: return 3 x = min(costBus,costCaminant) if x==costBus: return 2 elif x==costCaminant: return 3 else: raise ValueError() elif not subway_selected and trolleybus_selected and walking_selected and not patata: return 3 elif subway_selected and trolleybus_selected and walking_selected and patata: #111 if costsubway==0 and costBus==0: return 3 elif costsubway==0: x = min(costBus,costCaminant) if x==costBus: return 2 elif x==costCaminant: return 3 else: raise ValueError() elif costBus==0: x = min(costsubway,costCaminant) if x==costsubway: return 1 elif x==costCaminant: return 3 else: raise ValueError() else: x = min(costsubway,costCaminant,costBus) if x==costsubway: return 1 elif x==costCaminant: return 3 elif x==costBus: return 2 else: raise ValueError() elif subway_selected and trolleybus_selected and walking_selected and not patata: if costsubway==0: return 3 x = min(costsubway,costCaminant) if x==costsubway: return 1 elif x==costCaminant: return 3 else: raise ValueError() else: raise ValueError() result.reverse() ###### Parse 2 per arreglar error matrix_parser = AdjacencyMatrixParser() matrix_parser.loadFile(MA_PATH) matrix_parser.parse() train_costs = matrix_parser.values matrix_parser.closeFile() print "result", result result = map(lambda num: num+1, result) # Increment each result by one print "result",result station_id1=result[0] for n, station_id2 in enumerate(result[1:], start=1): number = wayCheck(station_id1,station_id2) print "station ids: ", station_id1, station_id2 origen_station = self.stationIdToString(station_id1) destiny_station = self.stationIdToString(station_id2) station_id1=station_id2 self.output_text.AppendText(str(n) + ") " + origen_station + " -> " + destiny_station +": ") if number == 1: self.output_text.AppendText("Subway") elif number == 2: self.output_text.AppendText("Trolleybus") elif number == 3: self.output_text.AppendText("Walking") else: raise ValueError() if origen_station == destiny_station: self.output_text.AppendText(" (transfer)") self.output_text.AppendText("\n") # Move selection of text ctrl to topleft self.output_text.ShowPosition(0)