Solingen

lab3.py

Apr 9th, 2026
42
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 10.96 KB | None | 0 0
  1. # ============================================================
  2. # Хранение разреженных матриц — 5 форматов
  3. # Матрица задаётся вручную (список строк, 0 = пустая ячейка)
  4. # ============================================================
  5.  
  6. matrix = [
  7.     [1, 0, 0, 0, 2, 0],
  8.     [0, 0, 3, 4, 0, 0],
  9.     [0, 0, 0, 0, 0, 0],
  10.     [0, 0, 0, 8, 0, 5],
  11.     [0, 0, 0, 0, 0, 0],
  12.     [0, 7, 1, 0, 0, 6],
  13. ]
  14.  
  15. # ============================================================
  16. # Вспомогательные функции
  17. # ============================================================
  18.  
  19. def print_original(matrix):
  20.     rows = len(matrix)
  21.     cols = len(matrix[0])
  22.     print("  Исходная матрица A:")
  23.     print("  " + "-----" * cols)
  24.     for row in matrix:
  25.         print("  | " + "  ".join(f"{v:2}" for v in row) + " |")
  26.     print("  " + "-----" * cols)
  27.     total = rows * cols
  28.     non_zero = sum(1 for r in matrix for v in r if v != 0)
  29.     zero = total - non_zero
  30.     print(f"\n  Всего элементов:     {total}")
  31.     print(f"  Ненулевых:           {non_zero}")
  32.     print(f"  Нулевых (пустых):    {zero}")
  33.     print(f"  Разреженность:       {zero/total*100:.1f}% нулей")
  34.  
  35. def get_nonzero(matrix):
  36.     """Возвращает список (row, col, value) для всех ненулевых элементов."""
  37.     result = []
  38.     for i, row in enumerate(matrix):
  39.         for j, val in enumerate(row):
  40.             if val != 0:
  41.                 result.append((i, j, val))
  42.     return result
  43.  
  44. def print_array(name, arr):
  45.     print(f"  {name}: [ " + "  ".join(f"{v}" for v in arr) + " ]")
  46.  
  47. # ============================================================
  48. # 1. COO — Coordinate Format (Координатный формат)
  49. #    Хранит три массива: Value, Row, Col
  50. #    Каждый i-й элемент описывает одно ненулевое значение
  51. # ============================================================
  52.  
  53. def coo(matrix):
  54.     print("\n" + "=" * 60)
  55.     print("  ФОРМАТ 1: COO (Coordinate Format)")
  56.     print("=" * 60)
  57.     print("  Идея: для каждого ненулевого элемента храним тройку")
  58.     print("        (значение, номер строки, номер столбца).")
  59.     print()
  60.  
  61.     nz = get_nonzero(matrix)
  62.  
  63.     values   = [v   for (i, j, v) in nz]
  64.     rows     = [i   for (i, j, v) in nz]
  65.     cols     = [j   for (i, j, v) in nz]
  66.  
  67.     print("  Перебор ненулевых элементов:")
  68.     for (i, j, v) in nz:
  69.         print(f"    A[{i}][{j}] = {v}")
  70.  
  71.     print()
  72.     print_array("Value", values)
  73.     print_array("Row  ", rows)
  74.     print_array("Col  ", cols)
  75.     print(f"\n  Память: {len(values) * 3} ячеек вместо {len(matrix)*len(matrix[0])}")
  76.  
  77.     return {"Value": values, "Row": rows, "Col": cols}
  78.  
  79. # ============================================================
  80. # 2. CSR — Compressed Sparse Row (Сжатые строки)
  81. #    Value   — все ненулевые значения слева направо, строка за строкой
  82. #    Col     — столбцы этих значений
  83. #    RowIndex — где в Value начинается каждая строка (длина = n_rows + 1)
  84. # ============================================================
  85.  
  86. def csr(matrix):
  87.     print("\n" + "=" * 60)
  88.     print("  ФОРМАТ 2: CSR (Compressed Sparse Row)")
  89.     print("=" * 60)
  90.     print("  Идея: Value и Col — как в COO, но вместо Row-массива")
  91.     print("        храним RowIndex: индекс начала каждой строки в Value.")
  92.     print()
  93.  
  94.     values    = []
  95.     col_idx   = []
  96.     row_index = [0]
  97.  
  98.     for i, row in enumerate(matrix):
  99.         count = 0
  100.         for j, val in enumerate(row):
  101.             if val != 0:
  102.                 values.append(val)
  103.                 col_idx.append(j)
  104.                 count += 1
  105.         row_index.append(row_index[-1] + count)
  106.         print(f"    Строка {i}: {count} ненулевых → RowIndex теперь {row_index}")
  107.  
  108.     print()
  109.     print_array("Value   ", values)
  110.     print_array("Col     ", col_idx)
  111.     print_array("RowIndex", row_index)
  112.     print(f"\n  Память: {len(values)*2 + len(row_index)} ячеек вместо {len(matrix)*len(matrix[0])}")
  113.     print(f"  RowIndex[i+1] - RowIndex[i] = количество ненулевых в строке i")
  114.  
  115.     return {"Value": values, "Col": col_idx, "RowIndex": row_index}
  116.  
  117. # ============================================================
  118. # 3. CSC — Compressed Sparse Column (Сжатые столбцы)
  119. #    Аналог CSR, но по столбцам
  120. #    Value   — ненулевые значения сверху вниз, столбец за столбцом
  121. #    Row     — строки этих значений
  122. #    ColIndex — где в Value начинается каждый столбец
  123. # ============================================================
  124.  
  125. def csc(matrix):
  126.     print("\n" + "=" * 60)
  127.     print("  ФОРМАТ 3: CSC (Compressed Sparse Column)")
  128.     print("=" * 60)
  129.     print("  Идея: то же что CSR, но обходим матрицу по столбцам.")
  130.     print()
  131.  
  132.     n_rows = len(matrix)
  133.     n_cols = len(matrix[0])
  134.  
  135.     values    = []
  136.     row_idx   = []
  137.     col_index = [0]
  138.  
  139.     for j in range(n_cols):
  140.         count = 0
  141.         for i in range(n_rows):
  142.             val = matrix[i][j]
  143.             if val != 0:
  144.                 values.append(val)
  145.                 row_idx.append(i)
  146.                 count += 1
  147.         col_index.append(col_index[-1] + count)
  148.         print(f"    Столбец {j}: {count} ненулевых → ColIndex теперь {col_index}")
  149.  
  150.     print()
  151.     print_array("Value   ", values)
  152.     print_array("Row     ", row_idx)
  153.     print_array("ColIndex", col_index)
  154.     print(f"\n  Память: {len(values)*2 + len(col_index)} ячеек вместо {n_rows*n_cols}")
  155.  
  156.     return {"Value": values, "Row": row_idx, "ColIndex": col_index}
  157.  
  158. # ============================================================
  159. # 4. DOK — Dictionary of Keys (Словарь ключей)
  160. #    Словарь: (строка, столбец) → значение
  161. #    Только ненулевые элементы
  162. # ============================================================
  163.  
  164. def dok(matrix):
  165.     print("\n" + "=" * 60)
  166.     print("  ФОРМАТ 4: DOK (Dictionary of Keys)")
  167.     print("=" * 60)
  168.     print("  Идея: словарь, где ключ = (строка, столбец),")
  169.     print("        значение = элемент матрицы. Нули не хранятся.")
  170.     print()
  171.  
  172.     d = {}
  173.     for i, row in enumerate(matrix):
  174.         for j, val in enumerate(row):
  175.             if val != 0:
  176.                 d[(i, j)] = val
  177.  
  178.     print("  Содержимое словаря:")
  179.     for key, val in d.items():
  180.         print(f"    ({key[0]}, {key[1]}) → {val}")
  181.  
  182.     print(f"\n  Доступ к элементу: dict.get((i, j), 0)")
  183.     print(f"  Память: {len(d)} записей вместо {len(matrix)*len(matrix[0])}")
  184.  
  185.     return d
  186.  
  187. # ============================================================
  188. # 5. ELLPACK (ELL)
  189. #    Две матрицы одинакового размера (n_rows × max_nnz_per_row):
  190. #      Value  — значения (строки дополнены нулями до одинаковой длины)
  191. #      Column — номера столбцов (для нулей-заполнителей тоже 0)
  192. #    max_nnz_per_row = максимальное кол-во ненулевых среди всех строк
  193. # ============================================================
  194.  
  195. def ellpack(matrix):
  196.     print("\n" + "=" * 60)
  197.     print("  ФОРМАТ 5: ELLPACK (ELL)")
  198.     print("=" * 60)
  199.     print("  Идея: две матрицы размером (строки × макс.ненулевых в строке).")
  200.     print("        Value — сами значения, Column — их столбцы.")
  201.     print("        Короткие строки дополняются нулями (паддинг).")
  202.     print()
  203.  
  204.     rows_data = []
  205.     for i, row in enumerate(matrix):
  206.         nz_in_row = [(j, val) for j, val in enumerate(row) if val != 0]
  207.         rows_data.append(nz_in_row)
  208.  
  209.     max_nnz = max(len(r) for r in rows_data)
  210.     print(f"  Максимум ненулевых в одной строке: {max_nnz}")
  211.     print(f"  Размер каждой из двух матриц: {len(matrix)} × {max_nnz}")
  212.     print()
  213.  
  214.     val_matrix = []
  215.     col_matrix = []
  216.  
  217.     for i, nz_in_row in enumerate(rows_data):
  218.         val_row = [v   for (j, v) in nz_in_row] + [0] * (max_nnz - len(nz_in_row))
  219.         col_row = [j   for (j, v) in nz_in_row] + [0] * (max_nnz - len(nz_in_row))
  220.         val_matrix.append(val_row)
  221.         col_matrix.append(col_row)
  222.         pad = max_nnz - len(nz_in_row)
  223.         print(f"    Строка {i}: ненулевых={len(nz_in_row)}, паддинг={pad} → "
  224.               f"Value={val_row}  Column={col_row}")
  225.  
  226.     col_w = 4
  227.     print("\n  Матрица Value:")
  228.     for row in val_matrix:
  229.         print("    [ " + "  ".join(f"{v:{col_w}}" for v in row) + " ]")
  230.  
  231.     print("\n  Матрица Column:")
  232.     for row in col_matrix:
  233.         print("    [ " + "  ".join(f"{v:{col_w}}" for v in row) + " ]")
  234.  
  235.     print(f"\n  Память: {len(matrix) * max_nnz * 2} ячеек вместо {len(matrix)*len(matrix[0])}")
  236.  
  237.     return {"Value": val_matrix, "Column": col_matrix}
  238.  
  239. # ============================================================
  240. # Запуск
  241. # ============================================================
  242.  
  243. print("=" * 60)
  244. print("  ХРАНЕНИЕ РАЗРЕЖЕННЫХ МАТРИЦ — 5 ФОРМАТОВ")
  245. print("=" * 60)
  246. print_original(matrix)
  247.  
  248. coo_result     = coo(matrix)
  249. csr_result     = csr(matrix)
  250. csc_result     = csc(matrix)
  251. dok_result     = dok(matrix)
  252. ell_result     = ellpack(matrix)
  253.  
  254. print("\n" + "=" * 60)
  255. print("  ИТОГОВОЕ СРАВНЕНИЕ ФОРМАТОВ")
  256. print("=" * 60)
  257. n = len(matrix) * len(matrix[0])
  258. nz = sum(1 for r in matrix for v in r if v != 0)
  259. print(f"  Исходная матрица:  {n} ячеек  ({nz} ненулевых)\n")
  260. print(f"  {'Формат':<10} {'Структура хранения':<40} {'Ячеек'}")
  261. print(f"  {'-'*60}")
  262. print(f"  {'COO':<10} {'Value + Row + Col':<40} {nz * 3}")
  263. print(f"  {'CSR':<10} {'Value + Col + RowIndex':<40} {nz * 2 + len(matrix) + 1}")
  264. print(f"  {'CSC':<10} {'Value + Row + ColIndex':<40} {nz * 2 + len(matrix[0]) + 1}")
  265. print(f"  {'DOK':<10} {'dict (i,j)->v':<40} {nz} записей")
  266. max_nnz = max(sum(1 for v in r if v != 0) for r in matrix)
  267. print(f"  {'ELLPACK':<10} {'Value-матрица + Column-матрица':<40} {len(matrix) * max_nnz * 2}")
Advertisement
Add Comment
Please, Sign In to add comment