commit 56a2ca8a77c11baf05b5444b7640cd2bbb989c43
Author: shadowik <zahar.mark@bk.ru>
Date:   Mon Dec 18 04:08:40 2023 +0400

    Initial

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()
+
+