



"""simple docstring"""

import os
from shutil import copyfile
from typing import Any, Dict, List, Optional, Tuple

import sentencepiece as spm

from ...tokenization_utils import PreTrainedTokenizer
from ...utils import logging


a_			   =					logging.get_logger(__name__)

a_			   =					'''▁'''

a_			   =					{'''vocab_file''': '''sentencepiece.bpe.model'''}

a_			   =					{
    '''vocab_file''': {
        '''facebook/xglm-564M''': '''https://huggingface.co/facebook/xglm-564M/resolve/main/sentencepiece.bpe.model''',
    }
}

a_			   =					{
    '''facebook/xglm-564M''': 2048,
}







class    __lowercase     (					_UpperCAmelCase):







						"""simple docstring"""







						_A		:							List[Any]							       =		VOCAB_FILES_NAMES
						_A		:							Optional[Any]							       =		PRETRAINED_VOCAB_FILES_MAP
						_A		:							Dict							       =		PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES
						_A		:							int							       =		["""input_ids""", """attention_mask"""]







						def __init__(self   ,		lowercase__   ,		lowercase__="<s>"   ,		lowercase__="</s>"   ,		lowercase__="</s>"   ,		lowercase__="<s>"   ,		lowercase__="<unk>"   ,		lowercase__="<pad>"   ,		lowercase__ = None   ,		**lowercase__   ,		):
											snake_case_					:		List[str] 					=					{} if sp_model_kwargs is None else sp_model_kwargs

											# Compatibility with the original tokenizer
											snake_case_					:		Tuple 					=					7
											snake_case_					:		Any 					=					[f'<madeupword{i}>' for i in range(self.num_madeup_words       )]

											snake_case_					:		Tuple 					=					kwargs.get("""additional_special_tokens"""   ,		[]       )
											kwargs["additional_special_tokens"] += [
											    word for word in madeup_words if word not in kwargs["additional_special_tokens"]
											]

											super().__init__(
											    bos_token=lowercase__   ,		eos_token=lowercase__   ,		unk_token=lowercase__   ,		sep_token=lowercase__   ,		cls_token=lowercase__   ,		pad_token=lowercase__   ,		sp_model_kwargs=self.sp_model_kwargs   ,		**lowercase__   ,		)

											snake_case_					:		List[Any] 					=					spm.SentencePieceProcessor(**self.sp_model_kwargs       )
											self.sp_model.Load(str(lowercase__       )       )
											snake_case_					:		Optional[int] 					=					vocab_file

											# Original fairseq vocab and spm vocab must be "aligned":
											# Vocab    |    0    |    1    |   2    |    3    |  4  |  5  |  6  |   7   |   8   |  9
											# -------- | ------- | ------- | ------ | ------- | --- | --- | --- | ----- | ----- | ----
											# fairseq  | '<s>'   | '<pad>' | '</s>' | '<unk>' | ',' | '.' | '▁' | 's'   | '▁de' | '-'
											# spm      | '<unk>' | '<s>'   | '</s>' | ','     | '.' | '▁' | 's' | '▁de' | '-'   | '▁a'

											# The first "real" token "," has position 4 in the original fairseq vocab and position 3 in the spm vocab
											snake_case_					:		str 					=					1

											# Mimic fairseq token-to-id alignment for the first 4 token
											snake_case_					:		Any 					=					{"""<s>""": 0, """<pad>""": 1, """</s>""": 2, """<unk>""": 3}

											snake_case_					:		List[str] 					=					len(self.sp_model       )
											snake_case_					:		List[str] 					=					{f'<madeupword{i}>': sp_size + i + self.fairseq_offset for i in range(self.num_madeup_words       )}
											self.fairseq_tokens_to_ids.update(lowercase__       )

											snake_case_					:		Any 					=					{v: k for k, v in self.fairseq_tokens_to_ids.items()}







						def __getstate__(self       ):
											snake_case_					:		List[str] 					=					self.__dict__.copy()
											snake_case_					:		Dict 					=					None
											snake_case_					:		int 					=					self.sp_model.serialized_model_proto()
											return state







						def __setstate__(self   ,		lowercase__       ):
											snake_case_					:		int 					=					d

											# for backward compatibility
											if not hasattr(self   ,		"""sp_model_kwargs"""       ):
																snake_case_					:		Tuple 					=					{}

											snake_case_					:		Dict 					=					spm.SentencePieceProcessor(**self.sp_model_kwargs       )
											self.sp_model.LoadFromSerializedProto(self.sp_model_proto       )







						def 						__UpperCamelCase							(self   ,		lowercase__   ,		lowercase__ = None       ):

											if token_ids_a is None:
																return [self.sep_token_id] + token_ids_a
											snake_case_					:		Tuple 					=					[self.sep_token_id]
											return sep + token_ids_a + sep + sep + token_ids_a







						def 						__UpperCamelCase							(self   ,		lowercase__   ,		lowercase__ = None   ,		lowercase__ = False       ):

											if already_has_special_tokens:
																return super().get_special_tokens_mask(
																    token_ids_a=lowercase__   ,		token_ids_a=lowercase__   ,		already_has_special_tokens=lowercase__       )

											if token_ids_a is None:
																return [1] + ([0] * len(lowercase__       ))
											return [1] + ([0] * len(lowercase__       )) + [1, 1] + ([0] * len(lowercase__       ))







						def 						__UpperCamelCase							(self   ,		lowercase__   ,		lowercase__ = None       ):
											snake_case_					:		Union[str, Any] 					=					[self.sep_token_id]

											if token_ids_a is None:
																return len(sep + token_ids_a       ) * [0]
											return len(sep + token_ids_a + sep + sep + token_ids_a       ) * [0]







						@property
						def 						__UpperCamelCase							(self       ):
											return len(self.sp_model       ) + self.fairseq_offset + self.num_madeup_words







						def 						__UpperCamelCase							(self       ):
											snake_case_					:		Union[str, Any] 					=					{self.convert_ids_to_tokens(lowercase__       ): i for i in range(self.vocab_size       )}
											vocab.update(self.added_tokens_encoder       )
											return vocab







						def 						__UpperCamelCase							(self   ,		lowercase__       ):
											return self.sp_model.encode(lowercase__   ,		out_type=lowercase__       )







						def 						__UpperCamelCase							(self   ,		lowercase__       ):
											if token in self.fairseq_tokens_to_ids:
																return self.fairseq_tokens_to_ids[token]
											snake_case_					:		Union[str, Any] 					=					self.sp_model.PieceToId(lowercase__       )

											# Need to return unknown token if the SP model returned 0
											return spm_id + self.fairseq_offset if spm_id else self.unk_token_id







						def 						__UpperCamelCase							(self   ,		lowercase__       ):
											if index in self.fairseq_ids_to_tokens:
																return self.fairseq_ids_to_tokens[index]
											return self.sp_model.IdToPiece(index - self.fairseq_offset       )







						def 						__UpperCamelCase							(self   ,		lowercase__       ):
											snake_case_					:		Optional[Any] 					=					"""""".join(lowercase__       ).replace(lowercase__   ,		""" """       ).strip()
											return out_string







						def 						__UpperCamelCase							(self   ,		lowercase__   ,		lowercase__ = None       ):
											if not os.path.isdir(lowercase__       ):
																logger.error(f'Vocabulary path ({save_directory}) should be a directory'       )
																return
											snake_case_					:		Any 					=					os.path.join(
											    lowercase__   ,		(filename_prefix + """-""" if filename_prefix else """""") + VOCAB_FILES_NAMES["""vocab_file"""]       )

											if os.path.abspath(self.vocab_file       ) != os.path.abspath(lowercase__       ) and os.path.isfile(self.vocab_file       ):
																copyfile(self.vocab_file   ,		lowercase__       )
											elif not os.path.isfile(self.vocab_file       ):
																with open(lowercase__   ,		"""wb"""       ) as fi:
																					snake_case_					:		Dict 					=					self.sp_model.serialized_model_proto()
																					fi.write(lowercase__       )

											return (out_vocab_file,)









"""simple docstring"""

import argparse
import copy







def 							SCREAMING_SNAKE_CASE__      (		SCREAMING_SNAKE_CASE__ :  Any			):



					"""simple docstring"""





					snake_case_					:		List[Any] 					=					{}

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

					return dict_of_neighbours







def 							SCREAMING_SNAKE_CASE__      (		SCREAMING_SNAKE_CASE__ :  List[Any]				,    SCREAMING_SNAKE_CASE__ :  str			):



					"""simple docstring"""





					with open(SCREAMING_SNAKE_CASE__			) as f:
										snake_case_					:		Optional[Any] 					=					f.read(1			)
					snake_case_					:		Union[str, Any] 					=					start_node

					snake_case_					:		Dict 					=					[]

					snake_case_					:		Union[str, Any] 					=					start_node

					snake_case_					:		Tuple 					=					0
					while visiting not in first_solution:
										snake_case_					:		int 					=					1_0_0_0_0
										for k in dict_of_neighbours[visiting]:
															if int(k[1]			) < int(SCREAMING_SNAKE_CASE__			) and k[0] not in first_solution:
																				snake_case_					:		Union[str, Any] 					=					k[1]
																				snake_case_					:		Any 					=					k[0]

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

					first_solution.append(SCREAMING_SNAKE_CASE__			)

					snake_case_					:		Optional[Any] 					=					0
					for k in dict_of_neighbours[first_solution[-2]]:
										if k[0] == start_node:
															break
										position += 1

					snake_case_					:		int 					=					(
					    distance_of_first_solution
					    + int(dict_of_neighbours[first_solution[-2]][position][1]			)
					    - 1_0_0_0_0
					)
					return first_solution, distance_of_first_solution







def 							SCREAMING_SNAKE_CASE__      (		SCREAMING_SNAKE_CASE__ :  Union[str, Any]				,    SCREAMING_SNAKE_CASE__ :  Optional[int]			):



					"""simple docstring"""





					snake_case_					:		Union[str, Any] 					=					[]

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

															snake_case_					:		Optional[Any] 					=					copy.deepcopy(SCREAMING_SNAKE_CASE__			)
															snake_case_					:		int 					=					kn
															snake_case_					:		Dict 					=					n

															snake_case_					:		Optional[int] 					=					0

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

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

					snake_case_					:		Optional[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 							SCREAMING_SNAKE_CASE__      (		SCREAMING_SNAKE_CASE__ :  List[str]				,    SCREAMING_SNAKE_CASE__ :  Dict				,    SCREAMING_SNAKE_CASE__ :  List[Any]				,    SCREAMING_SNAKE_CASE__ :  str				,    SCREAMING_SNAKE_CASE__ :  List[Any]			):



					"""simple docstring"""





					snake_case_					:		Dict 					=					1
					snake_case_					:		List[Any] 					=					first_solution
					snake_case_					:		List[Any] 					=					[]
					snake_case_					:		Optional[Any] 					=					distance_of_first_solution
					snake_case_					:		Dict 					=					solution

					while count <= iters:
										snake_case_					:		List[str] 					=					find_neighborhood(SCREAMING_SNAKE_CASE__				,    SCREAMING_SNAKE_CASE__			)
										snake_case_					:		List[Any] 					=					0
										snake_case_					:		List[Any] 					=					neighborhood[index_of_best_solution]
										snake_case_					:		Union[str, Any] 					=					len(SCREAMING_SNAKE_CASE__			) - 1

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

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

										snake_case_					:		List[str] 					=					count + 1

					return best_solution_ever, best_cost







def 							SCREAMING_SNAKE_CASE__      (		SCREAMING_SNAKE_CASE__ :  Optional[Any]=None			):



					"""simple docstring"""





					snake_case_					:		Tuple 					=					generate_neighbours(args.File			)

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

					snake_case_					,			snake_case_					:		Dict 					=					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__":
			a_			   =					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())




