Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import numpy as np
- import pandas as pd
- def beautiful_table(df, N):
- beaut_t = df.copy()
- beaut_t.iloc[1:N+2, 3:-1] = beaut_t.iloc[1:N+2, 3:-1].map(lambda x: np.round(x, 4))
- beaut_t = beaut_t.map(lambda x: f'${x}$')
- beaut_t.index = beaut_t.index.map(lambda x: f'${x}$')
- beaut_t.columns = beaut_t.columns.map(lambda x: f'${x}$')
- beaut_t.index = [' ' for i in range(len(beaut_t.index))]
- return beaut_t
- def symplex_method(F, A, B, direction='max'):
- db = []
- N = len(A)
- columns = ['№', 'Коеф. \ при \ базисних \ змінних \ ЦФ', 'Базис', 'Вільні \ члени \ системи \ обмежень']
- for col in F:
- columns.append(col)
- columns.append('Оцінне \ відношення')
- table = pd.DataFrame(columns=columns)
- row = [' ' for i in range(4)]
- for i in range(len(F)):
- row.append(f'x_{i+1}')
- row.append(' ')
- table.loc[0] = row
- len_x = len(A[0])
- arr = []
- for i in range(len_x):
- if np.sum(A[:, i] == 0) == N-1:
- arr.append(i)
- B_full = np.array([0.0 for i in range(len_x)])
- for i, k in enumerate(arr):
- B_full[k] = B[i]
- F_i = np.sum(F * B_full)
- for i in range(N):
- row = [i+1, F[arr[i]], f'x_{arr[i]+1}', B[i]]
- for a in (A[i]):
- row.append(a)
- row.append(' ')
- table.loc[i+1] = row
- row = [' ', ' ', 'F', F_i]
- for i in range(len_x):
- row.append(np.sum(table.iloc[1:N+1, 1] * A[:, i]) - F[i])
- row.append(' ')
- table.loc[max(table.index) + 1] = row
- data = table.copy()
- data = data.drop(columns=['№', 'Коеф. \ при \ базисних \ змінних \ ЦФ', 'Базис', 'Вільні \ члени \ системи \ обмежень', 'Оцінне \ відношення'])
- data = data.loc[1:]
- min_ = np.argmin(data.iloc[-1].values)
- ratio = []
- min_ratio = np.inf
- for i in range(N):
- r = B[i] / data.iloc[i, min_]
- if r > 0:
- ratio.append(r)
- if r < min_ratio:
- min_ratio = r
- divider = i
- else:
- ratio.append('-')
- table.loc[1:N, 'Оцінне \ відношення'] = ratio[:]
- row_index = divider + 1
- min_ += 4
- solv_a = table.iloc[row_index, min_]
- new_x = table.iloc[0, min_]
- db.append(beautiful_table(table, N))
- print(table)
- if direction == 'max':
- test = (table.iloc[N+1, 4:-1] < 0).any()
- if direction == 'min':
- test = (table.iloc[N+1, 4:-1] > 0).any()
- while test:
- print(f"\nРозв'язувальний елемент: {solv_a} (Рядок: {row_index}; Колонка: {new_x})\n")
- new_table = table.copy()
- new_table.iloc[row_index, 2] = new_x
- new_table.iloc[row_index, 1] = int(min_)
- if solv_a != 1:
- new_table.iloc[row_index, (-len_x-2):-1] = new_table.iloc[row_index, (-len_x-2):-1].apply(lambda x: x / solv_a)
- c = table.iloc[row_index, 3]
- for row in range(1, N+2):
- if new_table.iloc[row, 2] != new_x:
- a = new_table.iloc[row, 3]
- b = new_table.iloc[row, min_]
- new_table.iloc[row, 3] = a - ((b * c) / solv_a)
- arr = []
- for value in new_table.loc[1:N, 'Базис'].values:
- arr.append(np.where(new_table.iloc[0] == value)[0][0])
- for col in np.sort(arr):
- for i in range(1, N+2):
- if (new_table.iloc[0, col] == new_table.loc[i, 'Базис']):
- new_table.iloc[i, col] = 1
- else:
- new_table.iloc[i, col] = 0
- for col in range(4, 4+len_x):
- if col not in arr:
- for row in range(1, N+2):
- if row != row_index:
- a = table.iloc[row, col]
- c = table.iloc[row, min_]
- b = table.iloc[row_index, col]
- new_table.iloc[row, col] = a - ((b * c) / solv_a)
- data = new_table.copy()
- data = data.drop(columns=['№', 'Коеф. \ при \ базисних \ змінних \ ЦФ', 'Базис', 'Вільні \ члени \ системи \ обмежень', 'Оцінне \ відношення'])
- data = data.loc[1:]
- min_ = np.argmin(data.iloc[-1].values) + 4
- ratio = []
- min_ratio = np.inf
- for i in range(1, N+1):
- if data.iloc[i-1, min_-4] != 0:
- r = new_table.iloc[i, 3] / data.iloc[i-1, min_-4]
- if r <= 0:
- ratio.append('-')
- else:
- ratio.append(r)
- if r < min_ratio:
- min_ratio = r
- divider = i
- else:
- ratio.append('-')
- new_table.loc[1:N, 'Оцінне \ відношення'] = ratio[:]
- row_index = divider
- solv_a = new_table.iloc[row_index, min_]
- new_x = new_table.iloc[0, min_]
- table = new_table.copy()
- print(new_table.iloc[:, :-1])
- print(new_table.iloc[:, -2:])
- db.append(beautiful_table(new_table, N))
- if direction == 'max':
- test = (table.iloc[N+1, 4:-1] < 0).any()
- if direction == 'min':
- test = (table.iloc[N+1, 4:-1] > 0).any()
- B_full = np.array([0 for i in range(len_x)])
- arr = np.array(arr) - 4
- for i, k in enumerate(arr):
- B_full[k] = np.round(table.iloc[i+1, 3], 4)
- print(f'\nПеревірка\nF = sum({B_full} * {F}) = {np.sum(B_full * F)}')
- return pd.concat(db, ignore_index=False), db
- print("\nF = -x1 + 4*x2 + 2*x4 - x5 -> max\n / x1 - 5*x2 + x3 = 5\n { -x1 + x2 + x4 = 4\n \ x1 + x2 + x5 = 8\nx1, x_j ≥ 0, j=1,...,5.\n")
- F = np.array([-1, 4, 0, 2, -1])
- direction = 'max'
- A = np.array([
- [1, -5, 1, 0, 0],
- [-1, 1, 0, 1, 0],
- [1, 1, 0, 0, 1]
- ])
- B = np.array([5, 4, 8])
- print(f'F:\n{F}\nA:\n{A}\nB:\n{B}\n')
- db, tables = symplex_method(F, A, B, direction)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement