Beispiel #1
0
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)
Beispiel #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)
Beispiel #3
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 #4
0
def main():

    # Evaluator
    evaluator = Evaluator()

    # HillClimb
    # solution = Solution(100, 50)
    # solution.start()
    # optimizer = HillClimb(100000)
    # optimizer.run(solution, evaluator.shiftedSphere, 1, 1)

    # Simulated Annealing
    solution = Solution(100, 100)
    solution.start()
    optimizer = SimulatedAnnealing(100000, 0)
    optimizer.run(solution, evaluator.shiftedSphere, 1, 3, 100)
Beispiel #5
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)
Beispiel #6
0
def hillclimber(map, max_routes, max_time, min_score, solution, algorithm, depth, ratio, change_routes):
    """"Create hillclimber solution based on greedy output.

    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
    """

    # Get all data from stations in map
    data = RailNL(map).data

    # Set best solution which can should be improved
    best_solution = solution

    # Remove routes that needs to be changed
    last_solution = deepcopy(best_solution)
    last_solution = remove_routes(last_solution, change_routes)

    # Add routes to solution to get new solution
    new_routes = add_routes(map, max_time, min_score, data, last_solution,
        algorithm, depth, ratio, change_routes, "improve")

    new_solution = Solution(map, new_routes)

    # Change best solution if needed
    if new_solution.score > last_solution.score:
        best_solution = new_solution

    return best_solution
Beispiel #7
0
def solve(instance):
    master_problem_params = {
        'SEC': None,
        'activate_DB': False,
        'min_visited_nodes': 0,
        'time_limit': 3600
    }
    subproblem_params = {
        'M':
        sum(
            sorted(
                instance.truck_travel_time.values())[::-1][:2 *
                                                           (instance.n - 1):2])
    }

    functions = {
        'get_route': get_route,
        'get_route_recourse': get_route_recourse,
        'get_shortcuts': get_shortcuts
    }

    master_problem = MasterProblem(instance, master_problem_params)
    subproblem = SubProblem(instance, subproblem_params)
    callback = Callback(instance, functions)
    solution = Solution(instance)

    cb = callback.callback(master_problem, subproblem, solution)

    solution.start_time = time()
    master_problem._solve(cb)

    solution.truck_arcs = [
        a for a in instance.arcs if master_problem.variables['x'][a].X > 0.5
    ]
    recourse = get_route_recourse(solution.truck_arcs, instance.arcs)

    subproblem.set_constr_rhs(recourse)
    subproblem._solve()
    solution.operations = [
        e for e in instance.operations if subproblem.variables['o'][e].X > 0.5
    ]

    plotter.plot(instance, solution.truck_arcs, solution.drone_arcs)
def simulated_annealing(map, max_routes, max_time, min_score, solution,
                        algorithm, depth, ratio, change_routes, i, iterations,
                        formula):
    """"Create hillclimber solution based on greedy output.

    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
    i (int)                 ith iteration
    iterations	 (int)      total iterations of improving
    formula (str)           temperature formula
    """

    # Get all data from stations in map
    data = RailNL(map).data

    # Set best solution which can should be improved
    best_solution = solution

    # Remove routes that needs to be changed
    last_solution = deepcopy(best_solution)
    last_solution = remove_routes(last_solution, change_routes)

    # Add routes to solution to get new solution
    new_routes = add_routes(map, max_time, min_score, data, last_solution,
                            algorithm, depth, ratio, change_routes, "improve")

    new_solution = Solution(map, new_routes)

    # Set temperature depending of formula
    if formula == "linear":
        temperature = iterations / 2 - 0.5 * i
    elif formula == "exponential":
        temperature = iterations / 2 * (0.995**i)

    # Determine if new solution needs to be accepted
    acceptation_probability = 2**Decimal(
        (new_solution.score - last_solution.score) / Decimal(temperature))
    random_probability = random()
    if acceptation_probability > random_probability:
        best_solution = new_solution

    return best_solution
Beispiel #9
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
Beispiel #10
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)