Пример #1
0
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
Пример #2
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)
Пример #3
0
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)
Пример #4
0
    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
Пример #5
0
    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
Пример #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)
Пример #7
0
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
Пример #8
0
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
Пример #9
0
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)