def run_algorithm(map, max_routes, max_time, solution, algorithm, iterations, key, depth, ratio, change_routes, formula, definition): """Run algorithm of choice for user. Keyword arguments: algorithm (str) algorithm that will be used to improve solution iterations (int) total iterations of improving key (str) options: [Connections, Time, Score]. Method Greedy makes choices depth (int) length of route after which can be pruned ratio (int) score/length ratio in order to best solution after which can be pruned change_routes (int) amount of routes that can be improved formula (str) temperature formula definition (str) options:[Create, Improve]. Goal of algorithm """ data = RailNL(map).data min_score = 10000 / len(all_connections(map)) - 105 # Run algorithm based on input if definition == 'create': solution_algorithm = start_algorithm(map, max_routes, max_time, min_score, algorithm, iterations, key, depth, ratio) else: solution_algorithm = improve_algorithm(map, max_routes, max_time, min_score, solution, algorithm, iterations, key, depth, ratio, change_routes, formula, definition) print(solution_algorithm) return solution_algorithm
def delete_short_route(map, min_score, solution): """Delete short route or route that doesn't contribute to K score from route.""" old_score = solution.score # Find and delete routes that don't contribute to overall K score for route in solution.routes: if route.score < min_score: solution.routes.remove(route) routes = [] for i in range(len(solution.routes)): solution.routes[i] = solution.routes[i].route solution.routes[i] = Route(map, solution.routes[:i + 1]) # Calculate new K score new_score = Solution(map, solution.routes).score improvement = new_score - old_score # Update unused connections unused_connections = all_connections(map) - all_used_connections( Solution(map, solution.routes).routes) if unused_connections == set() or improvement <= 0: return False return Solution(map, solution.routes)
def breadth_first(map, max_routes, max_time, min_score, depth, ratio): """Create solution consisting of set of routes based on breadth first algorithm. Keyword arguments: depth (int) length of route after which can be pruned ratio (int) score/length ratio in order to best solution after which can be pruned """ # Get all data for stations in current map data = RailNL(map).data # Create list where routes can be added routes = [] # Keep track of fraction of used connections num_connections = len(all_connections(map)) connections = connections_station(data) # Create random routes until it is not possible anymore due to the constrains while len(routes) < max_routes and len( connections["used_connections"]) < num_connections: breadth_first_route(map, max_time, min_score, data, routes, depth, ratio, definition=None) connections = update_connections(map, data, routes) return Solution(map, routes)
def calc_p(self, map): """Calculate the fraction of used connections.""" used_connections = len(all_used_connections(self.routes)) total_num_connections = len(all_connections(map)) p = used_connections / total_num_connections return p
def calc_score(self, map, routes): """Determine score of current route.""" # Fraction of based on used connections p = len(all_used_connections_route(routes)) / len(all_connections(map)) # Formula to calcucate the quality of route self.score = 10000 * p - (100 + self.time) return self.score
def add_unused_connection(solution, map, data, traject, connections_left): """Add unused connection to route. Keyword arguments: traject (obj) route connections_left (list) list of unused connections tuples """ # Find station in route that can still make new connection for station in traject.route: if str(station) in connections_left.keys(): if connections_left[str(station)] >= 1: unused_connections = all_connections( map) - all_used_connections(solution.routes) # Break if all it's connections are used if unused_connections == set(): break # Find neighbour station that has no connection for connection in unused_connections: if str(connection[0]) == str(station): new_station = data[str(connection[1])] elif str(connection[1]) == str(station): new_station = data[str(connection[0])] else: return False # Create temporary route with unconnected station added to calculate new score index = traject.route.index(station) first_part = list(traject.route[:index + 1]) last_part = list(traject.route[index:]) temp_route = first_part + [new_station] + last_part # Calculate score based on solution with temporary route added copy_routes = deepcopy(solution) route_index = solution.routes.index(traject) copy_routes.routes[route_index].route = Route( map, [temp_route]).route temp_score = Solution(map, copy_routes.routes).score score_original = solution.score # Add station to route if score has improved if temp_score > score_original: solution.routes[route_index] = copy_routes.routes[ route_index] break return Solution(map, solution.routes)
def add_routes(map, max_time, min_score, data, solution, algorithm, depth, ratio, change_routes, definition): """Add new route with input algorithm to the solution. Keyword arguments: algorithm (str) algorithm that will be used to improve solution depth (int) length of route after which can be pruned ratio (int) score/length ratio in order to best solution after which can be pruned change_routes (int) amount of routes that can be improved definition (str) options: [Create, Improve]. Goal of algorithm """ # Keep track of fraction of used connections num_connections = len(all_connections(map)) connections = update_connections(map, data, solution.routes) # Keep adding new routes untill all connections have been added to a route counter = 0 while counter < change_routes and len( connections["used_connections"]) < num_connections: # Add route following input algorithm if algorithm == "random": random_route(map, max_time, data, solution.routes) elif algorithm == "greedy": greedy_route(map, max_time, data, solution.routes, "connections") elif algorithm == "depth_first": depth_first_route(map, max_time, min_score, data, solution.routes, depth, ratio, "improve") elif algorithm == "breadth_first": breadth_first_route(map, max_time, min_score, data, solution.routes, depth, ratio, "improve") # Update used connections connections = update_connections(map, data, solution.routes) counter += 1 return solution.routes
def randomize(map, max_routes, max_time): """Create solution consisting of random routes.""" # Get all data of stations of current map data = RailNL(map).data # Make empty list for all routes routes = [] # Keep track of fraction of used connections num_connections = len(all_connections(map)) connections = connections_station(data) # Make random routes untill it is not possible anymore due to the constrains while len(routes) < max_routes and len( connections["used_connections"]) < num_connections: random_route(map, max_time, data, routes) connections = update_connections(map, data, routes) # Make solution class and update attributes random_solution = Solution(map, routes) return random_solution
def greedy(map, max_routes, max_time, key): """Create solution consisting of routes based on greedy algorithm. Keyword arguments: key (str) options: [Connections, Time, Score]. Method Greedy makes choices """ # Get all data from stations in map data = RailNL(map).data # Create list where routes can be added routes = [] # Keep track of fraction of used connections num_connections = len(all_connections(map)) connections = connections_station(data) # Make greedy routes until it is not possible anymore due to the constrains while len(routes) < max_routes and len( connections["used_connections"]) < num_connections: greedy_route(map, max_time, data, routes, key) connections = update_connections(map, data, routes) return Solution(map, routes)