Advertisement
mirosh111000

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

Mar 19th, 2024 (edited)
31
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.28 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.    
  63.  
  64.    
  65.     ratio = []
  66.     min_ratio = np.inf
  67.     for i in range(N):
  68.         if data.iloc[i, min_] != 0:
  69.             r = B[i] / data.iloc[i, min_]
  70.             if r > 0:
  71.                 ratio.append(r)
  72.                 if r < min_ratio:
  73.                     min_ratio = r
  74.                     divider = i
  75.             else:
  76.                 ratio.append('-')
  77.         else:
  78.             ratio.append('-')
  79.            
  80.     table.loc[1:N, 'Оцінне \ відношення'] = ratio[:]
  81.     row_index = divider + 1
  82.     min_ += 4
  83.     solv_a = table.iloc[row_index, min_]
  84.     new_x = table.iloc[0, min_]
  85.    
  86.     db.append(beautiful_table(table, N))
  87.    
  88.     print(table)
  89.    
  90.    
  91.     if direction == 'max':
  92.         test = (table.iloc[N+1, 4:-1] < 0).any()
  93.     if direction == 'min':
  94.         test = (table.iloc[N+1, 4:-1] > 0).any()
  95.    
  96.     while test:
  97.        
  98.         print(f"\nРозв'язувальний елемент: {solv_a} (Рядок: {row_index}; Колонка: {new_x})\n")
  99.        
  100.         new_table = table.copy()
  101.         new_table.iloc[row_index, 2] = new_x
  102.         new_table.iloc[row_index, 1] = new_table.columns[int(min_)]
  103.         if solv_a != 1:
  104.             new_table.iloc[row_index, (-len_x-2):-1] = new_table.iloc[row_index, (-len_x-2):-1].apply(lambda x: x / solv_a)
  105.  
  106.         c = table.iloc[row_index, 3]
  107.         for row in range(1, N+2):
  108.             if new_table.iloc[row, 2] != new_x:
  109.                 a = new_table.iloc[row, 3]
  110.                 b = new_table.iloc[row, min_]
  111.                 new_table.iloc[row, 3] = a - ((b * c) / solv_a)
  112.  
  113.  
  114.         arr = []
  115.         for value in new_table.loc[1:N, 'Базис'].values:
  116.             arr.append(np.where(new_table.iloc[0] == value)[0][0])
  117.         for col in np.sort(arr):
  118.             for i in range(1, N+2):
  119.                 if (new_table.iloc[0, col] == new_table.loc[i, 'Базис']):
  120.                     new_table.iloc[i, col] = 1
  121.                 else:
  122.                     new_table.iloc[i, col] = 0
  123.  
  124.         for col in range(4, 4+len_x):
  125.             if col not in arr:
  126.                 for row in range(1, N+2):
  127.                     if row != row_index:
  128.                         a = table.iloc[row, col]
  129.                         c = table.iloc[row, min_]
  130.                         b = table.iloc[row_index, col]
  131.                         new_table.iloc[row, col] = a - ((b * c) / solv_a)
  132.  
  133.         data = new_table.copy()
  134.         data = data.drop(columns=['№', 'Коеф. \ при \ базисних \ змінних \ ЦФ', 'Базис', 'Вільні \ члени \ системи \ обмежень', 'Оцінне \ відношення'])
  135.         data = data.loc[1:]
  136.         min_ = np.argmin(data.iloc[-1].values) + 4
  137.  
  138.         ratio = []
  139.         min_ratio = np.inf
  140.         for i in range(1, N+1):
  141.             if data.iloc[i-1, min_-4] != 0:
  142.                 r = new_table.iloc[i, 3] / data.iloc[i-1, min_-4]
  143.                 if r <= 0:
  144.                     ratio.append('-')
  145.                 else:
  146.                     ratio.append(r)
  147.                     if r < min_ratio:
  148.                         min_ratio = r
  149.                         divider = i
  150.             else:
  151.                 ratio.append('-')
  152.         new_table.loc[1:N, 'Оцінне \ відношення'] = ratio[:]
  153.         row_index = divider
  154.         solv_a = new_table.iloc[row_index, min_]
  155.         new_x = new_table.iloc[0, min_]
  156.         table = new_table.copy()
  157.         print(new_table.iloc[:, :-1])
  158.         print(new_table.iloc[:, -2:])
  159.  
  160.         db.append(beautiful_table(new_table, N))
  161.        
  162.         if direction == 'max':
  163.             test = (table.iloc[N+1, 4:-1] < 0).any()
  164.         if direction == 'min':
  165.             test = (table.iloc[N+1, 4:-1] > 0).any()
  166.      
  167.     B_full = np.array([0 for i in range(len_x)])
  168.     arr = np.array(arr) - 4
  169.     for i, k in enumerate(arr):
  170.         B_full[k] = np.round(table.iloc[i+1, 3], 4)
  171.     print(f'\nПеревірка\nF = sum({B_full} * {F}) = {np.sum(B_full * F)}')
  172.    
  173.     return pd.concat(db, ignore_index=False), db
  174.  
  175.  
  176.  
  177.  
  178. F = np.array([1, 7, 0, 0, 0, 0])
  179. direction = 'max'
  180.  
  181. A = np.array([
  182.     [3, 4, 1, 0, 0, 0],
  183.     [2, 1, 0, 1, 0, 0],
  184.     [1, 0, 0, 0, 1, 0],
  185.     [0, 5, 0, 0, 0, 1]
  186. ])
  187. B = np.array([264, 140, 68, 150])
  188. print(f'F:\n{F}\nA:\n{A}\nB:\n{B}\n')
  189.  
  190. db, tables = symplex_method(F, A, B, direction)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement