Files
VM_lab_PIbd_31_Akimova_A.A/SimplexMethod.py

80 lines
3.4 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import numpy as np
class SimplexMethod:
def __init__(self, source):
# исходная таблица source
m, n = source.shape
# table - таблица, с которой будем работать
# basis - базисные переменные
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