






'''simple docstring'''







from typing import Any

import numpy as np






class 					a__    :
     '''simple docstring'''







     def __init__(self    :	Union[str, Any]				,				lowercase__    :	Any				,				lowercase__    :	Dict					)  ->       Union[str, Any]:
           # Check if RHS is negative
           if np.any(tableau[:, -1]				,				where=tableau[:, -1] < 0					):
                 raise ValueError("RHS must be > 0"					)

           __A		   =      tableau
           __A   ,				__A		   =      tableau.shape

           # Number of decision variables x1, x2, x3...
           __A		   =      n_vars

           # Number of artificial variables to be minimised
           __A		   =      len(np.where(tableau[self.n_vars : -1] == -1					)[0]					)

           # 2 if there are >= or == constraints (nonstandard), 1 otherwise (std)
           __A		   =      (self.n_art_vars > 0) + 1

           # Number of slack variables added to make inequalities into equalities
           __A		   =      self.n_rows - self.n_stages

           # Objectives for each stage
           __A		   =      ["max"]

           # In two stage simplex, first minimise then maximise
           if self.n_art_vars:
                 self.objectives.append("min"					)

           __A		   =      [""]

           # Index of current pivot row and column
           __A		   =      None
           __A		   =      None

           # Does objective row only contain (non)-negative values?
           __A		   =      False






     @staticmethod
     def     _UpperCamelCase   (*lowercase__    :	Optional[Any]					)  ->       Tuple:
           if len(__snake_case					) != 3:
                 raise ValueError("Must provide n_vars, n_slack, and n_art_vars"					)

           if not all(x >= 0 and isinstance(__snake_case				,				__snake_case					) for x in args					):
                 raise ValueError("All arguments must be non-negative integers"					)

           # decision | slack | artificial
           __A		   =      ["x", "s", "a"]
           __A		   =      []
           for i in range(3					):
                 for j in range(args[i]					):
                       titles.append(string_starts[i] + str(j + 1					)					)
           titles.append("RHS"					)
           return titles






     def     _UpperCamelCase   (self    :	List[Any]				,				lowercase__    :	Union[str, Any]					)  ->       Optional[int]:
           __A		   =      self.objectives[-1]

           # Find entries of highest magnitude in objective rows
           __A		   =      (objective == "min") - (objective == "max")
           __A		   =      np.argmax(sign * tableau[0, : self.n_vars]					)

           # Choice is only valid if below 0 for maximise, and above for minimise
           if sign * self.tableau[0, col_idx] <= 0:
                 __A		   =      True
                 return 0, 0

           # Pivot row is chosen as having the lowest quotient when elements of
           # the pivot column divide the right-hand side

           # Slice excluding the objective rows
           __A		   =      slice(self.n_stages				,				self.n_rows					)

           # RHS
           __A		   =      tableau[s, -1]

           # Elements of pivot column within slice
           __A		   =      tableau[s, col_idx]

           # Array filled with nans
           __A		   =      np.full(self.n_rows - self.n_stages				,				np.nan					)

           # If element in pivot column is greater than zeron_stages, return
           # quotient or nan otherwise
           __A		   =      np.divide(__snake_case				,				__snake_case				,				out=__snake_case				,				where=divisor > 0					)

           # Arg of minimum quotient excluding the nan values. n_stages is added
           # to compensate for earlier exclusion of objective columns
           __A		   =      np.nanargmin(__snake_case					) + self.n_stages
           return row_idx, col_idx






     def     _UpperCamelCase   (self    :	Tuple				,				lowercase__    :	str				,				lowercase__    :	Dict				,				lowercase__    :	Dict					)  ->       Dict:
           __A		   =      tableau[row_idx].copy()

           __A		   =      piv_row[col_idx]

           # Entry becomes 1
           piv_row *= 1 / piv_val

           # Variable in pivot column becomes basic, ie the only non-zero entry
           for idx, coeff in enumerate(tableau[:, col_idx]					):
                 tableau[idx] += -coeff * piv_row
           __A		   =      piv_row
           return tableau






     def     _UpperCamelCase   (self    :	Optional[Any]				,				lowercase__    :	Optional[Any]					)  ->       Tuple:
           self.objectives.pop()

           if not self.objectives:
                 return tableau

           # Slice containing ids for artificial columns
           __A		   =      slice(-self.n_art_vars - 1				,				-1					)

           # Delete the artificial variable columns
           __A		   =      np.delete(__snake_case				,				__snake_case				,				axis=1					)

           # Delete the objective row of the first stage
           __A		   =      np.delete(__snake_case				,				0				,				axis=0					)

           __A		   =      1
           self.n_rows -= 1
           __A		   =      0
           __A		   =      False
           return tableau






     def     _UpperCamelCase   (self    :	Optional[Any]					)  ->       Optional[int]:
           # Stop simplex algorithm from cycling.
           for _ in range(100					):
                 # Completion of each stage removes an objective. If both stages
                 # are complete, then no objectives are left
                 if not self.objectives:
                       __A		   =      self.generate_col_titles(
                           self.n_vars				,				self.n_slack				,				self.n_art_vars					)

                       # Find the values of each variable at optimal solution
                       return self.interpret_tableau(self.tableau				,				self.col_titles					)

                 __A   ,				__A		   =      self.find_pivot(self.tableau					)

                 # If there are no more negative values in objective row
                 if self.stop_iter:
                       # Delete artificial variable columns and rows. Update attributes
                       __A		   =      self.change_stage(self.tableau					)
                 else:
                       __A		   =      self.pivot(self.tableau				,				__snake_case				,				__snake_case					)
           return {}






     def     _UpperCamelCase   (self    :	List[Any]				,				lowercase__    :	List[Any]				,				lowercase__    :	Optional[Any]					)  ->       List[Any]:
           __A		   =      {"P": abs(tableau[0, -1]					)}

           for i in range(self.n_vars					):
                 # Gives ids of nonzero entries in the ith column
                 __A		   =      np.nonzero(tableau[:, i]					)
                 __A		   =      len(nonzero[0]					)

                 # First entry in the nonzero ids
                 __A		   =      nonzero[0][0]
                 __A		   =      tableau[nonzero_rowidx, i]

                 # If there is only one nonzero value in column, which is one
                 if n_nonzero == nonzero_val == 1:
                       __A		   =      tableau[nonzero_rowidx, -1]
                       __A		   =      rhs_val

        # Check for basic variables
           for title in col_titles:
                 # Don't add RHS or slack variables to output dict
                 if title[0] not in "R-s-a":
                       output_dict.setdefault(__snake_case				,				0					)
           return output_dict


if __name__ == "__main__":
       import doctest

       doctest.testmod()










'''simple docstring'''







from __future__ import annotations

from queue import Queue






class 					a__    :
     '''simple docstring'''







     def __init__(self    :	Any					)  ->       None:
           __A		   =      {}






     def     _UpperCamelCase   (self    :	Optional[int]					)  ->       None:
           for i in self.vertices:
                 print(lowercase__				,				" : "				,				" -> ".join([str(lowercase__					) for j in self.vertices[i]]					)					)






     def     _UpperCamelCase   (self    :	Union[str, Any]				,				lowercase__    :	int				,				lowercase__    :	int					)  ->       None:
           if from_vertex in self.vertices:
                 self.vertices[from_vertex].append(lowercase__					)
           else:
                 __A		   =      [to_vertex]






     def     _UpperCamelCase   (self    :	Optional[int]				,				lowercase__    :	int					)  ->       set[int]:
           __A		   =      set()

           # create a first in first out queue to store all the vertices for BFS
           __A		   =      Queue()

           # mark the source node as visited and enqueue it
           visited.add(lowercase__					)
           queue.put(lowercase__					)

           while not queue.empty():
                 __A		   =      queue.get()

                 # loop through all adjacent vertex and enqueue it if not yet visited
                 for adjacent_vertex in self.vertices[vertex]:
                       if adjacent_vertex not in visited:
                             queue.put(lowercase__					)
                             visited.add(lowercase__					)
           return visited


if __name__ == "__main__":
       from doctest import testmod

       testmod(verbose=True)

       __A      :       Dict      =	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()
       # 0  :  1 -> 2
       # 1  :  2
       # 2  :  0 -> 3
       # 3  :  3

       assert sorted(g.bfs(2)) == [0, 1, 2, 3]


