





'''simple docstring'''







import argparse
import glob
import logging
import os
import time
from argparse import Namespace

import numpy as np
import torch
from lightning_base import BaseTransformer, add_generic_args, generic_train
from torch.utils.data import DataLoader, TensorDataset

from transformers import glue_compute_metrics as compute_metrics
from transformers import glue_convert_examples_to_features as convert_examples_to_features
from transformers import glue_output_modes, glue_tasks_num_labels
from transformers import glue_processors as processors


_lowercase       						=  logging.getLogger(__name__)
class 			_lowercase						(       snake_case__					):
     _UpperCAmelCase										=					'''sequence-classification'''







     def __init__( self    ,   A__    ) ->	Any:
      if type(_A    ) == dict:
       snake_case				=			Namespace(**_A    )
      snake_case				=			glue_output_modes[hparams.task]
      snake_case				=			glue_tasks_num_labels[hparams.task]

      super().__init__(_A    ,   _A    ,   self.mode    )







     def     UpperCamelCase			( self    ,   **A__    ) ->	Optional[Any]:
      return self.model(**_A    )







     def     UpperCamelCase			( self    ,   A__    ,   A__    ) ->	Union[str, Any]:
      snake_case				=			{'input_ids': batch[0], 'attention_mask': batch[1], 'labels': batch[3]}

      if self.config.model_type not in ["distilbert", "bart"]:
       snake_case				=			batch[2] if self.config.model_type in ['bert', 'xlnet', 'albert'] else None

      snake_case				=			self(**_A    )
      snake_case				=			outputs[0]

      snake_case				=			self.trainer.lr_schedulers[0]['scheduler']
      snake_case				=			{'loss': loss, 'rate': lr_scheduler.get_last_lr()[-1]}
      return {"loss": loss, "log": tensorboard_logs}







     def     UpperCamelCase			( self    ) ->	Optional[Any]:
      snake_case				=			self.hparams
      snake_case				=			processors[args.task]()
      snake_case				=			processor.get_labels()

      for mode in ["train", "dev"]:
       snake_case				=			self._feature_file(_A    )
       if os.path.exists(_A    ) and not args.overwrite_cache:
        logger.info('''Loading features from cached file %s'''    ,   _A    )
       else:
        logger.info('''Creating features from dataset file at %s'''    ,   args.data_dir    )
        snake_case				=			(
            processor.get_dev_examples(args.data_dir    )
            if mode == 'dev'
            else processor.get_train_examples(args.data_dir    )
        )
        snake_case				=			convert_examples_to_features(
            _A    ,   self.tokenizer    ,   max_length=args.max_seq_length    ,   label_list=self.labels    ,   output_mode=args.glue_output_mode    ,   )
        logger.info('''Saving features into cached file %s'''    ,   _A    )
        torch.save(_A    ,   _A    )







     def     UpperCamelCase			( self    ,   A__    ,   A__    ,   A__ = False    ) ->	Tuple:
      snake_case				=			'dev' if mode == 'test' else mode

      snake_case				=			self._feature_file(_A    )
      logger.info('''Loading features from cached file %s'''    ,   _A    )
      snake_case				=			torch.load(_A    )
      snake_case				=			torch.tensor([f.input_ids for f in features]    ,   dtype=torch.long    )
      snake_case				=			torch.tensor([f.attention_mask for f in features]    ,   dtype=torch.long    )
      snake_case				=			torch.tensor([f.token_type_ids for f in features]    ,   dtype=torch.long    )
      if self.hparams.glue_output_mode == "classification":
       snake_case				=			torch.tensor([f.label for f in features]    ,   dtype=torch.long    )
      elif self.hparams.glue_output_mode == "regression":
       snake_case				=			torch.tensor([f.label for f in features]    ,   dtype=torch.float    )

      return DataLoader(
          TensorDataset(_A    ,   _A    ,   _A    ,   _A    )    ,   batch_size=_A    ,   shuffle=_A    ,   )







     def     UpperCamelCase			( self    ,   A__    ,   A__    ) ->	List[str]:
      snake_case				=			{'input_ids': batch[0], 'attention_mask': batch[1], 'labels': batch[3]}

      if self.config.model_type not in ["distilbert", "bart"]:
       snake_case				=			batch[2] if self.config.model_type in ['bert', 'xlnet', 'albert'] else None

      snake_case				=			self(**_A    )
      snake_case				=			outputs[:2]
      snake_case				=			logits.detach().cpu().numpy()
      snake_case				=			inputs['labels'].detach().cpu().numpy()

      return {"val_loss": tmp_eval_loss.detach().cpu(), "pred": preds, "target": out_label_ids}







     def     UpperCamelCase			( self    ,   A__    ) ->	Any:
      snake_case				=			torch.stack([x['''val_loss'''] for x in outputs]    ).mean().detach().cpu().item()
      snake_case				=			np.concatenate([x['''pred'''] for x in outputs]    ,   axis=0    )

      if self.hparams.glue_output_mode == "classification":
       snake_case				=			np.argmax(_A    ,   axis=1    )
      elif self.hparams.glue_output_mode == "regression":
       snake_case				=			np.squeeze(_A    )

      snake_case				=			np.concatenate([x['''target'''] for x in outputs]    ,   axis=0    )
      snake_case				=			[[] for _ in range(out_label_ids.shape[0]    )]
      snake_case				=			[[] for _ in range(out_label_ids.shape[0]    )]

      snake_case				=			{**{'val_loss': val_loss_mean}, **compute_metrics(self.hparams.task    ,   _A    ,   _A    )}

      snake_case				=			dict(results.items()    )
      snake_case				=			results
      return ret, preds_list, out_label_list







     def     UpperCamelCase			( self    ,   A__    ) ->	Optional[Any]:
      snake_case				=			self._eval_end(_A    )
      snake_case				=			ret['log']
      return {"val_loss": logs["val_loss"], "log": logs, "progress_bar": logs}







     def     UpperCamelCase			( self    ,   A__    ) ->	Tuple:
      snake_case				=			self._eval_end(_A    )
      snake_case				=			ret['log']
      # `val_loss` is the key returned by `self._eval_end()` but actually refers to `test_loss`
      return {"avg_test_loss": logs["val_loss"], "log": logs, "progress_bar": logs}







     @staticmethod
     def     UpperCamelCase			( A__    ,   A__    ) ->	Any:
      BaseTransformer.add_model_specific_args(_A    ,   _A    )
      parser.add_argument(
          '''--max_seq_length'''    ,   default=1_28    ,   type=_A    ,   help=(
              '''The maximum total input sequence length after tokenization. Sequences longer '''
              '''than this will be truncated, sequences shorter will be padded.'''
          )    ,   )

      parser.add_argument(
          '''--task'''    ,   default=''''''    ,   type=_A    ,   required=_A    ,   help='''The GLUE task to run'''    ,   )
      parser.add_argument(
          '''--gpus'''    ,   default=0    ,   type=_A    ,   help='''The number of GPUs allocated for this, it is by default 0 meaning none'''    ,   )

      parser.add_argument(
          '''--overwrite_cache'''    ,   action='''store_true'''    ,   help='''Overwrite the cached training and evaluation sets'''    )

      return parser




def    __UpperCamelCase	(	) ->Tuple:
 snake_case				=			argparse.ArgumentParser()
 add_generic_args(a					,   os.getcwd()     )
 snake_case				=			GLUETransformer.add_model_specific_args(a					,   os.getcwd()     )
 snake_case				=			parser.parse_args()

 # If output_dir not provided, a folder will be generated in pwd
 if args.output_dir is None:
  snake_case				=			os.path.join(
      '''./results'''					,   f"""{args.task}_{time.strftime('%Y%m%d_%H%M%S'     )}"""					,   )
  os.makedirs(args.output_dir     )

 snake_case				=			GLUETransformer(a     )
 snake_case				=			generic_train(a					,   a     )

 # Optionally, predict on dev set and write to output_dir
 if args.do_predict:
  snake_case				=			sorted(glob.glob(os.path.join(args.output_dir					,   '''checkpoint-epoch=*.ckpt'''     )					,   recursive=a     )     )
  snake_case				=			model.load_from_checkpoint(checkpoints[-1]     )
  return trainer.test(a     )


if __name__ == "__main__":
   main()








'''simple docstring'''







import argparse
import copy

def    __UpperCamelCase	(	a    : Union[str, Any]     ) ->Tuple:
 snake_case				=			{}

 with open(a     ) as f:
  for line in f:
   if line.split()[0] not in dict_of_neighbours:
    snake_case				=			[]
    _list.append([line.split()[1], line.split()[2]]     )
    snake_case				=			_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				=			[]
    _list.append([line.split()[0], line.split()[2]]     )
    snake_case				=			_list
   else:
    dict_of_neighbours[line.split()[1]].append(
        [line.split()[0], line.split()[2]]     )

 return dict_of_neighbours

def    __UpperCamelCase	(	a    : Dict					,   a    : Tuple     ) ->int:

 with open(a     ) as f:
  snake_case				=			f.read(1     )
 snake_case				=			start_node

 snake_case				=			[]

 snake_case				=			start_node

 snake_case				=			0
 while visiting not in first_solution:
  snake_case				=			1_0000
  for k in dict_of_neighbours[visiting]:
   if int(k[1]     ) < int(a     ) and k[0] not in first_solution:
    snake_case				=			k[1]
    snake_case				=			k[0]

  first_solution.append(a     )
  snake_case				=			distance_of_first_solution + int(a     )
  snake_case				=			best_node

 first_solution.append(a     )

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

 snake_case				=			(
     distance_of_first_solution
     + int(dict_of_neighbours[first_solution[-2]][position][1]     )
     - 1_0000
 )
 return first_solution, distance_of_first_solution

def    __UpperCamelCase	(	a    : Optional[int]					,   a    : str     ) ->str:
 snake_case				=			[]

 for n in solution[1:-1]:
  snake_case				=			solution.index(a     )
  for kn in solution[1:-1]:
   snake_case				=			solution.index(a     )
   if n == kn:
    continue

   snake_case				=			copy.deepcopy(a     )
   snake_case				=			kn
   snake_case				=			n

   snake_case				=			0

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

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

 snake_case				=			len(neighborhood_of_solution[0]     ) - 1

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

def    __UpperCamelCase	(	a    : Any					,   a    : Optional[Any]					,   a    : int					,   a    : Optional[int]					,   a    : Union[str, Any]     ) ->List[Any]:
 snake_case				=			1
 snake_case				=			first_solution
 snake_case				=			[]
 snake_case				=			distance_of_first_solution
 snake_case				=			solution

 while count <= iters:
  snake_case				=			find_neighborhood(a					,   a     )
  snake_case				=			0
  snake_case				=			neighborhood[index_of_best_solution]
  snake_case				=			len(a     ) - 1

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

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

  snake_case				=			count + 1

 return best_solution_ever, best_cost

def    __UpperCamelCase	(	a    : Union[str, Any]=None     ) ->Optional[Any]:
 snake_case				=			generate_neighbours(args.File     )

 snake_case				,		snake_case				=			generate_first_solution(
     args.File					,   a     )

 snake_case				,		snake_case				=			tabu_search(
     a					,   a					,   a					,   args.Iterations					,   args.Size					,   )

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


if __name__ == "__main__":
   _lowercase       						=			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())

