Advertisement
Guest User

Untitled

a guest
Oct 18th, 2018
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.50 KB | None | 0 0
  1. import numpy as np
  2. from itertools import combinations
  3.  
  4.  
  5. def get_jb(A):
  6.     m,n = A.shape
  7.     for jb in combinations(range(n), m):
  8.         if abs(np.linalg.det(A[:, jb])) > 0.000001:
  9.             return list(jb)
  10.     raise ValueError('no basic plan')
  11.  
  12.  
  13. def dual_simplex(A, b, c, d_lo, d_hi, Jb=None):
  14.     if Jb is None:
  15.         Jb = get_jb(A)
  16.     m, n = A.shape
  17.     Jn = list(set(range(n)) - set(Jb))
  18.     # print('Jb',Jb)
  19.     B = np.linalg.inv(A[:,list(Jb)])
  20.     y = c[list(Jb)] @ B
  21.     delta = y @ A - c
  22.  
  23.     J_plus = [x for x in Jn if delta[x] >= 0]
  24.     J_minus = [x for x in Jn if delta[x] < 0]
  25.  
  26.     iter = 0
  27.     while iter < 100:
  28.         vector = np.zeros(n)
  29.         vector[J_plus] = d_lo[J_plus]
  30.         vector[J_minus] = d_hi[J_minus]
  31.         vector[Jb] = B @ (b - np.sum(A[:,list(Jn)]*vector[Jn], axis=1))
  32.  
  33.         jk = None
  34.         for i in Jb:
  35.             if not d_lo[i] <= vector[i] <= d_hi[i]:
  36.                 jk = i
  37.                 break
  38.         if jk is None:
  39.             return vector, Jb
  40.        
  41.         myu = 1 if vector[jk] < d_lo[jk] else -1
  42.         k = Jb.index(jk)
  43.         m_vector = B[k] * myu
  44.         myu_n = m_vector @ A[:, Jn]
  45.         steps = np.array([-delta[j] / myu_n[idx]
  46.                  if (j in J_plus and myu_n[idx] < 0) or (j in J_minus and myu_n[idx] > 0)
  47.                  else np.inf
  48.                  for idx, j in enumerate(Jn)])
  49.  
  50.         j_star_idx = np.argmin(steps)
  51.         j_star = Jn[j_star_idx]
  52.         min_step = steps[j_star_idx]
  53.         if min_step == np.inf:
  54.             return None, None
  55.         delta[Jn] += min_step * myu_n
  56.         delta[jk] += min_step * myu
  57.         Jb[Jb.index(jk)] = j_star
  58.  
  59.         M = np.identity(B.shape[0])
  60.         z = B @ A[:, j_star]
  61.         zs = z[k]
  62.         z[k] = -1
  63.         z = -1 / zs * z
  64.         M[:, k] = z
  65.         B = np.dot(M, B)
  66.  
  67.         Jn[j_star_idx] = jk
  68.         if j_star in J_plus:
  69.             if myu == 1:
  70.                 J_plus.remove(j_star)
  71.                 J_plus.append(jk)
  72.             else:
  73.                 J_plus.remove(j_star)
  74.         else:
  75.             if myu == 1:
  76.                 J_plus.append(jk)
  77.             else:
  78.                 pass
  79.         J_minus = list(set(Jn) - set(J_plus))
  80.         iter += 1
  81.     raise RuntimeError('too many iters')
  82.  
  83.  
  84. if __name__ == '__main__':
  85.  
  86.     # A = np.array([
  87.     #     np.array([2, 1, -1, 0, 0, 1], dtype=np.float),
  88.     #     np.array([1, 0,  1, 1, 0, 1], dtype=np.float),
  89.     #     np.array([0, 1,  0, 0, 1, 0], dtype=np.float)
  90.     # ])
  91.     # b = np.array([2, 5, 0], dtype=np.float)
  92.     # c = np.array([3, 2, 0, 3, -2, -4], dtype=np.float)
  93.     # d_low = np.array([0, -1, 2, 1, -1, 0], dtype=np.float)
  94.     # d_high = np.array([2, 4, 4, 3, 3, 5], dtype=np.float)
  95.     #
  96.     # j_b= [3, 4, 5]
  97.     # x0 = dual_simplex(A, b, c, d_low, d_high, j_b)
  98.     # print(x0)
  99.     # print(c @ x0[0])
  100.     #
  101.     # A = np.array([
  102.     #     np.array([1, -5, 3, 1, 0, 0], dtype=np.float),
  103.     #     np.array([4, -1, 1, 0, 1, 0], dtype=np.float),
  104.     #     np.array([2,  4, 2, 0, 0, 1], dtype=np.float)
  105.     # ])
  106.     # b = np.array([-7, 22, 30], dtype=np.float)
  107.     # c = np.array([7, -2, 6, 0, 5, 2], dtype=np.float)
  108.     # d_low = np.array([2, 1, 0, 0, 1, 1], dtype=np.float)
  109.     # d_high = np.array([6, 6, 5, 2, 4, 6], dtype=np.float)
  110.     #
  111.     # x, jb = dual_simplex(A, b, c, d_low, d_high)
  112.     # print(x, jb)
  113.     # print(c @ x)
  114.  
  115.     A = np.array([
  116.         np.array([1, 7, 2, 0, 1, -1, 4], dtype=np.float),
  117.         np.array([0, 5, 6, 1, 0, -3,-2], dtype=np.float),
  118.         np.array([3, 2, 2, 1, 1,  1, 5], dtype=np.float)
  119.     ])
  120.     b = np.array([1, 4, 7], dtype=np.float)
  121.     c = np.array([1, 2, 1, -3, 3, 1, 0], dtype=np.float)
  122.     d_low = np.array([-1, 1, -2, 0, 1, 2, 4], dtype=np.float)
  123.     d_high = np.array([3, 2, 2, 5, 3, 4, 5], dtype=np.float)
  124.  
  125.     x, jb = dual_simplex(A, b, c, d_low, d_high)
  126.     print(x, jb)
  127.  
  128.  
  129.     # A = np.array([
  130.     #     [1, -3, 2, 0, 1, -1, 4, -1, 0],
  131.     #     [1, -1, 6, 1, 0, -2, 2, 2, 0],
  132.     #     [2, 2, -1, 1, 0, -3, 8, -1, 1],
  133.     #     [4, 1, 0, 0, 1, -1, 0, -1, 1],
  134.     #     [1, 1, 1, 1, 1, 1, 1, 1, 1]
  135.     # ], dtype=np.float32)
  136.     # b = np.array([3, 9, 9, 5, 9], dtype=np.float32)
  137.     # c = np.array([-1, 5, -2, 4, 3, 1, 2, 8, 3], dtype=np.float32)
  138.     #
  139.     # d_low = np.array([0, 0, 0, 0, 0, 0, 0, 0, 0],dtype=float)
  140.     # d_high = np.array([5, 5, 5, 5, 5, 5, 5, 5, 5], dtype=float)
  141.     #
  142.     # # j_base = np.array([3, 4, 5, 6, 7])
  143.     # x, jb = dual_simplex(A, b, c, d_low, d_high)
  144.     # print(x, x@c)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement