Feature: Completed lab
This commit is contained in:
parent
67c0bc343d
commit
14e8a11374
28
Simplex.py
28
Simplex.py
@ -1,73 +1,83 @@
|
|||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
|
|
||||||
class Simplex:
|
class Simplex:
|
||||||
def __init__(self, source):
|
def __init__(self, source):
|
||||||
|
# Инициализация объекта Simplex с исходной таблицей source
|
||||||
m, n = source.shape
|
m, n = source.shape
|
||||||
|
# Инициализация таблицы и списка базисных переменных
|
||||||
self.table = np.zeros((m, n + m - 1))
|
self.table = np.zeros((m, n + m - 1))
|
||||||
self.basis = []
|
self.basis = []
|
||||||
|
|
||||||
|
# Формирование начальной симплекс-таблицы
|
||||||
for i in range(m):
|
for i in range(m):
|
||||||
for j in range(self.table.shape[1]):
|
for j in range(self.table.shape[1]):
|
||||||
if j < n:
|
if j < n:
|
||||||
|
# Копирование коэффициентов из исходной таблицы
|
||||||
self.table[i, j] = source[i, j]
|
self.table[i, j] = source[i, j]
|
||||||
else:
|
else:
|
||||||
|
# Добавление единичных столбцов для базисных переменных
|
||||||
self.table[i, j] = 0
|
self.table[i, j] = 0
|
||||||
|
|
||||||
if (n + i) < self.table.shape[1]:
|
if (n + i) < self.table.shape[1]:
|
||||||
|
# Установка единицы в соответствующем столбце для базисной переменной
|
||||||
self.table[i, n + i] = 1
|
self.table[i, n + i] = 1
|
||||||
|
# Добавление базисной переменной в список
|
||||||
self.basis.append(n + i)
|
self.basis.append(n + i)
|
||||||
|
|
||||||
self.m = m
|
self.m = m
|
||||||
self.n = self.table.shape[1]
|
self.n = self.table.shape[1]
|
||||||
|
|
||||||
def calculate(self, result):
|
def calculate(self, result):
|
||||||
|
# Основной цикл симплекс-метода
|
||||||
while not self.is_it_end():
|
while not self.is_it_end():
|
||||||
|
# Нахождение ведущей колонки и строки
|
||||||
main_col = self.find_main_col()
|
main_col = self.find_main_col()
|
||||||
main_row = self.find_main_row(main_col)
|
main_row = self.find_main_row(main_col)
|
||||||
|
# Обновление списка базисных переменных
|
||||||
self.basis[main_row] = main_col
|
self.basis[main_row] = main_col
|
||||||
|
|
||||||
|
# Пересчет симплекс-таблицы
|
||||||
new_table = np.zeros((self.m, self.n))
|
new_table = np.zeros((self.m, self.n))
|
||||||
|
|
||||||
for j in range(self.n):
|
for j in range(self.n):
|
||||||
|
# Нормализация ведущей строки
|
||||||
new_table[main_row, j] = self.table[main_row, j] / self.table[main_row, main_col]
|
new_table[main_row, j] = self.table[main_row, j] / self.table[main_row, main_col]
|
||||||
|
|
||||||
for i in range(self.m):
|
for i in range(self.m):
|
||||||
if i == main_row:
|
if i == main_row:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
for j in range(self.n):
|
for j in range(self.n):
|
||||||
|
# Обновление остальных строк таблицы
|
||||||
new_table[i, j] = self.table[i, j] - self.table[i, main_col] * new_table[main_row, j]
|
new_table[i, j] = self.table[i, j] - self.table[i, main_col] * new_table[main_row, j]
|
||||||
|
|
||||||
self.table = new_table
|
self.table = new_table
|
||||||
|
|
||||||
|
# Получение решения
|
||||||
for i in range(len(result)):
|
for i in range(len(result)):
|
||||||
|
# Извлечение значений переменных из базиса
|
||||||
k = self.basis.index(i + 1) if i + 1 in self.basis else -1
|
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
|
result[i] = self.table[k, 0] if k != -1 else 0
|
||||||
|
|
||||||
return self.table
|
return self.table
|
||||||
|
|
||||||
def is_it_end(self):
|
def is_it_end(self):
|
||||||
|
# Проверка критерия окончания: все элементы последней строки неотрицательны
|
||||||
return np.all(self.table[self.m - 1, 1:] >= 0)
|
return np.all(self.table[self.m - 1, 1:] >= 0)
|
||||||
|
|
||||||
def find_main_col(self):
|
def find_main_col(self):
|
||||||
|
# Нахождение ведущей колонки: минимальный отрицательный коэффициент в последней строке
|
||||||
main_col = 1
|
main_col = 1
|
||||||
|
|
||||||
for j in range(2, self.n):
|
for j in range(2, self.n):
|
||||||
if self.table[self.m - 1, j] < self.table[self.m - 1, main_col]:
|
if self.table[self.m - 1, j] < self.table[self.m - 1, main_col]:
|
||||||
main_col = j
|
main_col = j
|
||||||
|
|
||||||
return main_col
|
return main_col
|
||||||
|
|
||||||
def find_main_row(self, main_col):
|
def find_main_row(self, main_col):
|
||||||
|
# Нахождение ведущей строки: минимальное положительное отношение свободного члена к ведущему элементу
|
||||||
main_row = 0
|
main_row = 0
|
||||||
|
|
||||||
for i in range(self.m - 1):
|
for i in range(self.m - 1):
|
||||||
if self.table[i, main_col] > 0:
|
if self.table[i, main_col] > 0:
|
||||||
main_row = i
|
main_row = i
|
||||||
break
|
break
|
||||||
|
|
||||||
for i in range(main_row + 1, self.m - 1):
|
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]):
|
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
|
main_row = i
|
||||||
|
|
||||||
return main_row
|
return main_row
|
Loading…
Reference in New Issue
Block a user