






'''simple docstring'''



import argparse
import copy



def  __UpperCAmelCase						(					SCREAMING_SNAKE_CASE__:						Tuple     )	->      Any:

   """simple docstring"""
   __a					  =     {}

   with open(a__     ) as f:
      for line in f:
         if line.split()[0] not in dict_of_neighbours:
            __a					  =     []
            _list.append([line.split()[1], line.split()[2]]     )
            __a					  =     _list
         else:
            dict_of_neighbours[line.split()[0]].append(
                [line.split()[1], line.split()[2]]     )
         if line.split()[1] not in dict_of_neighbours:
            __a					  =     []
            _list.append([line.split()[0], line.split()[2]]     )
            __a					  =     _list
         else:
            dict_of_neighbours[line.split()[1]].append(
                [line.split()[0], line.split()[2]]     )

   return dict_of_neighbours



def  __UpperCAmelCase						(					SCREAMING_SNAKE_CASE__:						Dict,       SCREAMING_SNAKE_CASE__:						List[Any]     )	->      List[str]:

   """simple docstring"""





   with open(a__     ) as f:
      __a					  =     f.read(1     )
   __a					  =     start_node

   __a					  =     []

   __a					  =     start_node

   __a					  =     0
   while visiting not in first_solution:
      __a					  =     10000
      for k in dict_of_neighbours[visiting]:
         if int(k[1]     ) < int(a__     ) and k[0] not in first_solution:
            __a					  =     k[1]
            __a					  =     k[0]

      first_solution.append(a__     )
      __a					  =     distance_of_first_solution + int(a__     )
      __a					  =     best_node

   first_solution.append(a__     )

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

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



def  __UpperCAmelCase						(					SCREAMING_SNAKE_CASE__:						List[Any],       SCREAMING_SNAKE_CASE__:						Tuple     )	->      List[str]:

   """simple docstring"""
   __a					  =     []

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

         __a					  =     copy.deepcopy(a__     )
         __a					  =     kn
         __a					  =     n

         __a					  =     0

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

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

   __a					  =     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  __UpperCAmelCase						(					SCREAMING_SNAKE_CASE__:						List[Any],       SCREAMING_SNAKE_CASE__:						Optional[Any],       SCREAMING_SNAKE_CASE__:						Optional[int],       SCREAMING_SNAKE_CASE__:						int,       SCREAMING_SNAKE_CASE__:						Optional[int]     )	->      str:

   """simple docstring"""
   __a					  =     1
   __a					  =     first_solution
   __a					  =     []
   __a					  =     distance_of_first_solution
   __a					  =     solution

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

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

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

      __a					  =     count + 1

   return best_solution_ever, best_cost



def  __UpperCAmelCase						(					SCREAMING_SNAKE_CASE__:						int=None     )	->      int:

   """simple docstring"""
   __a					  =     generate_neighbours(args.File     )

   __a  ,      __a					  =     generate_first_solution(
       args.File,       a__     )

   __a  ,      __a					  =     tabu_search(
       a__,       a__,       a__,       args.Iterations,       args.Size,       )

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


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



from .imports import is_rich_available


if is_rich_available():
		from rich.traceback import install

		install(show_locals=False)

else:
		raise ModuleNotFoundError('''To use the rich extension, install rich with `pip install rich`''')
