Beispiel #1
0
def greedy_route(map, max_time, data, routes, key):
    """Create a greedy route.

    Keyword arguments:
    key (str)       options:[Connections, Time, Score]. Method Greedy makes choices
    """

    # Make new empty route list and add (non-final) route to list of routes
    routes.append([])

    # Pick a/the best station as starting point of the route
    routes[-1].append(greedy_option(map, data, routes, "connections"))

    # Keep adding stations to the route until constraints are met
    while greedy_option(map, data, routes, key) != None:
        routes[-1].append(greedy_option(map, data, routes, key))

        # Check if route meets time constrain
        total_time = Route(map, routes).time
        if total_time > max_time:
            routes[-1] = routes[-1][:-1]
            break

    # Replace route list by final route object in list of routes
    routes[-1] = Route(map, routes)

    return routes[-1]
Beispiel #2
0
def breadth_first_route(map, max_time, min_score, data, routes, depth, ratio,
                        definition):
    """Create a breadth first route.

    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
    definition (str)    options: [Create, Improve]. Goal of algorithm
    """

    # Starting station of route
    chain = Queue()
    routes.append([])
    start = [greedy_option(map, data, routes, "connections")]
    chain.put(start)

    # Set details for best route with breadth first algorithm
    best_route = Route(map, [start])

    # Keep searching for routes until no feasible options
    while not chain.empty():

        # Get top route/station from tree of routes
        state = chain.get()
        routes[-1] = state

        # Find each possible child from state and add to tree of routes
        if routes[-1][-1] != None and breadth_first_options(
                data, routes, definition) != None:
            for option in breadth_first_options(data, routes, definition):
                child = deepcopy(state)
                child.append(option)
                routes[-1] = child
                route = Route(map, routes)

                # Check time constrains for route
                if route.time < max_time:
                    chain.put(child)

                    # Apply Greedy look-ahead with minimal score or with score-route length ratio
                    if len(route.route) > depth and (
                            route.score < min_score or
                        (ratio - 1 / 20 * len(route.route)) * route.score /
                            len(route.route) <
                            best_route.score / len(best_route.route)):
                        chain.get()

                    # Check if route is best solution yet
                    best_route = choose_best_route(route, best_route)

    routes[-1] = best_route

    return best_route
Beispiel #3
0
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
Beispiel #4
0
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)
Beispiel #5
0
	def bootstrap(cls, env, response):
		""" Bootstrap the application, send back headers and body """
		cls.handle_wsgi_reboot(env)
		cls.build_request_obj(env)

		from classes.route import Route
		body = Route.init()

		cls.add_header('Content-type', 'text/html')
		cls.add_header('Content-Length', str(len(body)))
		response(cls.status, cls.headers)
		return [body]
Beispiel #6
0
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)
Beispiel #7
0
def random_route(map, max_time, data, routes):
    """Randomize a route."""

    # Make new empty route list and add (non-final) route to list of routes
    routes.append([])
    total_time = 0

    # Pick a random station as starting point of the route
    routes[-1].append(data[rd_choice(list(data.keys()))])

    # Keep adding stations to the route until no more possible destinations
    while random_options(map, data, routes) != None:
        routes[-1].append(random_options(map, data, routes))

        # Check if route meets time constrain, if not end route
        total_time = Route(map, routes).time
        if total_time > max_time:
            routes[-1] = routes[-1][:-1]
            break

    # Replace route list by final route object in list of routes
    routes[-1] = Route(map, routes)

    return routes[-1]
Beispiel #8
0
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