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 random_options(map, data, routes): """Return possible destinations. Not possible to go to a station that is already on the route.""" # Determine amount of connections and used connections for all Stations routes[-1] = Route(map, routes[len(routes) - 1:]) connections = update_connections(map, data, routes) routes[-1] = routes[-1].route # Convert route of Station objects to route list of strings route_list = convert_object_to_string(routes[-1]) # Determine all possible connections from current station options = [] for connection in data[route_list[-1]].connections: possible_connection = (route_list[-1], connection[0]) if tuple(sorted( possible_connection)) not in connections["used_connections"]: options.append(connection[0]) # If any options, return random option if options: random_option = data[rd_choice(options)] return random_option return None
def short_route_swap(map, max_time, min_score, solution_output): """"Create hillclimber solution based on solution output.""" # Delete short routes from solution solution = delete_short_route(map, min_score, solution_output) # Return solution if all connections are already used if solution == False: return Solution(map, solution_output.routes) # Update connections that are unused data = RailNL(map).data solution = Solution(map, solution.routes) connections_left = update_connections( map, data, solution.routes)['amount_connections'] # Find stations with unused connection and add these to route for traject in solution.routes: new_solution = add_unused_connection(solution, map, data, traject, connections_left) if new_solution == False: return Solution(map, solution_output.routes) return Solution(map, new_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)
def greedy_option(map, data, routes, key): """Determine best destination. Keyword arguments: key (str) options:[Connections, Time, Score]. Method Greedy makes choices """ # Determine amount of connections and used connections for all stations routes[-1] = Route(map, routes[len(routes) - 1:]) connections = update_connections(map, data, routes) routes[-1] = routes[-1].route options = {} # Choose best option (not yet in route) from current station based on minimum of connections or time if key == "connections" or key == "time": # Convert route of Station objects to route list of strings route_list = convert_object_to_string(routes[-1]) # Check if route has station. If so, determine (unused) connections of current station if route_list != []: for connection in data[route_list[-1]].connections: possible_connection = (route_list[-1], connection[0]) # Check if connection has not yet been made, then add station to dict with corresponding amount of connections if tuple(sorted(possible_connection) ) not in connections["used_connections"]: if key == "connections": options[connection[0]] = connections[ "amount_connections"][connection[0]] elif key == "time": options[connection[0]] = connection[1] # All stations possible as starting station else: options = connections["amount_connections"] # If any options, choose best option which has least connections if options: best_option = data[rd_choice([ k for k, v in options.items() if v == min(list(options.values())) ])] return best_option return None elif key == "score": # Check if route has station. If so, determine (unused) connections of current station if routes[-1] != []: # Make list of already used connections in current route for connection in routes[-1][-1].connections: possible_connection = (routes[-1][-1].name, connection[0]) # Check if connection has not yet been made, then add station to dict with corresponding amount of connections if tuple(sorted(possible_connection) ) not in connections["used_connections"]: possible_routes = [] possible_route = routes[-1].copy() possible_routes.append(possible_route) possible_route.append(data[connection[0]]) options[connection[0]] = Route(map, possible_routes).score # All stations possible as starting station else: options = connections["amount_connections"] # If any options, choose best option which has least connections if options: best_option = data[rd_choice([ k for k, v in options.items() if v == max(list(options.values())) ])] return best_option return None