Advertisement
mirosh111000

Симплексний метод

Mar 16th, 2024
31
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.23 KB | None | 0 0
  1. import numpy as np
  2. import pandas as pd
  3.  
  4.  
  5. def beautiful_table(df, N):
  6.     beaut_t = df.copy()
  7.     beaut_t.iloc[1:N+2, 3:-1] = beaut_t.iloc[1:N+2, 3:-1].map(lambda x: np.round(x, 4))
  8.     beaut_t = beaut_t.map(lambda x: f'${x}$')
  9.     beaut_t.index = beaut_t.index.map(lambda x: f'${x}$')
  10.     beaut_t.columns = beaut_t.columns.map(lambda x: f'${x}$')
  11.     beaut_t.index = [' ' for i in range(len(beaut_t.index))]
  12.    
  13.     return beaut_t
  14.  
  15. def symplex_method(F, A, B, direction='max'):
  16.    
  17.     db = []
  18.    
  19.     N = len(A)
  20.    
  21.     columns = ['№', 'Коеф. \ при \ базисних \ змінних \ ЦФ', 'Базис', 'Вільні \ члени \ системи \ обмежень']
  22.     for col in F:
  23.         columns.append(col)
  24.     columns.append('Оцінне \ відношення')
  25.     table = pd.DataFrame(columns=columns)
  26.     row = [' ' for i in range(4)]
  27.     for i in range(len(F)):
  28.         row.append(f'x_{i+1}')
  29.     row.append(' ')
  30.     table.loc[0] = row
  31.     len_x = len(A[0])
  32.    
  33.    
  34.     arr = []
  35.     for i in range(len_x):
  36.         if np.sum(A[:, i] == 0) == N-1:
  37.             arr.append(i)
  38.      
  39.     B_full = np.array([0.0 for i in range(len_x)])
  40.     for i, k in enumerate(arr):
  41.         B_full[k] = B[i]
  42.    
  43.     F_i = np.sum(F * B_full)
  44.    
  45.     for i in range(N):
  46.         row = [i+1, F[arr[i]], f'x_{arr[i]+1}', B[i]]
  47.         for a in (A[i]):
  48.             row.append(a)
  49.         row.append(' ')
  50.         table.loc[i+1] = row
  51.     row = [' ',  ' ', 'F', F_i]
  52.     for i in range(len_x):
  53.         row.append(np.sum(table.iloc[1:N+1, 1] * A[:, i]) - F[i])
  54.     row.append(' ')
  55.     table.loc[max(table.index) + 1] = row
  56.    
  57.     data = table.copy()
  58.     data = data.drop(columns=['№', 'Коеф. \ при \ базисних \ змінних \ ЦФ', 'Базис', 'Вільні \ члени \ системи \ обмежень', 'Оцінне \ відношення'])
  59.     data = data.loc[1:]
  60.     min_ = np.argmin(data.iloc[-1].values)
  61.    
  62.     ratio = []
  63.     min_ratio = np.inf
  64.     for i in range(N):
  65.         r = B[i] / data.iloc[i, min_]
  66.         if r > 0:
  67.             ratio.append(r)
  68.             if r < min_ratio:
  69.                 min_ratio = r
  70.                 divider = i
  71.         else:
  72.             ratio.append('-')
  73.            
  74.     table.loc[1:N, 'Оцінне \ відношення'] = ratio[:]
  75.     row_index = divider + 1
  76.     min_ += 4
  77.     solv_a = table.iloc[row_index, min_]
  78.     new_x = table.iloc[0, min_]
  79.    
  80.     db.append(beautiful_table(table, N))
  81.    
  82.     print(table)
  83.    
  84.    
  85.     if direction == 'max':
  86.         test = (table.iloc[N+1, 4:-1] < 0).any()
  87.     if direction == 'min':
  88.         test = (table.iloc[N+1, 4:-1] > 0).any()
  89.    
  90.     while test:
  91.        
  92.         print(f"\nРозв'язувальний елемент: {solv_a} (Рядок: {row_index}; Колонка: {new_x})\n")
  93.        
  94.         new_table = table.copy()
  95.         new_table.iloc[row_index, 2] = new_x
  96.         new_table.iloc[row_index, 1] = int(min_)
  97.         if solv_a != 1:
  98.             new_table.iloc[row_index, (-len_x-2):-1] = new_table.iloc[row_index, (-len_x-2):-1].apply(lambda x: x / solv_a)
  99.  
  100.         c = table.iloc[row_index, 3]
  101.         for row in range(1, N+2):
  102.             if new_table.iloc[row, 2] != new_x:
  103.                 a = new_table.iloc[row, 3]
  104.                 b = new_table.iloc[row, min_]
  105.                 new_table.iloc[row, 3] = a - ((b * c) / solv_a)
  106.  
  107.  
  108.         arr = []
  109.         for value in new_table.loc[1:N, 'Базис'].values:
  110.             arr.append(np.where(new_table.iloc[0] == value)[0][0])
  111.         for col in np.sort(arr):
  112.             for i in range(1, N+2):
  113.                 if (new_table.iloc[0, col] == new_table.loc[i, 'Базис']):
  114.                     new_table.iloc[i, col] = 1
  115.                 else:
  116.                     new_table.iloc[i, col] = 0
  117.  
  118.         for col in range(4, 4+len_x):
  119.             if col not in arr:
  120.                 for row in range(1, N+2):
  121.                     if row != row_index:
  122.                         a = table.iloc[row, col]
  123.                         c = table.iloc[row, min_]
  124.                         b = table.iloc[row_index, col]
  125.                         new_table.iloc[row, col] = a - ((b * c) / solv_a)
  126.  
  127.         data = new_table.copy()
  128.         data = data.drop(columns=['№', 'Коеф. \ при \ базисних \ змінних \ ЦФ', 'Базис', 'Вільні \ члени \ системи \ обмежень', 'Оцінне \ відношення'])
  129.         data = data.loc[1:]
  130.         min_ = np.argmin(data.iloc[-1].values) + 4
  131.  
  132.         ratio = []
  133.         min_ratio = np.inf
  134.         for i in range(1, N+1):
  135.             if data.iloc[i-1, min_-4] != 0:
  136.                 r = new_table.iloc[i, 3] / data.iloc[i-1, min_-4]
  137.                 if r <= 0:
  138.                     ratio.append('-')
  139.                 else:
  140.                     ratio.append(r)
  141.                     if r < min_ratio:
  142.                         min_ratio = r
  143.                         divider = i
  144.             else:
  145.                 ratio.append('-')
  146.         new_table.loc[1:N, 'Оцінне \ відношення'] = ratio[:]
  147.         row_index = divider
  148.         solv_a = new_table.iloc[row_index, min_]
  149.         new_x = new_table.iloc[0, min_]
  150.         table = new_table.copy()
  151.         print(new_table.iloc[:, :-1])
  152.         print(new_table.iloc[:, -2:])
  153.  
  154.         db.append(beautiful_table(new_table, N))
  155.        
  156.         if direction == 'max':
  157.             test = (table.iloc[N+1, 4:-1] < 0).any()
  158.         if direction == 'min':
  159.             test = (table.iloc[N+1, 4:-1] > 0).any()
  160.      
  161.     B_full = np.array([0 for i in range(len_x)])
  162.     arr = np.array(arr) - 4
  163.     for i, k in enumerate(arr):
  164.         B_full[k] = np.round(table.iloc[i+1, 3], 4)
  165.     print(f'\nПеревірка\nF = sum({B_full} * {F}) = {np.sum(B_full * F)}')
  166.    
  167.     return pd.concat(db, ignore_index=False), db
  168.  
  169. 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")
  170.  
  171. F = np.array([-1, 4, 0, 2, -1])
  172. direction = 'max'
  173.  
  174. A = np.array([
  175.     [1, -5, 1, 0, 0],
  176.     [-1, 1, 0, 1, 0],
  177.     [1, 1, 0, 0, 1]
  178. ])
  179. B = np.array([5, 4, 8])
  180. print(f'F:\n{F}\nA:\n{A}\nB:\n{B}\n')
  181.  
  182. db, tables = symplex_method(F, A, B, direction)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement