Kiri3L

4 laba

Dec 13th, 2019
135
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 11.38 KB | None | 0 0
  1. import sys
  2. from Table_printer import print_table
  3.  
  4.  
  5. def parse_file(filename):
  6.     f = open(filename)
  7.     lines = []
  8.     for line in f:
  9.         if not line.startswith('#'):
  10.             lines.append(line.split('|'))
  11.     return lines
  12.  
  13.  
  14. def det2(table):
  15.     return table[0][0]*table[1][1] - table[0][1]*table[1][0]
  16.  
  17.  
  18. def get_submatrix(table, line, colon):
  19.     matrix = []
  20.     for i in range(len(table)):
  21.         if i != line:
  22.             matrix.append([])
  23.             for j in range(len(table)):
  24.                 if j != colon:
  25.                     matrix[-1].append(table[i][j])
  26.     return matrix
  27.  
  28.  
  29. def det(table):
  30.     if len(table) == 1:
  31.         return table[0][0]
  32.     if len(table) == 2:
  33.         return det2(table)
  34.     result = 0
  35.     for i in range(len(table)):
  36.         result += ((-1)**i)*table[i][0]*det(get_submatrix(table, i, 0))
  37.     return result
  38.  
  39.  
  40. def transpose(table):
  41.     matrix = []
  42.     for i in range(len(table)):
  43.         matrix.append([])
  44.         for j in range(len(table)):
  45.             matrix[-1].append(table[j][i])
  46.     return matrix
  47.  
  48.  
  49. def mul_matrix(table, c):
  50.     for i in range(len(table)):
  51.         for j in range(len(table)):
  52.             table[i][j] *= c
  53.     return table
  54.  
  55.  
  56. def print_matrix(table):
  57.     t = []
  58.     t.append('split')
  59.     for l in range(len(table)):
  60.         t.append(table[l])
  61.         t[-1].append(' ')
  62.         t.append('split')
  63.     print_table(t, 2*len(table) + 1, len(table) + 1)
  64.  
  65.  
  66. def invertible_matrix(table):
  67.     print(" Исходная матрица:", end='')
  68.     print_matrix(table)
  69.     d = det(table)
  70.     print("\n det:    {}".format(d))
  71.     if d == 0:
  72.         print('Определитель равен нулю')
  73.         sys.exit()
  74.     d = 1 / d
  75.     print(" det^-1: {}".format(d))
  76.     table = transpose(table)
  77.     new_table = []
  78.     for i in range(len(table)):
  79.         new_table.append([])
  80.         for j in range(len(table)):
  81.             new_table[-1].append((-1)**(i+j)*det(get_submatrix(table, i, j)))
  82.     print("\n Матрица алгебраических дополнений:", end='')
  83.     print_matrix(new_table)
  84.     table = mul_matrix(new_table, d)
  85.     print("\n Обратная матрица: ", end='')
  86.     print_matrix(table)
  87.     return table
  88.  
  89.  
  90. def vector_mull_matrix(vector, matrix):
  91.     if len(vector) != len(matrix):
  92.         print("ERROR")
  93.         sys.exit()
  94.     result = []
  95.     for i in range(len(vector)):
  96.         result.append(0)
  97.         for j in range(len(matrix)):
  98.             result[i] += vector[j]*matrix[i][j]
  99.     return result
  100.  
  101.  
  102. def create_vector(size, index):
  103.     v = []
  104.     for i in range(size):
  105.         if i == index:
  106.             v.append(1)
  107.         else:
  108.             v.append(0)
  109.     return v
  110.  
  111.  
  112. class Table:
  113.     def __init__(self):
  114.         self.basis_coefficient = []
  115.         self.basis_variable = []
  116.         self.non_basis_coefficient = []
  117.         self.non_basis_variable = []
  118.         self.free_numbers = []
  119.         self.table = []
  120.         self.coefficient_in_function = {}
  121.         self.delta = []
  122.         self.Q = 0
  123.         self.count_variables = 0
  124.         self.A = {}
  125.         self.const_free_numbers = []
  126.  
  127.     def input_table(self, filename):
  128.         lines = parse_file(filename)
  129.         counter = 1
  130.         lines[-1].pop(0)
  131.         for token in lines[-1]:
  132.             self.non_basis_coefficient.append(float(token))
  133.             self.non_basis_variable.append('x{}'.format(counter))
  134.             self.coefficient_in_function.setdefault('x{}'.format(counter), float(token))
  135.             counter += 1
  136.  
  137.         lines.pop(-1)
  138.         for line in lines:
  139.             self.basis_coefficient.append(0.0)
  140.             self.basis_variable.append('x{}'.format(counter))
  141.             self.coefficient_in_function.setdefault('x{}'.format(counter), 0.0)
  142.             self.free_numbers.append(float(line.pop(-1)))
  143.  
  144.             counter += 1
  145.             line.pop(0)
  146.             self.table.append([])
  147.             for token in line:
  148.                 self.table[-1].append(float(token))
  149.  
  150.         self.count_variables = counter - 1
  151.         i = 0
  152.         for x in self.non_basis_variable:
  153.             self.A.setdefault(x, get_colon(self.table,i))
  154.             i += 1
  155.         i = 0
  156.         for x in self.basis_variable:
  157.             self.A.setdefault(x, create_vector(len(self.table),i))
  158.             i += 1
  159.         self.const_free_numbers.extend(self.free_numbers)
  160.  
  161.     def print_A(self):
  162.         print(self.A)
  163.  
  164.     def update_delta(self):
  165.         delta = []
  166.         for i in range(len(self.non_basis_coefficient)):
  167.             delta.append(scalar_multi(self.basis_coefficient, get_colon(self.table, i)) - self.non_basis_coefficient[i])
  168.         self.delta = delta
  169.  
  170.     def update_Q(self):
  171.         self.Q = scalar_multi(self.basis_coefficient, self.free_numbers)
  172.  
  173.     def stop(self):
  174.         for val in self.delta:
  175.             if val < 0:
  176.                 return False
  177.  
  178.         return True
  179.  
  180.     def get_resolution_colon(self):
  181.         min = self.delta[0]
  182.         min_index = 0
  183.         for i in range(len(self.delta)):
  184.             if min > self.delta[i]:
  185.                 min = self.delta[i]
  186.                 min_index = i
  187.         return min_index
  188.  
  189.     def get_resolution_line(self, colon):
  190.         min_index = -1
  191.         min = 0
  192.         for i in range(len(self.basis_coefficient)):
  193.             if colon[i] > 0:
  194.                 min_index = i
  195.                 min = self.free_numbers[i] / colon[i]
  196.                 break
  197.  
  198.         for i in range(min_index, len(self.basis_coefficient)):
  199.             if colon[i] > 0:
  200.                 if (self.free_numbers[i] / colon[i]) < min:
  201.                     min = self.free_numbers[i] / colon[i]
  202.                     min_index = i
  203.         if min_index == -1:
  204.             print("ERROR")
  205.             sys.exit()
  206.         return min_index
  207.  
  208.     def update_line(self, line_index, r):
  209.         for i in range(len(self.non_basis_coefficient)):
  210.             self.table[line_index][i] /= r
  211.         self.free_numbers[line_index] /= r
  212.  
  213.     def update_colon(self,colon_index,r):
  214.         for i in range(len(self.basis_coefficient)):
  215.             self.table[i][colon_index] /= r
  216.             self.table[i][colon_index] *= -1
  217.  
  218.     def update_free_number(self, line_index, colon_index):
  219.         for i in range(len(self.free_numbers)):
  220.             if i != line_index:
  221.                 self.free_numbers[i] = rectangle_rule(self.free_numbers[i], self.table[i][colon_index],
  222.                                                       self.free_numbers[line_index], self.table[line_index][colon_index])
  223.  
  224.     def update_other_element(self, line_index, colon_index):
  225.         self.update_free_number(line_index, colon_index)
  226.         for i in range(len(self.basis_coefficient)):
  227.             for j in range(len(self.non_basis_coefficient)):
  228.                 if i != line_index and j != colon_index:
  229.                     self.table[i][j] = rectangle_rule(self.table[i][j],          self.table[i][colon_index],
  230.                                                       self.table[line_index][j], self.table[line_index][colon_index])
  231.  
  232.     def update_coefficient_in_function(self):
  233.         for i in range(len(self.basis_variable)):
  234.             self.coefficient_in_function[self.basis_variable[i]] = self.free_numbers[i]
  235.         for i in range(len(self.non_basis_variable)):
  236.             self.coefficient_in_function[self.non_basis_variable[i]] = 0
  237.  
  238.     def print_function(self):
  239.         print("\n Целевая функция: ")
  240.         X = list(self.coefficient_in_function.keys())
  241.         print(' f(',end='')
  242.         for i in range(len(X) - 1):
  243.             print('{}, '.format(X[i]), end='')
  244.         print('{})'.format(X[-1]), end=' = ')
  245.         print('f(', end='')
  246.         for i in range(len(X) - 1):
  247.             print('{}, '.format(self.coefficient_in_function[X[i]]), end='')
  248.         print('{})'.format(self.coefficient_in_function[X[-1]]), end=' = ')
  249.         print(self.Q)
  250.  
  251.     def update_table(self):
  252.         if self.stop():
  253.             return
  254.         print(" Текущее решение не оптимально. Перестроим симплекс таблицу\n Найдем разрешающий элемент:")
  255.         j = self.get_resolution_colon()
  256.         i = self.get_resolution_line(get_colon(self.table, j))
  257.         r = self.table[i][j]
  258.         temp_x_coef = self.basis_coefficient[i]
  259.         temp_x = self.basis_variable[i]
  260.         self.basis_coefficient[i] = self.non_basis_coefficient[j]
  261.         self.basis_variable[i] = self.non_basis_variable[j]
  262.         self.non_basis_coefficient[j] = temp_x_coef
  263.         self.non_basis_variable[j] = temp_x
  264.         print(' Разрешающий столбец: {} Разрешающая строка: {} Разрешающий элемент {}'.format(j, i, r))
  265.         self.update_other_element(i, j)
  266.         self.update_colon(j, r)
  267.         self.update_line(i, r)
  268.         self.table[i][j] = 1.0 / r
  269.         self.update_delta()
  270.         self.update_Q()
  271.         self.update_coefficient_in_function()
  272.         self.print_table()
  273.  
  274.     def dual_solution(self):
  275.         dual_matrix = []
  276.         for x in self.basis_variable:
  277.             dual_matrix.append(self.A[x])
  278.         dual_matrix = invertible_matrix(dual_matrix)
  279.         result = vector_mull_matrix(self.basis_coefficient, dual_matrix)
  280.         print(' Умножим вектор коэффициентов при базисных векторах на получившуюся матрицу:\n')
  281.         print(' В результате получим вектор-столбец значений двойственной задачи переменных двойственной задачи\n ' + str(result))
  282.         print("\n min(g(y)) = max(f(x)) = ",end='')
  283.         print(scalar_multi(self.const_free_numbers, result))
  284.  
  285.     def print_table(self):
  286.         t = list()
  287.         t.append('split')
  288.         t.append(['  ', ' свободные '])
  289.         t[1].extend(self.non_basis_coefficient)
  290.         t[1].append(' ')
  291.         t[1].append(' ')
  292.         t.append('split')
  293.         t.append([' базис ', '  '])
  294.         t[3].extend(self.non_basis_variable)
  295.         t[3].append(' А ')
  296.         t[3].append(' ')
  297.         t.append('split')
  298.         for i in range(len(self.basis_variable)):
  299.             t.append([self.basis_coefficient[i], self.basis_variable[i]])
  300.             for j in range(len(self.non_basis_coefficient)):
  301.                 t[-1].append(self.table[i][j])
  302.             t[-1].append(self.free_numbers[i])
  303.             t[-1].append(' ')
  304.             t.append('split')
  305.  
  306.         t.append([' '])
  307.         t[-1].append('   f ')
  308.         for i in range(len(self.non_basis_coefficient)):
  309.             t[-1].append(self.delta[i])
  310.         t[-1].append(self.Q)
  311.         t[-1].append(' ')
  312.         t.append('split')
  313.         print_table(t, 2*len(self.basis_variable) + 7, len(self.non_basis_variable) + 4)
  314.         self.print_function()
  315.  
  316.  
  317. def get_colon(table, index):
  318.     colon = []
  319.     for line in table:
  320.         colon.append(line[index])
  321.     return colon
  322.  
  323.  
  324. def scalar_multi(C, A):
  325.     if len(C) != len(A):
  326.         print('ERROR 1')
  327.         return
  328.     result = 0
  329.     for i in range(len(C)):
  330.         result += C[i] * A[i]
  331.     return result
  332.  
  333.  
  334. def rectangle_rule(x1, x2, x3, x4):
  335.     return (x1 * x4 - x2 * x3) / x4
  336.  
  337.  
  338. t = Table()
  339. t.input_table('input2.txt')
  340. t.update_delta()
  341. t.update_Q()
  342. t.print_table()
  343. while not t.stop():
  344.     t.update_table()
  345.     print()
  346.  
  347. t.dual_solution()
Advertisement
Add Comment
Please, Sign In to add comment