


import argparse
import copy


def 			_UpperCamelCase				( lowercase__ ):
						__SCREAMING_SNAKE_CASE		:	Tuple						     =						{}

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

						return dict_of_neighbours


def 			_UpperCamelCase				( lowercase__       ,			lowercase__ ):

						with open(lowercase__ ) as f:
												__SCREAMING_SNAKE_CASE		:	Optional[int]						     =						f.read(1 )
						__SCREAMING_SNAKE_CASE		:	Any						     =						start_node

						__SCREAMING_SNAKE_CASE		:	Union[str, Any]						     =						[]

						__SCREAMING_SNAKE_CASE		:	Dict						     =						start_node

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

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

						first_solution.append(lowercase__ )

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

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


def 			_UpperCamelCase				( lowercase__       ,			lowercase__ ):
						__SCREAMING_SNAKE_CASE		:	Union[str, Any]						     =						[]

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

																		__SCREAMING_SNAKE_CASE		:	str						     =						copy.deepcopy(lowercase__ )
																		__SCREAMING_SNAKE_CASE		:	List[str]						     =						kn
																		__SCREAMING_SNAKE_CASE		:	List[str]						     =						n

																		__SCREAMING_SNAKE_CASE		:	List[Any]						     =						0

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

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

						__SCREAMING_SNAKE_CASE		:	List[str]						     =						len(neighborhood_of_solution[0] ) - 1

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


def 			_UpperCamelCase				( lowercase__       ,			lowercase__       ,			lowercase__       ,			lowercase__       ,			lowercase__ ):
						__SCREAMING_SNAKE_CASE		:	List[str]						     =						1
						__SCREAMING_SNAKE_CASE		:	List[str]						     =						first_solution
						__SCREAMING_SNAKE_CASE		:	int						     =						[]
						__SCREAMING_SNAKE_CASE		:	Dict						     =						distance_of_first_solution
						__SCREAMING_SNAKE_CASE		:	Union[str, Any]						     =						solution

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

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

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

												__SCREAMING_SNAKE_CASE		:	Optional[int]						     =						count + 1

						return best_solution_ever, best_cost


def 			_UpperCamelCase				( lowercase__=None ):
						__SCREAMING_SNAKE_CASE		:	int						     =						generate_neighbours(args.File )

						__SCREAMING_SNAKE_CASE		:	str						     =						generate_first_solution(
						    args.File       ,			lowercase__ )

						__SCREAMING_SNAKE_CASE		:	List[Any]						     =						tabu_search(
						    lowercase__       ,			lowercase__       ,			lowercase__       ,			args.Iterations       ,			args.Size       ,			)

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


if __name__ == "__main__":
						__lowerCAmelCase      :					List[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 collections.abc import Callable
from math import pi, sqrt
from random import uniform
from statistics import mean




def 		lowerCAmelCase_ (						lowerCamelCase ):

				# A local function to see if a dot lands in the circle.
				def is_in_circle(lowerCamelCase						,  lowerCamelCase ) -> bool:
								__magic_name__						:						Dict										=sqrt((x**2) + (y**2) )
								# Our circle has a radius of 1, so a distance
								# greater than 1 would land outside the circle.
								return distance_from_centre <= 1

				# The proportion of guesses that landed in the circle
				__magic_name__						:						Union[str, Any]										=mean(
				    int(is_in_circle(uniform(-1.0						,  1.0 )						,  uniform(-1.0						,  1.0 ) ) )
				    for _ in range(lowerCamelCase ) )
				# The ratio of the area for circle to square is pi/4.
				__magic_name__						:						List[Any]										=proportion * 4
				print(F"The estimated value of pi is {pi_estimate}" )
				print(F"The numpy value of pi is {pi}" )
				print(F"The total error is {abs(pi - pi_estimate )}" )




def 		lowerCAmelCase_ (						lowerCamelCase						,  lowerCamelCase						,  lowerCamelCase = 0.0						,  lowerCamelCase = 1.0						,  ):
				return mean(
				    function_to_integrate(uniform(lowerCamelCase						,  lowerCamelCase ) ) for _ in range(lowerCamelCase ) ) * (max_value - min_value)




def 		lowerCAmelCase_ (						lowerCamelCase						,  lowerCamelCase = 0.0						,  lowerCamelCase = 1.0 ):

				def identity_function(lowerCamelCase ) -> float:
								return x

				__magic_name__						:						Optional[int]										=area_under_curve_estimator(
				    lowerCamelCase						,  lowerCamelCase						,  lowerCamelCase						,  lowerCamelCase )
				__magic_name__						:						str										=(max_value * max_value - min_value * min_value) / 2

				print("""******************""" )
				print(F"Estimating area under y=x where x varies from {min_value} to {max_value}" )
				print(F"Estimated value is {estimated_value}" )
				print(F"Expected value is {expected_value}" )
				print(F"Total error is {abs(estimated_value - expected_value )}" )
				print("""******************""" )




def 		lowerCAmelCase_ (						lowerCamelCase ):

				def function_to_integrate(lowerCamelCase ) -> float:
								return sqrt(4.0 - x * x )

				__magic_name__						:						Dict										=area_under_curve_estimator(
				    lowerCamelCase						,  lowerCamelCase						,  0.0						,  2.0 )

				print("""******************""" )
				print("""Estimating pi using area_under_curve_estimator""" )
				print(F"Estimated value is {estimated_value}" )
				print(F"Expected value is {pi}" )
				print(F"Total error is {abs(estimated_value - pi )}" )
				print("""******************""" )


if __name__ == "__main__":
							import doctest

							doctest.testmod()




