Implement multi-start local search
This commit is contained in:
parent
c62d1213b8
commit
6ccc1cb661
|
@ -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]
|
||||||
|
|
Loading…
Reference in New Issue