


import math






class 	__lowercase					:





      def 							_lowercase					(		self    :       Any       ,							__lowerCamelCase    :       list[list[float]]       ,							__lowerCamelCase    :       list[int]							)     -> int:






         """simple docstring"""







         UpperCAmelCase      					=  0.0
         UpperCAmelCase      					=  0.0
         for i in range(len(__lowerCamelCase							)							):
            da += math.pow((sample[i] - weights[0][i])       ,							2							)
            da += math.pow((sample[i] - weights[1][i])       ,							2							)
            return 0 if da > da else 1
         return 0





      def 							_lowercase					(		self    :       List[Any]       ,							__lowerCamelCase    :       list[list[int | float]]       ,							__lowerCamelCase    :       list[int]       ,							__lowerCamelCase    :       int       ,							__lowerCamelCase    :       float							)     -> list[list[int | float]]:






         """simple docstring"""







         for i in range(len(__lowerCamelCase							)							):
            weights[j][i] += alpha * (sample[i] - weights[j][i])
         return weights

def 	_UpperCamelCase					(    )    ->None:
   # Training Examples ( m, n )
   UpperCAmelCase      					=  [[1, 1, 0, 0], [0, 0, 0, 1], [1, 0, 0, 0], [0, 0, 1, 1]]

   # weight initialization ( n, C )
   UpperCAmelCase      					=  [[0.2, 0.6, 0.5, 0.9], [0.8, 0.4, 0.7, 0.3]]

   # training
   UpperCAmelCase      					=  SelfOrganizingMap()
   UpperCAmelCase      					=  3
   UpperCAmelCase      					=  0.5

   for _ in range(lowerCAmelCase_ ):
      for j in range(len(lowerCAmelCase_ ) ):
         # training sample
         UpperCAmelCase      					=  training_samples[j]

         # Compute the winning vector
         UpperCAmelCase      					=  self_organizing_map.get_winner(lowerCAmelCase_	,    lowerCAmelCase_ )

         # Update the winning vector
         UpperCAmelCase      					=  self_organizing_map.update(lowerCAmelCase_	,    lowerCAmelCase_	,    lowerCAmelCase_	,    lowerCAmelCase_ )

    # classify test sample
   UpperCAmelCase      					=  [0, 0, 0, 1]
   UpperCAmelCase      					=  self_organizing_map.get_winner(lowerCAmelCase_	,    lowerCAmelCase_ )

   # results
   print(F"""Clusters that the test sample belongs to : {winner}""" )
   print(F"""Weights that have been trained : {weights}""" )


# running the main() function
if __name__ == "__main__":
 main()







class 	__lowercase					:





      def __init__(		self    :       Optional[int]							)     -> int:






         """simple docstring"""







         UpperCAmelCase      					=  {}





      def 							_lowercase					(		self    :       str							)     -> None:






         """simple docstring"""







         print(self.vertex							)
         for i in self.vertex:
            print(__lowerCamelCase       ,							""" -> """       ,							""" -> """.join([str(__lowerCamelCase							) for j in self.vertex[i]]							)							)





      def 							_lowercase					(		self    :       Optional[Any]       ,							__lowerCamelCase    :       int       ,							__lowerCamelCase    :       int							)     -> None:






         """simple docstring"""







         if from_vertex in self.vertex:
            self.vertex[from_vertex].append(__lowerCamelCase							)
         else:
            # else make a new vertex
            UpperCAmelCase      					=  [to_vertex]





      def 							_lowercase					(		self    :       str							)     -> None:






         """simple docstring"""







         UpperCAmelCase      					=  [False] * len(self.vertex							)

         # call the recursive helper function
         for i in range(len(self.vertex							)							):
            if not visited[i]:
               self.dfs_recursive(__lowerCamelCase       ,							__lowerCamelCase							)





      def 							_lowercase					(		self    :       Optional[int]       ,							__lowerCamelCase    :       int       ,							__lowerCamelCase    :       list							)     -> None:






         """simple docstring"""







         UpperCAmelCase      					=  True

         print(__lowerCamelCase       ,							end=""" """							)

         # Recur for all the vertices that are adjacent to this node
         for i in self.vertex:
            if not visited[i]:
               self.dfs_recursive(__lowerCamelCase       ,							__lowerCamelCase							)


if __name__ == "__main__":
 __a	 =      Graph()
 g.add_edge(0, 1)
 g.add_edge(0, 2)
 g.add_edge(1, 2)
 g.add_edge(2, 0)
 g.add_edge(2, 3)
 g.add_edge(3, 3)

 g.print_graph()
 print("""DFS:""")
 g.dfs()

 # OUTPUT:
 # 0  ->  1 -> 2
 # 1  ->  2
 # 2  ->  0 -> 3
 # 3  ->  3
 # DFS:
 #  0 1 2 3



