LabWork1
This commit is contained in:
commit
b2df8b08a1
73
lab1.py
Normal file
73
lab1.py
Normal file
@ -0,0 +1,73 @@
|
||||
import numpy as np
|
||||
|
||||
def simplex_method(c, A, b):
|
||||
m, n = A.shape
|
||||
c = np.concatenate([c, np.zeros(m)]) # Дополнение коэффициентов целевой функции нулями
|
||||
A = np.column_stack([A, np.eye(m)]) # Дополнение матрицы A единичной матрицей
|
||||
basis = np.arange(n, n + m) # Индексы базисных переменных
|
||||
|
||||
while True:
|
||||
# Шаг 1: Проверка на оптимальность
|
||||
|
||||
# Рассчитываем приведенные затраты (reduced_costs), вычитая из коэффициентов целевой функции (c)
|
||||
# линейную комбинацию базисных переменных и соответствующих им строк матрицы A.
|
||||
# Приведенные затраты - оценки изменения целевой функции при изменении значений переменных.
|
||||
reduced_costs = c - np.dot(c[basis], A)
|
||||
|
||||
# Если все приведенные затраты неотрицательны (все переменные в базисе удовлетворяют условиям оптимальности),
|
||||
# то достигнуто оптимальное решение, и цикл прерывается.
|
||||
if all(reduced_costs >= 0):
|
||||
break
|
||||
|
||||
# Шаг 2: Выбор входящей переменной
|
||||
# определяем индекс переменной, которую мы добавим в базис (войдет в решение) на следующей итерации.
|
||||
# выбираем переменную с наименьшим уменьшенным коэффициентом в функции цели.
|
||||
entering_var = np.argmin(reduced_costs)
|
||||
|
||||
# Шаг 3: Проверка на неограниченность
|
||||
# Проверяем, если все элементы столбца матрицы A, соответствующего входящей переменной,
|
||||
# меньше или равны нулю. Если это условие выполняется, то проблема неограничена.
|
||||
if all(A[:, entering_var] <= 0):
|
||||
raise Exception("Проблема неограничена")
|
||||
|
||||
# Шаг 4: Выбор выходящей переменной
|
||||
# Рассчитываем отношения значений правых частей к соответствующим коэффициентам входящей переменной в матрице A.
|
||||
# Если коэффициент входящей переменной положителен, оставляем отношение, иначе присваиваем бесконечность.
|
||||
ratios = np.divide(b, A[:, entering_var], out=np.full_like(b, np.inf, dtype=float), where=A[:, entering_var] > 0)
|
||||
|
||||
# Находим индекс минимального отношения, который определяет выходящую переменную.
|
||||
leaving_var = np.argmin(ratios)
|
||||
|
||||
# Шаг 5: Обновление базиса
|
||||
# Обновляем базис, заменяя выходящую переменную на входящую переменную.
|
||||
basis[leaving_var] = entering_var
|
||||
|
||||
|
||||
# Шаг 6: Обновление симплекс-таблицы
|
||||
pivot = A[leaving_var, entering_var] # Выбор опорного элемента (пересечение строки и столбца)
|
||||
A[leaving_var, :] /= pivot # Деление строки с опорным элементом на опорный элемент
|
||||
b[leaving_var] /= pivot # Деление правой части на опорный элемент
|
||||
for i in range(m):
|
||||
if i != leaving_var:
|
||||
factor = A[i, entering_var] # Выбор элемента в столбце входящей переменной
|
||||
A[i, :] -= factor * A[leaving_var, :] # Обновление строки матрицы
|
||||
b[i] -= factor * b[leaving_var] # Обновление правой части
|
||||
|
||||
c -= reduced_costs[entering_var] * A[leaving_var, :] # Обновление коэффициентов целевой функции
|
||||
|
||||
# Извлечение решения из симплекс-таблицы
|
||||
solution = np.zeros(n)
|
||||
for i in range(m):
|
||||
if basis[i] < n:
|
||||
solution[basis[i]] = b[i] # Извлечение значений базисных переменных из симплекс-таблицы
|
||||
|
||||
|
||||
return solution
|
||||
|
||||
# Пример использования:
|
||||
c = np.array([-3, -2]) # Коэффициенты целевой функции для минимизации
|
||||
A = np.array([[1, 2], [2, 1], [1, -1]]) # Коэффициенты ограничений-неравенств
|
||||
b = np.array([4, 7, 1]) # Значения правых частей ограничений
|
||||
|
||||
result = simplex_method(c, A, b)
|
||||
print("Оптимальное решение:", result)
|
Loading…
x
Reference in New Issue
Block a user