Advertisement
lutaco

Роди 4 лаба

May 24th, 2018
99
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.95 KB | None | 0 0
  1. # Молотков Иван molotkov.1997@mail.ru
  2. # Дробный алгоритм метода отсечений
  3.  
  4. from fractions import Fraction
  5. import numpy as np
  6. from copy import deepcopy
  7. from math import floor, ceil
  8.  
  9. # Эта хня создает массив B, содержащий коэффициенты в простых дробях
  10. def getB(A):
  11.     B = []
  12.     for i in range(len(A)):
  13.         B.append([])
  14.         for k in range(len(A[0])):
  15.             B[i].append(Fraction(A[i][k]))
  16.     return B
  17.  
  18. # Печать массива B
  19. def printla(B):
  20.     print(str(np.array(B)).replace('Fraction', '').replace(', ', ' / '))
  21.  
  22. # Принимает массив В и координаты ведущего элемента, возвращает новый массив В с каким-то там преобразованием
  23. def ref(B, newBas):
  24.     a = newBas[0]
  25.     b = newBas[1]
  26.     C = deepcopy(B)
  27.     for i in range(len(C)):
  28.         for k in range(len(C[0])):
  29.             if ( k == b):
  30.                 B[i][k] = (-C[i][k] / C[a][b])
  31.             else:
  32.                 B[i][k] = ((C[i][k] - C[a][k] * C[i][b] / C[a][b]))
  33.     return B
  34.  
  35. # Эта хрень ищет ведущий элемент
  36. def find1(B, cur_bas):
  37.     if True: # True для выбора минимального индекса, False для максимального
  38.         b = B[0].index(min(B[0][1:]))
  39.     else:
  40.         la = B[0][1:]
  41.         la.reverse()
  42.         b = len(la) - la.index(min(la))
  43.  
  44.     st = [
  45.         B[i][0] / B[i][b]
  46.         if B[i][b] != 0 # Не делить же на ноль
  47.         and i not in cur_bas and i != 0
  48.         and (np.sign(B[i][0]) == 0 and np.sign(B[i][b]) == 1
  49.         or (np.sign(B[i][0]) * np.sign(B[i][b])) == 1)
  50.         else np.inf
  51.         for i in range(len(B))
  52.     ]
  53.     if (min(st) is np.inf):
  54.         return None
  55.     a = st.index(min(st))
  56.     cur_bas[b - 1] = a
  57.     return(a, b)
  58.  
  59. # Ведущий элемент для псевдооптимального плана
  60. def find2(B, bb):
  61.     tm = [
  62.         B[i][0]
  63.         if i not in bb and i != 0
  64.         else np.inf
  65.         for i in range(len(B))
  66.     ]
  67.     a = tm.index(min(tm))
  68.    
  69.     st = [
  70.         - B[0][i] / B[a][i]
  71.         if B[a][i] != 0 # Не делить же на ноль
  72.         and i != 0
  73.         and (np.sign(-B[0][i]) == 0 and np.sign(B[a][i]) == 1
  74.         or (np.sign(-B[0][i]) * np.sign(B[a][i])) == 1)
  75.         else np.inf
  76.         for i in range(0, len(B[a]))
  77.     ]
  78.     if (min(st) is np.inf):
  79.         return None
  80.     t = st.index(min(st))
  81.     for i in range(1, len(st)):
  82.         if st[i] is not np.inf:
  83.             if st[i] == st[t]:
  84.                 if False: # True для выбора минимального индекса, False для максимального
  85.                     if bb[i - 1] < bb[t - 1]:  
  86.                         t = i
  87.                 else:
  88.                     if bb[i - 1] > bb[t - 1]:
  89.                         t = i
  90.     b = t
  91.     bb[b - 1] = a
  92.     return(a, b)
  93.  
  94. # Возвращает true, если решение оптимально
  95. def opt(B):
  96.     if (min(B[0][1:]) < 0):
  97.         return 1
  98.     if (min([B[i][0] for i in range(1, len(B))]) < 0):
  99.         return 2
  100.     return 0
  101.  
  102. # Делает отсечение и возвращает индекс переменной, для которой идет отсечение
  103. def ots(B):
  104.     lala = [B[i][0] -floor(B[i][0]) for i in range(1, len(B[0]))]
  105.     x = int(lala.index(max(lala)) + 1)
  106.     B.append([floor(B[x][i])-B[x][i] for i in range(0, len(B[0]))])
  107.     return x
  108.  
  109. # Ищет ведущий элемент
  110. def find(B, bb):
  111.     if (opt(B) == 1):
  112.         return find1(B, Bas)
  113.     else:
  114.         return find2(B, Bas)
  115. print('okay')
  116.  
  117. # Решение
  118.  
  119. A = np.array([
  120.     [0, -1, 0],
  121.     [0, -1, 0],
  122.     [0, 0, -1],
  123.     [12, 1, 3],
  124.     [24, 3, -8],
  125. ])
  126.  
  127. B = getB(A)
  128. Bas = [i for i in range(1, len(B[0]))]
  129.  
  130. Bas0  = deepcopy(Bas)
  131. B0 = deepcopy(B)
  132. flag = 0
  133. n_it = 50
  134. it = n_it
  135. while True:
  136.     # Оптимальное решение
  137.     while (opt(B) != 0):
  138.         print(Bas)
  139.         printla(B)
  140.         newBas = find(B, Bas)
  141.         if (newBas is None):
  142.             print('Вроде как такое не решить...')
  143.             flag = 1
  144.             break
  145.         print(newBas)
  146.         print('\n')
  147.         ref(B, newBas)
  148.         it -= 1
  149.         if it == 0:
  150.             print('Кажется мы зациклились :(')
  151.             flag = 1
  152.             break
  153.     if flag == 1:
  154.         break            
  155.     # Вывод оптимального решения
  156.     print(Bas)
  157.     printla(B)
  158.     print('\n')
  159.    
  160.     if sum([abs(floor(B[i][0]) - B[i][0]) for i in range(len(B))]) == 0:
  161.         break
  162.     # Отсечение
  163.     print('Отсечение x = ', ots(B))
  164.     it -= 1
  165.    
  166. print('Итераций', n_it - it)
  167.  
  168. print('F =', B[0][0])
  169. for i in range(1, len(B[0])):
  170.     print ('x', i, '=', B[i][0])
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement