


"""simple docstring"""







import argparse
import copy
def  a__      (    SCREAMING_SNAKE_CASE   :   int    ):


  '''simple docstring'''







  lowerCAmelCase					:					List[Any]								=							{}

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

  return dict_of_neighbours
def  a__      (    SCREAMING_SNAKE_CASE   :   Optional[int]    ,				SCREAMING_SNAKE_CASE   :   Tuple    ):


  '''simple docstring'''







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

  lowerCAmelCase					:					Tuple								=							[]

  lowerCAmelCase					:					List[str]								=							start_node

  lowerCAmelCase					:					List[Any]								=							0
  while visiting not in first_solution:
    lowerCAmelCase					:					Optional[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:
        lowerCAmelCase					:					Union[str, Any]								=							k[1]
        lowerCAmelCase					:					Dict								=							k[0]

    first_solution.append(SCREAMING_SNAKE_CASE    )
    lowerCAmelCase					:					Any								=							distance_of_first_solution + int(SCREAMING_SNAKE_CASE    )
    lowerCAmelCase					:					List[Any]								=							best_node

  first_solution.append(SCREAMING_SNAKE_CASE    )

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

  lowerCAmelCase					:					Union[str, Any]								=							(
      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  a__      (    SCREAMING_SNAKE_CASE   :   Any    ,				SCREAMING_SNAKE_CASE   :   Dict    ):


  '''simple docstring'''







  lowerCAmelCase					:					Tuple								=							[]

  for n in solution[1:-1]:
    lowerCAmelCase					:					int								=							solution.index(SCREAMING_SNAKE_CASE    )
    for kn in solution[1:-1]:
      lowerCAmelCase					:					Optional[Any]								=							solution.index(SCREAMING_SNAKE_CASE    )
      if n == kn:
        continue

      lowerCAmelCase					:					int								=							copy.deepcopy(SCREAMING_SNAKE_CASE    )
      lowerCAmelCase					:					Union[str, Any]								=							kn
      lowerCAmelCase					:					Optional[int]								=							n

      lowerCAmelCase					:					int								=							0

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

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

  lowerCAmelCase					:					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  a__      (    SCREAMING_SNAKE_CASE   :   Union[str, Any]    ,				SCREAMING_SNAKE_CASE   :   Any    ,				SCREAMING_SNAKE_CASE   :   Union[str, Any]    ,				SCREAMING_SNAKE_CASE   :   Dict    ,				SCREAMING_SNAKE_CASE   :   str    ):


  '''simple docstring'''







  lowerCAmelCase					:					Tuple								=							1
  lowerCAmelCase					:					str								=							first_solution
  lowerCAmelCase					:					str								=							[]
  lowerCAmelCase					:					Tuple								=							distance_of_first_solution
  lowerCAmelCase					:					Dict								=							solution

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

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

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

    lowerCAmelCase					:					List[Any]								=							count + 1

  return best_solution_ever, best_cost
def  a__      (    SCREAMING_SNAKE_CASE   :   Optional[Any]=None    ):


  '''simple docstring'''







  lowerCAmelCase					:					Optional[Any]								=							generate_neighbours(args.File    )

  lowerCAmelCase						,  lowerCAmelCase					:					Optional[Any]								=							generate_first_solution(
      args.File    ,				SCREAMING_SNAKE_CASE    )

  lowerCAmelCase						,  lowerCAmelCase					:					Union[str, Any]								=							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__":
     lowerCAmelCase__				    =       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 __future__ import annotations

from math import pi

# Define the Reduced Planck Constant ℏ (H bar), speed of light C, value of
# Pi and the function
lowerCAmelCase__				    =       1.0_5_4_5_7_1_8_1_7e-3_4  # unit of ℏ : J * s

lowerCAmelCase__				    =       3e8  # unit of c : m * s^-1
def  a__      (    SCREAMING_SNAKE_CASE   :   float    ,				SCREAMING_SNAKE_CASE   :   float    ,				SCREAMING_SNAKE_CASE   :   float    ):


  '''simple docstring'''







  if (force, area, distance).count(0    ) != 1:
    raise ValueError("One and only one argument must be 0"    )
  if force < 0:
    raise ValueError("Magnitude of force can not be negative"    )
  if distance < 0:
    raise ValueError("Distance can not be negative"    )
  if area < 0:
    raise ValueError("Area can not be negative"    )
  if force == 0:
    lowerCAmelCase					:					Any								=							(REDUCED_PLANCK_CONSTANT * SPEED_OF_LIGHT * pi**2 * area) / (
        2_4_0 * (distance) ** 4
    )
    return {"force": force}
  elif area == 0:
    lowerCAmelCase					:					Any								=							(2_4_0 * force * (distance) ** 4) / (
        REDUCED_PLANCK_CONSTANT * SPEED_OF_LIGHT * pi**2
    )
    return {"area": area}
  elif distance == 0:
    lowerCAmelCase					:					Dict								=							(
        (REDUCED_PLANCK_CONSTANT * SPEED_OF_LIGHT * pi**2 * area) / (2_4_0 * force)
    ) ** (1 / 4)
    return {"distance": distance}
  raise ValueError("One and only one argument must be 0"    )


# Run doctest
if __name__ == "__main__":
     import doctest

     doctest.testmod()





