Answer the question
In order to leave comments, you need to log in
Why is the modified simplex method looping (Python implementation with numpy)?
I'm trying to implement a modified simplex method in multiplicative form in Python using numpy. I constantly face the problem that it works for me only for maximization, and on small matrices - it calculates large ones with errors, the values of the objective function are very different from what they should be. On minimization most often goes in cycles. The theory is stated, for example, here . Here is an example of my minify code:
class Simplex(object):
def __init__(self, A: np.ndarray, b: np.ndarray, c: np.ndarray):
base_size = A.shape[0] # Кол-во базисных векторов
I = np.eye(base_size) # Единичная матрица - начальный базис системы.
self.extended_matrix = np.concatenate((A, I), axis=1) # Расширенная матрица системы
self.free_size = A.shape[1] # Кол-во свободных векторов
self.b = b # Правые части ограничений
self.base_inv = I # Начальная обратная матрица базиса равна его прямой матрице, т.к. является единичной
self.c = np.concatenate((c, np.zeros(base_size))) # Коэффициенты целевой ф-ции с учетом базисных переменных
self.c_i = [i for i, coeff in enumerate(self.c)] # Индексы всех переменных
@property
def c_f_indices(self):
"""
Индексы свободных переменных.
"""
return self.c_i[:self.free_size]
@property
def c_T_B(self):
"""
Коэффициенты целевой функции при базисных переменных.
"""
c_B_indices = self.c_i[self.free_size:] # Индексы базисных переменных.
return self.c[c_B_indices]
@property
def c_T_f(self):
"""
Коэффициенты целевой функции при свободных переменных.
"""
return self.c[self.c_f_indices]
@property
def free(self):
"""
Свободные векторы.
"""
return self.extended_matrix[:, self.c_f_indices]
@property
def y_T(self):
"""
Вектор относительных оценок (разрешающие множители по Канторовичу).
"""
return self.c_T_B @ self.base_inv
@property
def deltas(self):
"""
Текущие оценки векторов.
"""
return (self.y_T @ self.free) - self.c_T_f
def _swap(self, exits: int, enters: int) -> None:
"""
Включение/исключение в/из базис(-а) соответствующих векторов
"""
self.c_i[enters], self.c_i[exits + self.free_size] = self.c_i[exits + self.free_size], self.c_i[enters]
def optimize(self):
while any([delta > 0 for delta in self.deltas]): # В случае максимизации будет < 0
x_B = self.base_inv @ self.b # Текущие значения базисных переменных
enters_base = np.argmax(self.deltas) # Нахождение вектора, включаемого в базис. В случае максимизации будет argmin
# Нахождение вектора, исключаемого из базиса:
alpha = self.base_inv @ self.free[:, enters_base]
try:
exits_base = np.argmin([b/a if a > 0 else np.inf for b, a in zip(x_B, alpha)])
assert alpha[exits_base] != 0
except (ValueError, AssertionError):
raise Exception("No solutions")
# Нахождение матрицы соотношения E_r и вычисление новой обратной матрицы базиса системы:
zetas = [-alpha[j] / alpha[exits_base] if j != exits_base else 1/alpha[exits_base] for j, a_j in enumerate(alpha)]
E = np.eye(self.free.shape[0])
E[:, exits_base] = zetas
self.base_inv = E @ self.base_inv
# Включение/исключение в/из базис(-а) соответствующих векторов:
self._swap(exits_base, enters_base)
return self.c_T_B @ self.base_inv @ self.b # Итоговое значение целевой функции
Answer the question
In order to leave comments, you need to log in
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question