Advertisement
chuuupa

yyy

Jan 13th, 2020
267
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 8.53 KB | None | 0 0
  1. import numpy as np
  2.  
  3.  
  4. # печать матрицы
  5. def printMatr(_matr):
  6.     for row in _matr:
  7.         row = np.array(row)
  8.     _matr = np.array(_matr)
  9.     print(_matr)
  10.  
  11.  
  12. # перемножить массивы
  13. def multiplyArrays(arr1, arr2):
  14.     matrix = np.zeros((len(arr1), len(arr2)), dtype=float)
  15.     ll = list(matrix)
  16.     for l in ll:
  17.         l = list(l)
  18.     for i in range(len(arr1)):
  19.         for j in range(len(arr2)):
  20.             ll[i][j] = arr1[i] * arr2[j]
  21.     return ll
  22.  
  23.  
  24. # найти максимум в массиве
  25. def findMaxInArr(arr):
  26.     _max = arr[0]
  27.     for i in range(1, len(arr)):
  28.         if arr[i] > _max:
  29.             _max = arr[i]
  30.     return _max
  31.  
  32.  
  33. # найти минимум в массиве
  34. def findMinInArr(_arr):
  35.     if len(_arr) == 0:
  36.         return -1
  37.     _min = _arr[0]
  38.     for i in range(1, len(_arr)):
  39.         if _arr[i] < _min:
  40.             _min = _arr[i]
  41.     return _min
  42.  
  43.  
  44. # перевод из задачи максимизации в задачу минимизации
  45. def maxToMin(matr):
  46.     uMax = []
  47.     for i in range(len(matr)):
  48.         uMax.append(findMaxInArr(matr[i]))
  49.     for i in range(len(matr)):
  50.         for j in range(len(matr[i])):
  51.             matr[i][j] -= findMaxInArr(uMax)
  52.             matr[i][j] *= -1
  53.     return matr
  54.  
  55.  
  56. # ноль-преобразование по строке
  57. def reduceByMinRow(matr):
  58.     for i in range(len(matr)):
  59.         _min = findMinInArr(matr[i])
  60.         for j in range(len(matr[i])):
  61.             matr[i][j] -= _min
  62.     return matr
  63.  
  64.  
  65. # делает массив минимальных элементов по столбцам
  66. def minRow(matr):
  67.     min_in_col = []
  68.     for k in range(len(matr[0])):
  69.         min_in_col.append(matr[0][k])
  70.     for i in range(1, len(matr)):
  71.         for j in range(len(matr[i])):
  72.             if matr[i][j] < min_in_col[j]:
  73.                 min_in_col[j] = matr[i][j]
  74.     return min_in_col
  75.  
  76.  
  77. # ноль-преобразование по столбцам
  78. def reduceByMinCol(matr):
  79.     _min = minRow(matr)
  80.     for i in range(len(matr)):
  81.         for j in range(len(matr[i])):
  82.             matr[i][j] -= _min[j]
  83.     return matr
  84.  
  85.  
  86. # ноль-преобразование
  87. def stepOne(_matr):
  88.     return reduceByMinCol(reduceByMinRow(_matr))
  89.  
  90.  
  91. # определение ноль-независимых элементов и проверка на оптимальность
  92. def stepTwo(matr, c):
  93.     # булева матрица, полученная из исходной: на месте x > 0 стоят нули, иначе единицы
  94.     interim_matrix = []
  95.     # счетчик помеченных нулей
  96.     l = 0
  97.     # размерность матрицы
  98.     n = len(matr)
  99.     # массивы, содержащие счетчики нулей по столбцам и строкам
  100.     count_zeros_cols = np.zeros(n)
  101.     count_zeros_rows = np.zeros(n)
  102.     # заполнение булевой матрицы
  103.     for i in range(n):
  104.         interim_matrix.append([])
  105.         for j in range(n):
  106.             if matr[i][j] == 0:
  107.                 interim_matrix[i].append(1)
  108.                 count_zeros_cols[j] += 1
  109.                 count_zeros_rows[i] += 1
  110.             else:
  111.                 interim_matrix[i].append(0)
  112.  
  113.     # индексы невычеркнутых нулей матрицы
  114.     row_indexes = [i for i in range(n)]
  115.     col_indexes = [i for i in range(n)]
  116.  
  117.     # индексы помеченных нулей матрицы
  118.     res_rows = []
  119.     res_cols = []
  120.  
  121.     while sum(count_zeros_rows) + sum(count_zeros_cols) > 0:
  122.         if findMinInArr([x for x in count_zeros_cols if x > 0]) < findMinInArr([x for x in count_zeros_rows if x > 0]):
  123.             # алгоритм вычеркивания одного столбца
  124.             # столбцы, помеченные на удаление
  125.             redundant_cols = []
  126.             for k in col_indexes:
  127.                 if count_zeros_cols[k] == findMinInArr([x for x in count_zeros_cols if x > 0]):
  128.                     redundant_cols.append(k)
  129.             for i in redundant_cols:
  130.                 if count_zeros_cols[i] > 0:
  131.                     redundant_rows = []
  132.                     for j in row_indexes:
  133.                         if interim_matrix[j][i] == 1:
  134.                             redundant_rows.append(j)
  135.                     _max = count_zeros_rows[redundant_rows[0]]
  136.                     row_index = redundant_rows[0]
  137.                     for k in redundant_rows:
  138.                         if count_zeros_rows[k] > _max:
  139.                             _max = count_zeros_rows[k]
  140.                             row_index = k
  141.                     for k in [x for x in col_indexes if interim_matrix[row_index][x] == 1]:
  142.                         count_zeros_cols[k] -= 1
  143.                     res_cols.append(i)
  144.                     res_rows.append(row_index)
  145.                     count_zeros_rows[row_index] = 0
  146.                     count_zeros_cols[i] = 0
  147.                     row_indexes.remove(row_index)
  148.                     l += 1
  149.                 else:
  150.                     continue
  151.  
  152.         else:
  153.             # алгоритм вычеркивания одной строки
  154.             redundant_rows = []
  155.             for k in row_indexes:
  156.                 if count_zeros_rows[k] == findMinInArr([x for x in count_zeros_rows if x > 0]):
  157.                     redundant_rows.append(k)
  158.             for i in redundant_rows:
  159.                 if count_zeros_rows[i] > 0:
  160.                     redundant_cols = []
  161.                     for j in col_indexes:
  162.                         if interim_matrix[i][j] == 1:
  163.                             redundant_cols.append(j)
  164.                     _max = count_zeros_cols[redundant_cols[0]]
  165.                     col_index = redundant_cols[0]
  166.                     for k in redundant_cols:
  167.                         if count_zeros_cols[k] > _max:
  168.                             _max = count_zeros_cols[k]
  169.                             col_index = k
  170.                     for k in [x for x in row_indexes if interim_matrix[x][col_index] == 1]:
  171.                         count_zeros_rows[k] -= 1
  172.                     res_rows.append(i)
  173.                     res_cols.append(col_index)
  174.                     count_zeros_cols[col_index] = 0
  175.                     count_zeros_rows[i] = 0
  176.                     col_indexes.remove(col_index)
  177.                     l += 1
  178.                 else:
  179.                     continue
  180.  
  181.     if l == n:
  182.         stepThree(res_rows, res_cols)
  183.     else:
  184.         _min = matr[row_indexes[0]][col_indexes[0]]
  185.         for i in row_indexes:
  186.             for j in col_indexes:
  187.                 if matr[i][j] < _min:
  188.                     _min = matr[i][j]
  189.         for i in range(n):
  190.             for j in range(n):
  191.                 if i not in row_indexes:
  192.                     if j not in col_indexes:
  193.                         matr[i][j] += _min
  194.                     else:
  195.                         continue
  196.                 else:
  197.                     if j in col_indexes:
  198.                         matr[i][j] -= _min
  199.                     else:
  200.                         continue
  201.         _c = c + _min * (n - l)
  202.         print('Преобразование:')
  203.         printMatr(matr)
  204.         print('==================')
  205.         print('c = ' + str(_c))
  206.         print('==================')
  207.         stepTwo(matr, _c)
  208.  
  209.  
  210. def stepThree(rows, cols):
  211.     res = np.zeros((len(rows), len(cols)), dtype=int)
  212.     ll = list(res)
  213.     for l in ll:
  214.         l = list(l)
  215.     for i in range(len(rows)):
  216.         ll[rows[i]][cols[i]] = 1
  217.  
  218.     print('X: ')
  219.     printMatr(ll)
  220.  
  221.  
  222. solveAsMin = True
  223.  
  224. # Matrix = multiplyArrays(
  225. #     list([5.72, 7, 6.92, 4.8, 5]),
  226. #     list([0.75, 1.12, 0.55, 1.32, 0.5, 0.45]))
  227. #
  228. Matrix = [[15, 16, 17, 18, 19],
  229.           [1, 1, 3, 1, 16],
  230.           [2, 8, 8, 6, 17],
  231.           [2, 2, 2, 8, 18],
  232.           [4, 6, 7, 8, 19]]
  233.  
  234. print('Исходная матрица:')
  235. printMatr(Matrix)
  236.  
  237. if not solveAsMin:
  238.     Matrix = maxToMin(Matrix)
  239.  
  240. n = len(Matrix)
  241. m = len(Matrix[0])
  242.  
  243. while n != m:
  244.     if n > m:
  245.         for arr in Matrix:
  246.             arr.append(0)
  247.     else:
  248.         pt = []
  249.         for k in range(m):
  250.             pt.append(0)
  251.         Matrix.append(pt)
  252.     n = len(Matrix)
  253.     m = len(Matrix[0])
  254.  
  255. c = sum([findMinInArr(Matrix[i]) for i in range(len(Matrix))]) + sum(minRow(reduceByMinRow(Matrix)))
  256. print('==================')
  257. print('c = ' + str(c))
  258. print('==================')
  259. Matrix = stepOne(Matrix)
  260. printMatr(Matrix)
  261. print('==================')
  262. stepTwo(Matrix, c)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement