commit e1718b8ed7810d0d2fd60e21ac555aa01fe5ee0e Author: Danil Markov Date: Sun Dec 17 20:46:49 2023 +0400 Лабораторная работа по вычислительной математике diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..06bb031 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,12 @@ + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..07dd808 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..e15ec35 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/pythonProject.iml b/.idea/pythonProject.iml new file mode 100644 index 0000000..d0876a7 --- /dev/null +++ b/.idea/pythonProject.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Simplex.py b/Simplex.py new file mode 100644 index 0000000..6c40a8b --- /dev/null +++ b/Simplex.py @@ -0,0 +1,83 @@ +import numpy as np + + +class Simplex: + def __init__(self, source): + # Инициализация объекта Simplex с исходной таблицей source + m, n = source.shape + # Инициализация таблицы и списка базисных переменных + self.table = np.zeros((m, n + m - 1)) + self.basis = [] + + # Формирование начальной симплекс-таблицы + for i in range(m): + for j in range(self.table.shape[1]): + if j < n: + # Копирование коэффициентов из исходной таблицы + self.table[i, j] = source[i, j] + else: + # Добавление единичных столбцов для базисных переменных + self.table[i, j] = 0 + + if (n + i) < self.table.shape[1]: + # Установка единицы в соответствующем столбце для базисной переменной + self.table[i, n + i] = 1 + # Добавление базисной переменной в список + self.basis.append(n + i) + + self.m = m + self.n = self.table.shape[1] + + def calculate(self, result): + # Основной цикл симплекс-метода + while not self.is_it_end(): + # Нахождение ведущей колонки и строки + main_col = self.find_main_col() + main_row = self.find_main_row(main_col) + # Обновление списка базисных переменных + self.basis[main_row] = main_col + + # Пересчет симплекс-таблицы + new_table = np.zeros((self.m, self.n)) + for j in range(self.n): + # Нормализация ведущей строки + new_table[main_row, j] = self.table[main_row, j] / self.table[main_row, main_col] + for i in range(self.m): + if i == main_row: + continue + for j in range(self.n): + # Обновление остальных строк таблицы + new_table[i, j] = self.table[i, j] - self.table[i, main_col] * new_table[main_row, j] + self.table = new_table + + # Получение решения + for i in range(len(result)): + # Извлечение значений переменных из базиса + k = self.basis.index(i + 1) if i + 1 in self.basis else -1 + result[i] = self.table[k, 0] if k != -1 else 0 + + return self.table + + def is_it_end(self): + # Проверка критерия окончания: все элементы последней строки неотрицательны + return np.all(self.table[self.m - 1, 1:] >= 0) + + def find_main_col(self): + # Нахождение ведущей колонки: минимальный отрицательный коэффициент в последней строке + main_col = 1 + for j in range(2, self.n): + if self.table[self.m - 1, j] < self.table[self.m - 1, main_col]: + main_col = j + return main_col + + def find_main_row(self, main_col): + # Нахождение ведущей строки: минимальное положительное отношение свободного члена к ведущему элементу + main_row = 0 + for i in range(self.m - 1): + if self.table[i, main_col] > 0: + main_row = i + break + for i in range(main_row + 1, self.m - 1): + if self.table[i, main_col] > 0 and (self.table[i, 0] / self.table[i, main_col]) < (self.table[main_row, 0] / self.table[main_row, main_col]): + main_row = i + return main_row \ No newline at end of file diff --git a/main.py b/main.py new file mode 100644 index 0000000..4f94595 --- /dev/null +++ b/main.py @@ -0,0 +1,24 @@ +import numpy as np + +from Simplex import Simplex + +table = np.array([[7, 1, 1, 1, 1], + [2, -1, 1, -1, 1], + [-5, 3, -1, -2, 0], + [0, -1, 2, -3, 0]]) + +result = np.zeros(3) +S = Simplex(table) +table_result = S.calculate(result) + +print("Решенная симплекс-таблица:") +for i in range(table_result.shape[0]): + for j in range(table_result.shape[1]): + print(table_result[i, j], end=" ") + print() + +print() +print("Решение:") +print("X[1] =", result[0]) +print("X[2] =", result[1]) +print("X[3] =", result[2]) \ No newline at end of file