From 56a2ca8a77c11baf05b5444b7640cd2bbb989c43 Mon Sep 17 00:00:00 2001 From: shadowik Date: Mon, 18 Dec 2023 04:08:40 +0400 Subject: [PATCH] Initial --- main.py | 148 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 main.py diff --git a/main.py b/main.py new file mode 100644 index 0000000..ef8187d --- /dev/null +++ b/main.py @@ -0,0 +1,148 @@ +import numpy as np + + +class Config: + lst: list[[np.ndarray, str, float]] = [] + + def add(self, a: np.array, sim: str, b: float): + self.lst.append([a, sim, b]) + + def lst_to_canon(self): + for row in self.lst: + if row[2] < 0: + row[0] *= -1 + if row[1] == ">=": + row[1] = "<=" + elif row[1] == "<=": + row[1] = ">=" + row[2] *= -1 + + for index_row in range(len(self.lst)): + if self.lst[index_row][1] == "<=": + self.lst[index_row][0] = np.append(self.lst[index_row][0], 1) + elif self.lst[index_row][1] == ">=": + self.lst[index_row][0] = np.append(self.lst[index_row][0], -1) + self.lst[index_row][1] = "=" + for index_extra_row in range(len(self.lst)): + if index_row == index_extra_row: + continue + self.lst[index_extra_row][0] = np.append(self.lst[index_extra_row][0], 0) + + +class Simplex: + canon_conf: list[[np.ndarray, float, int | None]] = [] + func: np.ndarray + count: int + lst_header: list = ["ind", "bas", "Cb", "b"] + + def __init__(self, canon_cfg, func): + self.func = func + for row in canon_cfg: + self.canon_conf.append([row[0], row[2], None]) + self.count = len(canon_cfg[0][0]) + for i in range(self.count): + self.lst_header.append(f"x{i}") + + def find_basis(self): + busy = set() + for i in range(len(self.canon_conf)): + for j in range(len(self.canon_conf[i][0])): + if self.canon_conf[i][0][j] == 0: + continue + if self.canon_conf[i][1] / self.canon_conf[i][0][j] < 0: + continue + for k in range(len(self.canon_conf)): + if k == i: + continue + if self.canon_conf[k][0][j] != 0: + break + else: + busy.add(i) + self.canon_conf[i][2] = j + self.canon_conf[i][1] /= self.canon_conf[i][0][self.canon_conf[i][2]] + self.canon_conf[i][0] /= self.canon_conf[i][0][self.canon_conf[i][2]] + break + + if self.canon_conf[i][2] is None: + raise Exception("No basis") + + def method(self): + while True: + m = [sum([i[1] * self.func[i[2]] if i[2] < len(self.func) else 0 for i in self.canon_conf]), + [sum([row[0][i] * self.func[row[2]] if row[2] < len(self.func) else 0 for row in self.canon_conf]) + - (self.func[i] if i < len(self.func) else 0) for i in range(self.count)]] + self.print_table(m) + + col = -1 + for i in range(len(m[1])): + if m[1][i] > 0: + col = i + break + else: + return + + mi = 999999 + row = -1 + for i in range(len(self.canon_conf)): + if self.canon_conf[i][0][col] <= 0: + continue + buff = self.canon_conf[i][1] / self.canon_conf[i][0][col] + if buff < mi: + row = i + mi = buff + + if row < 0: + raise Exception("strange") + + k = self.canon_conf[row][0][col] + self.canon_conf[row][2] = col + + lst = [] + for i in range(len(self.canon_conf)): + lst.append(np.append([self.canon_conf[i][1]], self.canon_conf[i][0]).tolist()) + + self.canon_conf[row][1] /= k + self.canon_conf[row][0] /= k + + for i in range(len(self.canon_conf)): + if i == row: + continue + self.canon_conf[i][1] = self.canon_conf[i][1] - ((lst[row][0] * lst[i][col + 1]) / k) + for j in range(len(self.canon_conf[i][0])): + if j == col: + self.canon_conf[i][0][j] = 0 + else: + self.canon_conf[i][0][j] = self.canon_conf[i][0][j] - ((lst[row][j + 1] * lst[i][col + 1]) / k) + + def print_table(self, m: list | None = None): + print("Table:") + print("-" * 100) + print("".join([f"{i:<10}" for i in self.lst_header])) + for i in range(len(self.canon_conf)): + lst_data_row = [f"{i + 1}", f"{self.canon_conf[i][2]}"] + if self.canon_conf[i][2] >= len(self.func): + lst_data_row.append("0") + else: + lst_data_row.append(f"{self.func[self.canon_conf[i][2]]}") + lst_data_row.append(f"{self.canon_conf[i][1]}") + lst_data_row = np.append(lst_data_row, self.canon_conf[i][0]) + print("".join([f"{i:<10.7}" for i in lst_data_row])) + if m is not None: + lst_m = ["m + 1", " ", " ", m[0]] + m[1] + print("".join([f"{i:<10.7}" for i in lst_m])) + print("-" * 100) + + +if __name__ == "__main__": + Z = np.array([18, 16, 5, 21], dtype="float64") + conf = Config() + conf.add(np.array([1, 2, 0, 3], dtype="float64"), ">=", 2) + conf.add(np.array([3, 1, 1, 0], dtype="float64"), ">=", 3) + conf.lst_to_canon() + + simp = Simplex(conf.lst, np.array([18, 16, 5, 21])) + simp.find_basis() + # simp.print_table() + simp.method() + +