Implement multi-start local search

This commit is contained in:
coolneng 2021-06-22 08:37:38 +02:00
parent c62d1213b8
commit 6ccc1cb661
Signed by: coolneng
GPG Key ID: 9893DA236405AF57
1 changed files with 42 additions and 7 deletions

View File

@ -1,5 +1,8 @@
from numpy.random import choice, seed, randint from numpy.random import choice, seed, randint
from pandas import DataFrame from pandas import DataFrame
from multiprocessing import Pool
from functools import partial
from itertools import combinations
def get_row_distance(source, destination, data): def get_row_distance(source, destination, data):
@ -22,7 +25,7 @@ def compute_distance(element, solution, data):
return accumulator return accumulator
def get_first_random_solution(n, m, data): def get_first_random_solution(placeholder, n, m, data):
solution = DataFrame(columns=["point", "distance"]) solution = DataFrame(columns=["point", "distance"])
seed(42) seed(42)
solution["point"] = choice(n, size=m, replace=False) solution["point"] = choice(n, size=m, replace=False)
@ -67,9 +70,41 @@ def explore_neighbourhood(element, n, data, max_iterations=100000):
return neighbour return neighbour
def local_search(n, m, data): def evaluate_solution(solution, data):
first_solution = get_first_random_solution(n, m, data) fitness = 0
best_solution = explore_neighbourhood( comb = combinations(solution.index, r=2)
element=first_solution, n=n, data=data, max_iterations=100 for index in list(comb):
elements = solution.loc[index, :]
fitness += get_row_distance(
source=elements["point"].head(n=1).values[0],
destination=elements["point"].tail(n=1).values[0],
data=data,
) )
return best_solution return fitness
def generate_initial_solutions(n, m, data, number_solutions, cores=4):
generation_func = partial(get_first_random_solution, n=n, m=m, data=data)
with Pool(cores) as pool:
initial_solutions = pool.map(generation_func, range(number_solutions))
return initial_solutions
def evaluate_all_solutions(solutions, data, cores=4):
generation_func = partial(evaluate_solution, data=data)
with Pool(cores) as pool:
fitness = pool.map(generation_func, solutions)
return fitness
def local_search(n, m, data, number_solutions=10):
initial_solutions = generate_initial_solutions(n, m, data, number_solutions)
solutions = []
for solution in initial_solutions:
local_best_solution = explore_neighbourhood(
element=solution, n=n, data=data, max_iterations=100
)
solutions.append(local_best_solution)
fitness = evaluate_all_solutions(solutions, data)
best_index = fitness.index(max(fitness))
return solutions[best_index]