





'''simple docstring'''






import numpy




class  _A :

		def __init__(   self					:   Any  ,      __magic_name__					:   numpy.ndarray  ,      __magic_name__					:   numpy.ndarray			)					->    None:


					"""simple docstring"""

					__snake_case					:      Optional[int]							      =     input_array

					# Random initial weights are assigned where first argument is the
					# number of nodes in previous layer and second argument is the
					# number of nodes in the next layer.

					# Random initial weights are assigned.
					# self.input_array.shape[1] is used to represent number of nodes in input layer.
					# First hidden layer consists of 4 nodes.
					__snake_case					:      str							      =     numpy.random.rand(
					    self.input_array.shape[1]  ,      4			)

					# Random initial values for the first hidden layer.
					# First hidden layer has 4 nodes.
					# Second hidden layer has 3 nodes.
					__snake_case					:      Dict							      =     numpy.random.rand(
					    4  ,      3			)

					# Random initial values for the second hidden layer.
					# Second hidden layer has 3 nodes.
					# Output layer has 1 node.
					__snake_case					:      Any							      =     numpy.random.rand(3  ,      1			)

					# Real output values provided.
					__snake_case					:      Optional[int]							      =     output_array

					# Predicted output values by the neural network.
					# Predicted_output array initially consists of zeroes.
					__snake_case					:      Tuple							      =     numpy.zeros(output_array.shape			)

		def 	lowercase__     (   self					:   Optional[int]			)					->    numpy.ndarray:


					"""simple docstring"""

					__snake_case					:      Dict							      =     sigmoid(
					    numpy.dot(self.input_array  ,      self.input_layer_and_first_hidden_layer_weights			)			)

					# layer_between_first_hidden_layer_and_second_hidden_layer is the layer
					# connecting the first hidden set of nodes with the second hidden set of nodes.
					__snake_case					:      str							      =     sigmoid(
					    numpy.dot(
					        self.layer_between_input_and_first_hidden_layer  ,      self.first_hidden_layer_and_second_hidden_layer_weights  ,      )			)

					# layer_between_second_hidden_layer_and_output is the layer connecting
					# second hidden layer with the output node.
					__snake_case					:      List[str]							      =     sigmoid(
					    numpy.dot(
					        self.layer_between_first_hidden_layer_and_second_hidden_layer  ,      self.second_hidden_layer_and_output_layer_weights  ,      )			)

					return self.layer_between_second_hidden_layer_and_output

		def 	lowercase__     (   self					:   Tuple			)					->    None:


					"""simple docstring"""

					__snake_case					:      Optional[Any]							      =     numpy.dot(
					    self.layer_between_first_hidden_layer_and_second_hidden_layer.T  ,      2
					    * (self.output_array - self.predicted_output)
					    * sigmoid_derivative(self.predicted_output			)  ,      )
					__snake_case					:      Union[str, Any]							      =     numpy.dot(
					    self.layer_between_input_and_first_hidden_layer.T  ,      numpy.dot(
					        2
					        * (self.output_array - self.predicted_output)
					        * sigmoid_derivative(self.predicted_output			)  ,      self.second_hidden_layer_and_output_layer_weights.T  ,      )
					    * sigmoid_derivative(
					        self.layer_between_first_hidden_layer_and_second_hidden_layer			)  ,      )
					__snake_case					:      Tuple							      =     numpy.dot(
					    self.input_array.T  ,      numpy.dot(
					        numpy.dot(
					            2
					            * (self.output_array - self.predicted_output)
					            * sigmoid_derivative(self.predicted_output			)  ,      self.second_hidden_layer_and_output_layer_weights.T  ,      )
					        * sigmoid_derivative(
					            self.layer_between_first_hidden_layer_and_second_hidden_layer			)  ,      self.first_hidden_layer_and_second_hidden_layer_weights.T  ,      )
					    * sigmoid_derivative(self.layer_between_input_and_first_hidden_layer			)  ,      )

					self.input_layer_and_first_hidden_layer_weights += (
					    updated_input_layer_and_first_hidden_layer_weights
					)
					self.first_hidden_layer_and_second_hidden_layer_weights += (
					    updated_first_hidden_layer_and_second_hidden_layer_weights
					)
					self.second_hidden_layer_and_output_layer_weights += (
					    updated_second_hidden_layer_and_output_layer_weights
					)

		def 	lowercase__     (   self					:   Any  ,      __magic_name__					:   numpy.ndarray  ,      __magic_name__					:   int  ,      __magic_name__					:   bool			)					->    None:


					"""simple docstring"""

					for iteration in range(1  ,      iterations + 1			):
								__snake_case					:      Dict							      =     self.feedforward()
								self.back_propagation()
								if give_loss:
											__snake_case					:      int							      =     numpy.mean(numpy.square(output - self.feedforward()			)			)
											print(f'''Iteration {iteration} Loss: {loss}'''			)

		def 	lowercase__     (   self					:   Union[str, Any]  ,      __magic_name__					:   numpy.ndarray			)					->    int:


					"""simple docstring"""

					__snake_case					:      Dict							      =     input_arr

					__snake_case					:      List[str]							      =     sigmoid(
					    numpy.dot(self.array  ,      self.input_layer_and_first_hidden_layer_weights			)			)

					__snake_case					:      List[str]							      =     sigmoid(
					    numpy.dot(
					        self.layer_between_input_and_first_hidden_layer  ,      self.first_hidden_layer_and_second_hidden_layer_weights  ,      )			)

					__snake_case					:      Optional[Any]							      =     sigmoid(
					    numpy.dot(
					        self.layer_between_first_hidden_layer_and_second_hidden_layer  ,      self.second_hidden_layer_and_output_layer_weights  ,      )			)

					return int(self.layer_between_second_hidden_layer_and_output > 0.6			)







def 					_a						(       _lowerCamelCase ) ->				numpy.ndarray:



			"""simple docstring"""


			return 1 / (1 + numpy.exp(-value ))







def 					_a						(       _lowerCamelCase ) ->				numpy.ndarray:



			"""simple docstring"""


			return (value) * (1 - (value))







def 					_a						(       ) ->				int:



			"""simple docstring"""


			__snake_case					:      int							      =     numpy.array(
			    (
			        [0, 0, 0],
			        [0, 0, 1],
			        [0, 1, 0],
			        [0, 1, 1],
			        [1, 0, 0],
			        [1, 0, 1],
			        [1, 1, 0],
			        [1, 1, 1],
			    )    ,	dtype=numpy.floataa    ,	)

			# True output values for the given input values.
			__snake_case					:      Optional[Any]							      =     numpy.array(([0], [1], [1], [0], [1], [0], [0], [1])    ,	dtype=numpy.floataa )

			# Calling neural network class.
			__snake_case					:      List[Any]							      =     TwoHiddenLayerNeuralNetwork(
			    input_array=_lowerCamelCase    ,	output_array=_lowerCamelCase )

			# Calling training function.
			# Set give_loss to True if you want to see loss in every iteration.
			neural_network.train(output=_lowerCamelCase    ,	iterations=10    ,	give_loss=_lowerCamelCase )

			return neural_network.predict(numpy.array(([1, 1, 1])    ,	dtype=numpy.floataa ) )


if __name__ == "__main__":
	example()









'''simple docstring'''






from __future__ import annotations

__UpperCamelCase					    =	[
    [-1, 0],  # left
    [0, -1],  # down
    [1, 0],  # right
    [0, 1],  # up
]







def 					_a						(       _lowerCamelCase    ,	_lowerCamelCase    ,	_lowerCamelCase    ,	_lowerCamelCase    ,	_lowerCamelCase    ,	) ->				tuple[list[list[int]], list[list[int]]]:



			"""simple docstring"""


			__snake_case					:      List[str]							      =     [
			    [0 for col in range(len(grid[0] ) )] for row in range(len(_lowerCamelCase ) )
			]  # the reference grid
			__snake_case					:      Tuple							      =     1
			__snake_case					:      List[str]							      =     [
			    [0 for col in range(len(grid[0] ) )] for row in range(len(_lowerCamelCase ) )
			]  # the action grid

			__snake_case					:      List[str]							      =     init[0]
			__snake_case					:      str							      =     init[1]
			__snake_case					:      int							      =     0
			__snake_case					:      int							      =     g + heuristic[x][y]  # cost from starting cell to destination cell
			__snake_case					:      List[str]							      =     [[f, g, x, y]]

			__snake_case					:      Any							      =     False  # flag that is set when search is complete
			__snake_case					:      int							      =     False  # flag set if we can't find expand

			while not found and not resign:
						if len(_lowerCamelCase ) == 0:
									raise ValueError("""Algorithm is unable to find solution""" )
						else:  # to choose the least costliest action so as to move closer to the goal
									cell.sort()
									cell.reverse()
									__snake_case					:      Tuple							      =     cell.pop()
									__snake_case					:      Optional[int]							      =     next_cell[2]
									__snake_case					:      List[Any]							      =     next_cell[3]
									__snake_case					:      int							      =     next_cell[1]

									if x == goal[0] and y == goal[1]:
												__snake_case					:      Optional[Any]							      =     True
									else:
												for i in range(len(_lowerCamelCase ) ):  # to try out different valid actions
															__snake_case					:      Union[str, Any]							      =     x + DIRECTIONS[i][0]
															__snake_case					:      str							      =     y + DIRECTIONS[i][1]
															if xa >= 0 and xa < len(_lowerCamelCase ) and ya >= 0 and ya < len(grid[0] ):
																		if closed[xa][ya] == 0 and grid[xa][ya] == 0:
																					__snake_case					:      str							      =     g + cost
																					__snake_case					:      Tuple							      =     ga + heuristic[xa][ya]
																					cell.append([fa, ga, xa, ya] )
																					__snake_case					:      List[str]							      =     1
																					__snake_case					:      Optional[int]							      =     i
			__snake_case					:      List[str]							      =     []
			__snake_case					:      Optional[int]							      =     goal[0]
			__snake_case					:      List[Any]							      =     goal[1]
			invpath.append([x, y] )  # we get the reverse path from here
			while x != init[0] or y != init[1]:
						__snake_case					:      Dict							      =     x - DIRECTIONS[action[x][y]][0]
						__snake_case					:      int							      =     y - DIRECTIONS[action[x][y]][1]
						__snake_case					:      Optional[int]							      =     xa
						__snake_case					:      int							      =     ya
						invpath.append([x, y] )

			__snake_case					:      Optional[int]							      =     []
			for i in range(len(_lowerCamelCase ) ):
						path.append(invpath[len(_lowerCamelCase ) - 1 - i] )
			return path, action


if __name__ == "__main__":
	__UpperCamelCase					    =	[
	    [0, 1, 0, 0, 0, 0],
	    [0, 1, 0, 0, 0, 0],  # 0 are free path whereas 1's are obstacles
	    [0, 1, 0, 0, 0, 0],
	    [0, 1, 0, 0, 1, 0],
	    [0, 0, 0, 0, 1, 0],
	]

	__UpperCamelCase					    =	[0, 0]
	# all coordinates are given in format [y,x]
	__UpperCamelCase					    =	[len(grid) - 1, len(grid[0]) - 1]
	__UpperCamelCase					    =	1

	# the cost map which pushes the path closer to the goal
	__UpperCamelCase					    =	[[0 for row in range(len(grid[0]))] for col in range(len(grid))]
	for i in range(len(grid)):
		for j in range(len(grid[0])):
			__UpperCamelCase					    =	abs(i - goal[0]) + abs(j - goal[1])
			if grid[i][j] == 1:
				# added extra penalty in the heuristic map
				__UpperCamelCase					    =	99

	__UpperCamelCase    ,		__UpperCamelCase					    =	search(grid, init, goal, cost, heuristic)

	print("ACTION MAP")
	for i in range(len(action)):
		print(action[i])

	for i in range(len(path)):
		print(path[i])


