diff --git a/src/genetic_algorithm.py b/src/genetic_algorithm.py index 3567ba6..9357842 100644 --- a/src/genetic_algorithm.py +++ b/src/genetic_algorithm.py @@ -1,10 +1,14 @@ from numpy.random import choice, seed -def get_first_random_solution(m, data): +def get_first_random_solution(n, m): seed(42) - random_indexes = choice(len(data.index), size=m, replace=False) - return data.loc[random_indexes] + solution = zeros(shape=n, dtype=bool) + random_indices = choice(n, size=m, replace=False) + put(solution, ind=random_indices, v=True) + return solution + + def element_in_dataframe(solution, element): @@ -42,8 +46,8 @@ def explore_neighbourhood(element, data, max_iterations=100000): return neighbour -def local_search(m, data): - first_solution = get_first_random_solution(m=m, data=data) +def genetic_algorithm(n, m, data): + first_solution = get_first_random_solution(n=n, m=m) best_solution = explore_neighbourhood( element=first_solution, data=data, max_iterations=100 ) diff --git a/src/main.py b/src/main.py index f70aaa1..9286f13 100755 --- a/src/main.py +++ b/src/main.py @@ -1,17 +1,17 @@ from preprocessing import parse_file -from greedy import greedy_algorithm -from local_search import local_search +from genetic_algorithm import genetic_algorithm +from memetic_algorithm import memetic_algorithm from sys import argv from time import time def execute_algorithm(choice, n, m, data): - if choice == "greedy": - return greedy_algorithm(n, m, data) - elif choice == "local": - return local_search(m, data) + if choice == "genetic": + return genetic_algorithm(n, m, data) + elif choice == "memetic": + return memetic_algorithm(m, data) else: - print("The valid algorithm choices are 'greedy' and 'local'") + print("The valid algorithm choices are 'genetic' and 'memetic'") exit(1) @@ -28,8 +28,8 @@ def show_results(solutions, time_delta): def usage(argv): print(f"Usage: python {argv[0]} ") print("algorithm choices:") - print("greedy: greedy algorithm") - print("local: local search algorithm") + print("genetic: genetic algorithm") + print("memetic: memetic algorithm") exit(1) diff --git a/src/memetic_algorithm.py b/src/memetic_algorithm.py new file mode 100644 index 0000000..1a6425f --- /dev/null +++ b/src/memetic_algorithm.py @@ -0,0 +1,50 @@ +from numpy.random import choice, seed + + +def get_first_random_solution(m, data): + seed(42) + random_indexes = choice(len(data.index), size=m, replace=False) + return data.loc[random_indexes] + + +def element_in_dataframe(solution, element): + duplicates = solution.query( + f"(source == {element.source} and destination == {element.destination}) or (source == {element.destination} and destination == {element.source})" + ) + return not duplicates.empty + + +def replace_worst_element(previous, data): + solution = previous.copy() + worst_index = solution["distance"].astype(float).idxmin() + random_element = data.sample().squeeze() + while element_in_dataframe(solution=solution, element=random_element): + random_element = data.sample().squeeze() + solution.loc[worst_index] = random_element + return solution, worst_index + + +def get_random_solution(previous, data): + solution, worst_index = replace_worst_element(previous, data) + previous_worst_distance = previous["distance"].loc[worst_index] + while solution.distance.loc[worst_index] <= previous_worst_distance: + solution, _ = replace_worst_element(previous=solution, data=data) + return solution + + +def explore_neighbourhood(element, data, max_iterations=100000): + neighbourhood = [] + neighbourhood.append(element) + for _ in range(max_iterations): + previous_solution = neighbourhood[-1] + neighbour = get_random_solution(previous=previous_solution, data=data) + neighbourhood.append(neighbour) + return neighbour + + +def memetic_algorithm(m, data): + first_solution = get_first_random_solution(m=m, data=data) + best_solution = explore_neighbourhood( + element=first_solution, data=data, max_iterations=100 + ) + return best_solution