
'''simple docstring'''







import argparse
import copy
def 					snake_case_		(				__SCREAMING_SNAKE_CASE					: Optional[int]							):



						"""simple docstring"""





						lowercase_	:     List[Any]													=       {}

						with open(__SCREAMING_SNAKE_CASE							) as f:
												for line in f:
																		if line.split()[0] not in dict_of_neighbours:
																								lowercase_	:     Union[str, Any]													=       []
																								_list.append([line.split()[1], line.split()[2]]							)
																								lowercase_	:     str													=       _list
																		else:
																								dict_of_neighbours[line.split()[0]].append(
																								    [line.split()[1], line.split()[2]]							)
																		if line.split()[1] not in dict_of_neighbours:
																								lowercase_	:     Optional[int]													=       []
																								_list.append([line.split()[0], line.split()[2]]							)
																								lowercase_	:     Dict													=       _list
																		else:
																								dict_of_neighbours[line.split()[1]].append(
																								    [line.split()[0], line.split()[2]]							)

						return dict_of_neighbours
def 					snake_case_		(				__SCREAMING_SNAKE_CASE					: str      ,      __SCREAMING_SNAKE_CASE					: Tuple							):



						"""simple docstring"""





						with open(__SCREAMING_SNAKE_CASE							) as f:
												lowercase_	:     List[str]													=       f.read(1							)
						lowercase_	:     Optional[int]													=       start_node

						lowercase_	:     Any													=       []

						lowercase_	:     List[str]													=       start_node

						lowercase_	:     Optional[Any]													=       0
						while visiting not in first_solution:
												lowercase_	:     Any													=       10000
												for k in dict_of_neighbours[visiting]:
																		if int(k[1]							) < int(__SCREAMING_SNAKE_CASE							) and k[0] not in first_solution:
																								lowercase_	:     List[Any]													=       k[1]
																								lowercase_	:     List[Any]													=       k[0]

												first_solution.append(__SCREAMING_SNAKE_CASE							)
												lowercase_	:     Optional[Any]													=       distance_of_first_solution + int(__SCREAMING_SNAKE_CASE							)
												lowercase_	:     int													=       best_node

						first_solution.append(__SCREAMING_SNAKE_CASE							)

						lowercase_	:     Tuple													=       0
						for k in dict_of_neighbours[first_solution[-2]]:
												if k[0] == start_node:
																		break
												position += 1

						lowercase_	:     Optional[Any]													=       (
						    distance_of_first_solution
						    + int(dict_of_neighbours[first_solution[-2]][position][1]							)
						    - 10000
						)
						return first_solution, distance_of_first_solution
def 					snake_case_		(				__SCREAMING_SNAKE_CASE					: Optional[Any]      ,      __SCREAMING_SNAKE_CASE					: Union[str, Any]							):



						"""simple docstring"""





						lowercase_	:     Tuple													=       []

						for n in solution[1:-1]:
												lowercase_	:     List[str]													=       solution.index(__SCREAMING_SNAKE_CASE							)
												for kn in solution[1:-1]:
																		lowercase_	:     Any													=       solution.index(__SCREAMING_SNAKE_CASE							)
																		if n == kn:
																								continue

																		lowercase_	:     Dict													=       copy.deepcopy(__SCREAMING_SNAKE_CASE							)
																		lowercase_	:     Dict													=       kn
																		lowercase_	:     List[Any]													=       n

																		lowercase_	:     str													=       0

																		for k in _tmp[:-1]:
																								lowercase_	:     Tuple													=       _tmp[_tmp.index(__SCREAMING_SNAKE_CASE							) + 1]
																								for i in dict_of_neighbours[k]:
																														if i[0] == next_node:
																																				lowercase_	:     Optional[Any]													=       distance + int(i[1]							)
																		_tmp.append(__SCREAMING_SNAKE_CASE							)

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

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

						neighborhood_of_solution.sort(key=lambda __SCREAMING_SNAKE_CASE							: x[index_of_last_item_in_the_list]							)
						return neighborhood_of_solution
def 					snake_case_		(				__SCREAMING_SNAKE_CASE					: Tuple      ,      __SCREAMING_SNAKE_CASE					: List[Any]      ,      __SCREAMING_SNAKE_CASE					: Optional[int]      ,      __SCREAMING_SNAKE_CASE					: Optional[int]      ,      __SCREAMING_SNAKE_CASE					: Optional[Any]							):



						"""simple docstring"""





						lowercase_	:     Optional[int]													=       1
						lowercase_	:     List[str]													=       first_solution
						lowercase_	:     Dict													=       []
						lowercase_	:     List[str]													=       distance_of_first_solution
						lowercase_	:     Optional[Any]													=       solution

						while count <= iters:
												lowercase_	:     int													=       find_neighborhood(__SCREAMING_SNAKE_CASE      ,      __SCREAMING_SNAKE_CASE							)
												lowercase_	:     Any													=       0
												lowercase_	:     Dict													=       neighborhood[index_of_best_solution]
												lowercase_	:     Optional[Any]													=       len(__SCREAMING_SNAKE_CASE							) - 1

												lowercase_	:     Tuple													=       False
												while not found:
																		lowercase_	:     Optional[int]													=       0
																		while i < len(__SCREAMING_SNAKE_CASE							):
																								if best_solution[i] != solution[i]:
																														lowercase_	:     Tuple													=       best_solution[i]
																														lowercase_	:     Optional[int]													=       solution[i]
																														break
																								lowercase_	:     int													=       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]							)
																								lowercase_	:     Tuple													=       True
																								lowercase_	:     Optional[int]													=       best_solution[:-1]
																								lowercase_	:     Optional[Any]													=       neighborhood[index_of_best_solution][best_cost_index]
																								if cost < best_cost:
																														lowercase_	:     Optional[Any]													=       cost
																														lowercase_	:     int													=       solution
																		else:
																								lowercase_	:     Any													=       index_of_best_solution + 1
																								lowercase_	:     Any													=       neighborhood[index_of_best_solution]

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

												lowercase_	:     List[Any]													=       count + 1

						return best_solution_ever, best_cost
def 					snake_case_		(				__SCREAMING_SNAKE_CASE					: List[str]=None							):



						"""simple docstring"""





						lowercase_	:     Any													=       generate_neighbours(args.File							)

						lowercase_						, lowercase_	:     Union[str, Any]													=       generate_first_solution(
						    args.File      ,      __SCREAMING_SNAKE_CASE							)

						lowercase_						, lowercase_	:     Optional[int]													=       tabu_search(
						    __SCREAMING_SNAKE_CASE      ,      __SCREAMING_SNAKE_CASE      ,      __SCREAMING_SNAKE_CASE      ,      args.Iterations      ,      args.Size      ,      )

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


if __name__ == "__main__":
							_lowercase :  Any    							=       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'''




from .dependency_versions_table import deps
from .utils.versions import require_version, require_version_core


# define which module versions we always want to check at run time
# (usually the ones defined in `install_requires` in setup.py)
#
# order specific notes:
# - tqdm must be checked before tokenizers

UpperCamelCase__       :	Dict    = [
    '''python''',
    '''tqdm''',
    '''regex''',
    '''requests''',
    '''packaging''',
    '''filelock''',
    '''numpy''',
    '''tokenizers''',
    '''huggingface-hub''',
    '''safetensors''',
    '''accelerate''',
    '''pyyaml''',
]

for pkg in pkgs_to_check_at_runtime:
						if pkg in deps:
												if pkg == "tokenizers":
																		# must be loaded here, or else tqdm check may fail
																		from .utils import is_tokenizers_available

																		if not is_tokenizers_available():
																								continue  # not required, check version only if installed
												elif pkg == "accelerate":
																		# must be loaded here, or else tqdm check may fail
																		from .utils import is_accelerate_available

																		# Maybe switch to is_torch_available in the future here so that Accelerate is hard dep of
																		# Transformers with PyTorch
																		if not is_accelerate_available():
																								continue  # not required, check version only if installed

												require_version_core(deps[pkg])
						else:
												raise ValueError(f"can't find {pkg} in {deps.keys()}, check dependency_versions_table.py")


def 				lowerCAmelCase_   (	_lowerCamelCase:   List[Any]       ,      _lowerCamelCase:   Optional[int]=None					):
		require_version(deps[pkg]       ,      _lowerCamelCase					)