def constructWay(self, start, end): """ Домопіжний метод, що будує шлях, між двома вершинами у графі Може бути застосовами лише після дії алгоритмів пошуку шляху (Хвильового, Дейкстри, Беллмана-Форда, тощо) які записують допоміжну інформацію у вершини графа. :param start: Вершина, що початком шляху :param end: Вершина, що є кінцем шляху :return: Кортеж, що містить список вершин - найкоротший шлях, що сполучає вершини start та end та його вагу """ if self[end].source is None: # шляху не існує return None, INF # будуємо шлях за допомогою стеку stack = Stack() current = end while True: stack.push(current) if current == start: break current = self[current].source() if current is None: return None way = [] # Послідовність вершин шляху while not stack.empty(): way.append(stack.pop()) # Повертаємо шлях та його вагу return way, self[end].distance()
def convertToPolish(self): """ Конвертує арифметичний вираз з інфіксного у постфіксний вигляд Для коректної роботи цього методу, передбачається, що у рядку (що містить арифметичний вираз) усі операнди, оператори та дужки записуються через символ пропуску, наприклад "25 * ( 3 + 5 )" :return: Рядок, що містить арифметичний вираз у постфіксному вигляді """ infix_list = self.mInfixStr.split() # Розділяємо рядок на токени postfix_list = [] # Список, що міститиме вираз у постфіксному вигляді stack = Stack() # Допоміжний стек арифметичних операторів та дужок for token in infix_list: # Ітеруємо по всіх токенах інфіксного виразу if token in OPERATORS: # токен є оператором while not stack.empty(): prev = stack.top() # підглянемо попередній оператор зі стеку # Якщо попередній токен є оператором # пріорітет якого вищий за пріорітет поточного оператора if prev in OPERATORS and OPERATORS[prev] >= OPERATORS[token]: stack.pop() # Видаляємо його зі стеку операторів postfix_list.append(prev) # Додаємо його до постфіксного списку else: break stack.push(token) # кладемо поточний оператор у стек elif token == "(": # токен є лівою дужкою, stack.push(token) # кладемо його в стек elif token == ")": # якщо токен є правою дужкою, it = stack.pop() # Виштовхуємо елементи зі стеку опертаорів stack while it != "(": # доки не знайдемо відповідну ліву дужку. postfix_list.append(it) # при цьому кожен оператор додаємо до списку it = stack.pop() else: # якщо токен є операндом postfix_list.append(token) # додаємо його у кінець постфіксногосписку. while not stack.empty(): postfix_list.append(stack.pop()) return postfix_list
def drawWayInMatrix(source, start, end, TAG): # функція виведення шляху # будуємо шлях за допомогою стеку stack = Stack() current = end while True: stack.push(current) if current == start: break current = source[current[0]][current[1]] if current is None: print(TAG, ": The way doesn't exist") return n = len(source) # кількість рядків у матриці P4_Maizes m = len(source[0]) # кількість стовпчиків у матриці P4_Maizes # створення та ініціалізація хвильової матриці # такої ж розмірності, що і матриця лабіринту matrix = [] for i in range(n): row = [" . "] * m matrix.append(row) # виводимо шлях на екран if not stack.empty(): v = stack.pop() matrix[v[0]][v[1]] = "=S=" while not stack.empty(): v = stack.pop() if stack.empty(): matrix[v[0]][v[1]] = "=F=" else: matrix[v[0]][v[1]] = "-@-" return matrix
def showWay(source, start, end, TAG): # функція виведення шляху # будуємо шлях за допомогою стеку stack = Stack() current = end while True: stack.push(current) if current == start: break current = source[current[0]][current[1]] if current is None: print(TAG, ": The way doesn't exist") return # виводимо шлях на екран while not stack.empty(): v = stack.pop() if not stack.empty(): print(v, end=" -> ") else: print(v)
def waySearch(graph, start, end): """ Пошук найкоротшого шляху між двома заданими вершинами графа :param graph: Граф :param start: Початкова вершина :param end: Кінцева вершина :return: список вершин найкоротшого шляху, що сполучає вершини start та end """ assert start != end # Словник, що для кожної вершини (ключ) містить ключ вершини з якої прийшли у поточну sources = { start: None } # Для стартової вершини не визначено звідки в неї прийшли. q = Queue() # Створюємо чергу q.enqueue(start) # Додаємо у чергу стартову вершину while not q.empty(): current = q.dequeue() # Беремо перший елемент з черги # Додаємо в чергу всіх сусідів поточного елементу for neighbour in graph[current].neighbors(): if neighbour not in sources: # які ще не були відвідані q.enqueue(neighbour) # при цьому для кожної вершини запам'ятовуємо вершину з якої прийшли sources[neighbour] = current if end not in sources: # шляху не існує return None # будуємо шлях за допомогою стеку stack = Stack() current = end while current != start: stack.push(current) current = sources[current] stack.push(current) way = [] # Послідовність вершин шляху while not stack.empty(): way.append(stack.pop()) # Повертаємо шлях return way
def topological_sorting(graph): """ Функція топологічного сортування вершин графа :param graph: граф :return: список топологічно відсортованих вершин """ stack = Stack() # Стек, що буде містити відсортовані елементи for vertex in graph: # для всіх вершин графа # запускаємо пошук в глибину __dfs_helper(graph, vertex, stack) # Створюємо список топологічно відсортованих вершин sequence = [] while not stack.empty(): sequence.append(stack.pop()) return sequence # Повертаємо список, що містить відсортовані елементи
def findWay(maze, start, end): """ Шукає шлях у лабіринті :param maze: Матриця лабіринту :param start: Початкова точка шляху :param end: Кінцева точка шляху :return: Список, клітин шляху """ waveMatrix = wave(maze, start) # Будуємо хвильову матрицю лабіринту if waveMatrix[end[0]][end[ 1]] == -1: # Кінцева точка не досяжна зі стартової - шляху не існує return [] stack = Stack() # Будуємо шлях за допомогою стеку current = end # Рух починаємо з кінця while True: stack.push(current) # Вштовхуємо у стек поточку клітину шляху if current == start: # Якщо поточка вершина шляху є стартовою break # Усі клітини шляху містяться у стеку i = current[0] # координата поточного рядка матриці j = current[1] # координата поточного стовчика матриці for k in range(len(dj)): i1 = i + di[k] # координата рядка сусідньої клітини j1 = j + dj[k] # координата стовпчика сусідньої клітини # Шукаємо клітину з якої ми прийшли у поточну current = None if waveMatrix[i1][j1] == waveMatrix[i][j] - 1: current = (i1, j1) break # Відновлюємо шлях зі стеку way = [] while not stack.empty(): way.append(stack.pop()) return way