
"""simple docstring"""




import argparse
import copy

def lowercase_						(     _snake_case		):
							SCREAMING_SNAKE_CASE__		: List[str]     =     {}

							with open(_snake_case		) as f:
														for line in f:
																					if line.split()[0] not in dict_of_neighbours:
																												SCREAMING_SNAKE_CASE__		: Tuple     =     []
																												_list.append([line.split()[1], line.split()[2]]		)
																												SCREAMING_SNAKE_CASE__		: Tuple     =     _list
																					else:
																												dict_of_neighbours[line.split()[0]].append(
																												    [line.split()[1], line.split()[2]]		)
																					if line.split()[1] not in dict_of_neighbours:
																												SCREAMING_SNAKE_CASE__		: List[Any]     =     []
																												_list.append([line.split()[0], line.split()[2]]		)
																												SCREAMING_SNAKE_CASE__		: str     =     _list
																					else:
																												dict_of_neighbours[line.split()[1]].append(
																												    [line.split()[0], line.split()[2]]		)

							return dict_of_neighbours

def lowercase_						(     _snake_case     ,_snake_case		):

							with open(_snake_case		) as f:
														SCREAMING_SNAKE_CASE__		: Optional[Any]     =     f.read(1		)
							SCREAMING_SNAKE_CASE__		: List[Any]     =     start_node

							SCREAMING_SNAKE_CASE__		: Dict     =     []

							SCREAMING_SNAKE_CASE__		: Tuple     =     start_node

							SCREAMING_SNAKE_CASE__		: List[Any]     =     0
							while visiting not in first_solution:
														SCREAMING_SNAKE_CASE__		: Dict     =     10_000
														for k in dict_of_neighbours[visiting]:
																					if int(k[1]		) < int(_snake_case		) and k[0] not in first_solution:
																												SCREAMING_SNAKE_CASE__		: Optional[Any]     =     k[1]
																												SCREAMING_SNAKE_CASE__		: Dict     =     k[0]

														first_solution.append(_snake_case		)
														SCREAMING_SNAKE_CASE__		: List[str]     =     distance_of_first_solution + int(_snake_case		)
														SCREAMING_SNAKE_CASE__		: Tuple     =     best_node

							first_solution.append(_snake_case		)

							SCREAMING_SNAKE_CASE__		: List[str]     =     0
							for k in dict_of_neighbours[first_solution[-2]]:
														if k[0] == start_node:
																					break
														position += 1

							SCREAMING_SNAKE_CASE__		: Optional[int]     =     (
							    distance_of_first_solution
							    + int(dict_of_neighbours[first_solution[-2]][position][1]		)
							    - 10_000
							)
							return first_solution, distance_of_first_solution

def lowercase_						(     _snake_case     ,_snake_case		):
							SCREAMING_SNAKE_CASE__		: Union[str, Any]     =     []

							for n in solution[1:-1]:
														SCREAMING_SNAKE_CASE__		: Tuple     =     solution.index(_snake_case		)
														for kn in solution[1:-1]:
																					SCREAMING_SNAKE_CASE__		: int     =     solution.index(_snake_case		)
																					if n == kn:
																												continue

																					SCREAMING_SNAKE_CASE__		: Optional[Any]     =     copy.deepcopy(_snake_case		)
																					SCREAMING_SNAKE_CASE__		: int     =     kn
																					SCREAMING_SNAKE_CASE__		: List[Any]     =     n

																					SCREAMING_SNAKE_CASE__		: Tuple     =     0

																					for k in _tmp[:-1]:
																												SCREAMING_SNAKE_CASE__		: Optional[int]     =     _tmp[_tmp.index(_snake_case		) + 1]
																												for i in dict_of_neighbours[k]:
																																			if i[0] == next_node:
																																										SCREAMING_SNAKE_CASE__		: str     =     distance + int(i[1]		)
																					_tmp.append(_snake_case		)

																					if _tmp not in neighborhood_of_solution:
																												neighborhood_of_solution.append(_tmp		)

							SCREAMING_SNAKE_CASE__		: Union[str, Any]     =     len(neighborhood_of_solution[0]		) - 1

							neighborhood_of_solution.sort(key=lambda _snake_case		: x[index_of_last_item_in_the_list]		)
							return neighborhood_of_solution

def lowercase_						(     _snake_case     ,_snake_case     ,_snake_case     ,_snake_case     ,_snake_case		):
							SCREAMING_SNAKE_CASE__		: Dict     =     1
							SCREAMING_SNAKE_CASE__		: str     =     first_solution
							SCREAMING_SNAKE_CASE__		: Optional[Any]     =     []
							SCREAMING_SNAKE_CASE__		: Dict     =     distance_of_first_solution
							SCREAMING_SNAKE_CASE__		: str     =     solution

							while count <= iters:
														SCREAMING_SNAKE_CASE__		: int     =     find_neighborhood(_snake_case     ,_snake_case		)
														SCREAMING_SNAKE_CASE__		: Optional[Any]     =     0
														SCREAMING_SNAKE_CASE__		: List[Any]     =     neighborhood[index_of_best_solution]
														SCREAMING_SNAKE_CASE__		: int     =     len(_snake_case		) - 1

														SCREAMING_SNAKE_CASE__		: Optional[Any]     =     False
														while not found:
																					SCREAMING_SNAKE_CASE__		: str     =     0
																					while i < len(_snake_case		):
																												if best_solution[i] != solution[i]:
																																			SCREAMING_SNAKE_CASE__		: Tuple     =     best_solution[i]
																																			SCREAMING_SNAKE_CASE__		: int     =     solution[i]
																																			break
																												SCREAMING_SNAKE_CASE__		: Dict     =     i + 1

																					if [first_exchange_node, second_exchange_node] not in tabu_list and [
																					    second_exchange_node,
																					    first_exchange_node,
																					] not in tabu_list:
																												tabu_list.append([first_exchange_node, second_exchange_node]		)
																												SCREAMING_SNAKE_CASE__		: Union[str, Any]     =     True
																												SCREAMING_SNAKE_CASE__		: str     =     best_solution[:-1]
																												SCREAMING_SNAKE_CASE__		: Union[str, Any]     =     neighborhood[index_of_best_solution][best_cost_index]
																												if cost < best_cost:
																																			SCREAMING_SNAKE_CASE__		: Any     =     cost
																																			SCREAMING_SNAKE_CASE__		: List[str]     =     solution
																					else:
																												SCREAMING_SNAKE_CASE__		: str     =     index_of_best_solution + 1
																												SCREAMING_SNAKE_CASE__		: Optional[int]     =     neighborhood[index_of_best_solution]

														if len(_snake_case		) >= size:
																					tabu_list.pop(0		)

														SCREAMING_SNAKE_CASE__		: List[Any]     =     count + 1

							return best_solution_ever, best_cost

def lowercase_						(     _snake_case=None		):
							SCREAMING_SNAKE_CASE__		: Any     =     generate_neighbours(args.File		)

							SCREAMING_SNAKE_CASE__		: Optional[Any]     =     generate_first_solution(
							    args.File     ,_snake_case		)

							SCREAMING_SNAKE_CASE__		: int     =     tabu_search(
							    _snake_case     ,_snake_case     ,_snake_case     ,args.Iterations     ,args.Size     ,)

							print(f'''Best solution: {best_sol}, with total distance: {best_cost}.'''		)


if __name__ == "__main__":
					UpperCAmelCase__   :					List[str]												=				argparse.ArgumentParser(description='Tabu Search')
					parser.add_argument(
					    '-f',
					    '--File',
					    type=str,
					    help='Path to the file containing the data',
					    required=True,
					)
					parser.add_argument(
					    '-i',
					    '--Iterations',
					    type=int,
					    help='How many iterations the algorithm should perform',
					    required=True,
					)
					parser.add_argument(
					    '-s', '--Size', type=int, help='Size of the tabu list', required=True
					)

					# Pass the arguments to main method
					main(parser.parse_args())





"""simple docstring"""




import torch

def lowercase_						(     ):
							if torch.cuda.is_available():
														SCREAMING_SNAKE_CASE__		: List[Any]     =     torch.cuda.device_count()
							else:
														SCREAMING_SNAKE_CASE__		: int     =     0
							print(f'''Successfully ran on {num_gpus} GPUs'''		)


if __name__ == "__main__":
					main()




