61 lines
2.1 KiB
Python
61 lines
2.1 KiB
Python
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 replace_worst_element(previous, data):
|
|
solution = previous.copy()
|
|
worst_index = solution["distance"].astype(float).idxmin()
|
|
random_element = data.sample().squeeze()
|
|
while solution.isin(random_element.values.ravel()).any().any():
|
|
random_element = data.sample().squeeze()
|
|
solution.loc[worst_index] = random_element
|
|
return solution, worst_index
|
|
|
|
|
|
def choose_best_solution(previous, current, index):
|
|
if previous.loc[index].distance >= current.loc[index].distance:
|
|
return previous
|
|
return current
|
|
|
|
|
|
def get_random_solution(previous, data):
|
|
candidates = []
|
|
candidates.append(previous)
|
|
solution, worst_index = replace_worst_element(previous, data)
|
|
previous_worst_distance = previous["distance"].loc[worst_index]
|
|
last_solution = candidates[-1]
|
|
while last_solution.distance.loc[worst_index] <= previous_worst_distance:
|
|
solution, _ = replace_worst_element(previous=solution, data=data)
|
|
if solution.equals(last_solution):
|
|
best_solution = choose_best_solution(
|
|
previous=previous, current=solution, index=worst_index
|
|
)
|
|
return best_solution
|
|
candidates.append(solution)
|
|
last_solution = candidates[-1]
|
|
return last_solution
|
|
|
|
|
|
def explore_neighbourhood(element, data, max_iterations=100000):
|
|
neighbourhood = []
|
|
neighbourhood.append(element)
|
|
for i in range(max_iterations):
|
|
print(f"Iteration {i}")
|
|
previous_solution = neighbourhood[-1]
|
|
neighbour = get_random_solution(previous=previous_solution, data=data)
|
|
if neighbour.equals(previous_solution):
|
|
break
|
|
neighbourhood.append(neighbour)
|
|
return neighbour
|
|
|
|
|
|
def local_search(m, data):
|
|
first_solution = get_first_random_solution(m=m, data=data)
|
|
best_solution = explore_neighbourhood(element=first_solution, data=data)
|
|
return best_solution
|