Advertisement
kostyukevich

graph

Dec 18th, 2023
993
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.22 KB | None | 0 0
  1. from typing import TypeVar, Generic, Callable
  2. from typing import Tuple
  3. import pickle
  4. from dataclasses import dataclass
  5.  
  6. T = TypeVar("T")
  7.  
  8. @dataclass
  9.  
  10. class Graph(Generic[T]):
  11.     def __init__(self, is_directed: bool = False, ) -> None: #задаем данные матрицы
  12.         self.length: int = 0
  13.         self.matrix: list[list[int]] = []
  14.         self.vertex_names: dict[T, int] = {}
  15.         self.is_directed: bool = is_directed
  16.  
  17.     def add_vertex(self,  name: T) -> int: #добавляем вершину
  18.         index = self.length
  19.         self.matrix.append([0] * self.length)
  20.         for row in self.matrix:
  21.             row.append(0)
  22.         self.length += 1
  23.         self.vertex_names[name] = index
  24.         return index
  25.  
  26.     def add_edge(self, v1: int, v2: int, weight: int) -> None: #добавляем грань
  27.         if v1 >= self.length or v2 >= self.length:
  28.             raise Exception("out of range")
  29.         self.matrix[v1][v2] = weight
  30.         if not self.is_directed:
  31.             self.matrix[v2][v1] = weight
  32.  
  33.     def add_without_weight(self, vertex1: T, vertex2: T) -> None: #добавляем грань без веса
  34.         self.add_edge(vertex1, vertex2, 0)
  35.  
  36.     def for_each_vertex(self, fun: Callable[[T], None]) -> None: #применить функцию для каждой вершины
  37.         for vert, _ in self.matrix:
  38.             fun(vert)
  39.    
  40.     def amount_vertexes(self) -> int: #колчиество вершин
  41.         return len(self.vertex_names)
  42.    
  43.     def for_each_adj_edge(self, vertex: T, fun: Callable[[int], None]): #применить функцию для каждой грани
  44.         if vertex in self.vertex_names:
  45.             edges: list[int] = self.matrix[self.vertex_names[vertex]]
  46.             for number in edges:
  47.                 fun(number)
  48.  
  49.     def print_matrix(self) -> None: #вывести матрицу смежности
  50.         print("    ", end="")
  51.         for index in range(self.length):
  52.             print(f"{self.get_vertex_by_index(index):<8}", end="")
  53.         print()
  54.  
  55.         for i, row in enumerate(self.matrix):
  56.             print(f"{self.get_vertex_by_index(i):<4}", end="")
  57.             for val in row:
  58.                 print(f"{val:<8}", end="")
  59.             print()
  60.  
  61.     def get_vertex_by_index(self, index: int) -> T: #вытащить вершину по ее номеру
  62.         for vertex, vert_index in self.vertex_names.items():
  63.             if vert_index == index:
  64.                 return vertex
  65.         raise ValueError("Vertex not found")
  66.  
  67.     def prim(self) -> list[Tuple[T, T, int]]: #поиск минимального остовного дерева
  68.         if self.length == 0:
  69.             return []
  70.  
  71.         visited = set()
  72.         edges = []
  73.         start_vertex = next(iter(self.vertex_names))
  74.         visited.add(start_vertex)
  75.  
  76.         while len(visited) < self.length:
  77.             min_edge = None
  78.             min_weight = float('inf')
  79.  
  80.             for visited_vertex in visited:
  81.                 visited_vertex_index = self.vertex_names[visited_vertex]
  82.  
  83.                 for neighbor_index, weight in enumerate(self.matrix[visited_vertex_index]):
  84.                     if weight != 0 and self.get_vertex_by_index(neighbor_index) not in visited:
  85.                         if weight < min_weight:
  86.                             min_edge = (visited_vertex, self.get_vertex_by_index(neighbor_index), weight)
  87.                             min_weight = weight
  88.  
  89.             if min_edge:
  90.                 edges.append(min_edge)
  91.                 visited.add(min_edge[1])
  92.  
  93.         return edges
  94.  
  95.     def save_to_file(self, filename: str) -> None:
  96.         data = {
  97.             'length': self.length,
  98.             'matrix': self.matrix,
  99.             'vertex_names': self.vertex_names,
  100.             'is_directed': self.is_directed
  101.         }
  102.  
  103.         with open(filename, 'wb') as file:
  104.             pickle.dump(data, file)
  105.  
  106.     def load_from_file(self, filename: str) -> None:
  107.         with open(filename, 'rb') as file:
  108.             data = pickle.load(file)
  109.  
  110.         self.length = data['length']
  111.         self.matrix = data['matrix']
  112.         self.vertex_names = data['vertex_names']
  113.         self.is_directed = data['is_directed']
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement