Advertisement
Guest User

Untitled

a guest
May 22nd, 2019
119
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 7.89 KB | None | 0 0
  1. import time
  2. import sys
  3. import numpy as np
  4. from functools import reduce
  5. from math import gcd
  6.  
  7.  
  8. FILE_PATH = './test.txt'
  9. RANDOM = False
  10. RESULTS_PATH = './result-random.txt'
  11. sys.stdout = open(RESULTS_PATH, 'w')
  12.  
  13. _p = list()
  14. _q = list()
  15.  
  16.  
  17. def generate_matrix_for_input(d=3):
  18.     return np.eye(d)
  19.  
  20.  
  21. def timeit(method):
  22.     def timed(*args, **kw):
  23.         ts = time.time()
  24.         result = method(*args, **kw)
  25.         te = time.time()
  26.         if 'log_time' in kw:
  27.             name = kw.get('log_name', method.__name__.upper())
  28.             kw['log_time'][name] = int((te - ts) * 1000)
  29.         else:
  30.             print('execution time for %r: %2.2f ms' % (
  31.                 method.__name__, (te - ts) * 1000))
  32.         return result
  33.     return timed
  34.  
  35.  
  36. @timeit
  37. def normalize(vector):
  38.     # since vector is a matrix row - convert it to 1-d array
  39.     # (т.к. вектор - строка матрицы: превращаем его в одномерный массив)
  40.     vector = np.array(vector).flatten()  # [[1. 2. 0. 1.]] -> [1. 2. 0. 1.]
  41.     vector = list(map(int, vector))
  42.     if not any(vector):  # we don't need to normalize zero vector (нам не нужно нормализовать нулевой вектор)
  43.         return vector
  44.     _gcd = reduce(lambda x, y: gcd(x, y), vector)  # compute gcd (считаем НОД)
  45.     return np.array(list(map(lambda x: x / _gcd, vector)))  # divide all elements by gcd (делим все элементы на НОД)
  46.  
  47. @timeit
  48. def _bool(vector, xor=False):
  49.     # since vector is a matrix row - convert it to 1-d array
  50.     # (т.к. вектор - строка матрицы: превращаем его в одномерный массив)
  51.     vector = np.array(vector).flatten()  # [[1. 2. 0. 1.]] -> [1. 2. 0. 1.]
  52.     # возвращаем 1 если больше 0, иначе - 0
  53.     if not xor:
  54.         return np.matrix([[int(bool(element))
  55.                            for element in vector]]).transpose()
  56.     else:
  57.         return np.matrix([[1 if element == 1 else 0
  58.                            for element in vector]]).transpose()
  59.  
  60. @timeit
  61. def adjacent(q, j_1, j_2, j_pos_neg):
  62.     for k in range(q.shape[0]):
  63.         if k != j_1 and k != j_2:
  64.             if not any([q[k, m] for m in j_pos_neg]):
  65.                 return False
  66.     return True
  67.  
  68. @timeit
  69. def DDM_DYN(matrix):
  70.  
  71.     m = matrix.shape[0]  # number of rows (количество строк)
  72.     d = matrix.shape[1]  # number of columns (количество столбцов)
  73.  
  74.     U = np.matrix(np.eye(m))  # to understand why m, not d - look at U(0) at tests
  75.     # (чтобы понять, почему тут m - смотри тест U(0)
  76.  
  77.     # V and Q should be width m but without rows
  78.     # (V и Q должны содержать m столбцов но не содержать строк)
  79.     V = np.empty((0, m))  # to understand, why m, not d - look at V(1) at tests
  80.     # (чтобы понять, почему m - смотри V(1) в тестах
  81.     Q = np.empty((0, 0))
  82.  
  83.     print("ITER 0: \nU:\n{U} \nV:\n{V} \nQ:\n{Q}".format(
  84.         U=U, V=V, Q=Q))
  85.  
  86.     for i in range(d):  # m, not d, check tests (we have d iterations)
  87.         # (d итераций - смотри тесты, там d итераций, а не m)
  88.  
  89.         p = U * matrix[:, i]
  90.  
  91.         # if V was just initialized - shape == (0, m)
  92.         # Если V только что инициализировано (нет строк, shape == (0, m)) пишем просто столбец
  93.         q = V * matrix[:, i] if V.shape[0] != 0 else matrix[:, i]
  94.         print("p: ", p)
  95.         print("q: ", q)
  96.  
  97.         if np.count_nonzero(p) == 0:  # if zero vector
  98.             # (если p - нулевой вектор)
  99.             Q = np.hstack((Q, _bool(q)))
  100.  
  101.             j_pos = {idx for idx, value in enumerate(q) if value > 0}
  102.             j_neg = {idx for idx, value in enumerate(q) if value < 0}
  103.  
  104.             V_new = np.empty((0, m))  # same that for V
  105.             # (то же самое, что и для V)
  106.             Q_new = np.empty((0, Q.shape[1]))  # we need to add Q_new rows to Q
  107.             # (нам нужно добавить Q_new к Q - количество столбцов должно быть равно)
  108.  
  109.             r = d - Q.shape[0]  # should be U, but works with Q
  110.  
  111.             for j_1 in j_pos:
  112.                 for j_2 in j_neg:
  113.  
  114.                     j_pos_neg = {k for k in range(Q.shape[1])
  115.                                  if Q[j_1, k] == Q[j_2, k] == 0}
  116.  
  117.                     if len(j_pos_neg) >= r - 2:
  118.                         if adjacent(Q, j_1, j_2, j_pos_neg):
  119.                             V_new = np.vstack(
  120.                                 (V_new, normalize(q[j_1] * V[j_2] - q[j_2] * V[j_1])))
  121.  
  122.                             # disjunction of Q[j_1] and Q[j_2]
  123.                             # (xor - исключающий или Q[j_1] и Q[j_2]
  124.                             xor = _bool(
  125.                                 _bool(Q[j_1]).transpose() + _bool(Q[j_2]).transpose(),
  126.                                 xor=True).transpose()
  127.                             Q_new = np.vstack(
  128.                                 (Q_new, normalize(xor)))
  129.  
  130.             # if Q_new.shape[0]:  # add column if Q_new has rows
  131.             #     Q_new = np.hstack((Q_new, np.zeros((Q_new.shape[0], 1))))
  132.  
  133.             V = np.delete(V, list(j_neg), axis=0)
  134.             Q = np.delete(Q, list(j_neg), axis=0)
  135.  
  136.             if V_new.shape[0]:  # if V_new has rows (numpy won't let add 0xVALUE row or column)
  137.                 # (если V_new имеет строки (numpy не даст нам добавить матрицу без строк)
  138.                 V = np.vstack((V, V_new))
  139.             if Q_new.shape[0]:  # same as for V_new
  140.                 # (то же самое, что для V_new)
  141.                 Q = np.vstack((Q, Q_new))
  142.  
  143.         else:
  144.             j_0 = None
  145.             for idx, value in enumerate(p):
  146.                 if value:
  147.                     j_0 = idx
  148.                     break
  149.  
  150.             if p[j_0] < 0:
  151.                 U[j_0] = -U[j_0]
  152.                 p[j_0] = -p[j_0]
  153.  
  154.             t = U.shape[0]  # t because U shape is (t, d)
  155.             # (потому что размерность U - t на d)
  156.             for j in range(t):  # range(t) because p length equals to number of rows in U
  157.                 # range(t) потому что длина p равна количеству строк в U
  158.                 if j != j_0 and p[j] != 0:
  159.                     U[j] = normalize(
  160.                         p[j_0] * U[j] - p[j] * U[j_0])
  161.  
  162.             s = V.shape[0]  # because V is shape (s, d), check algorithm description
  163.             # (потому что размерность V - s на d, смотри описание алгоритма)
  164.             for j in range(s):
  165.                 if q[j]:
  166.                     V[j] = normalize(
  167.                         p[j_0] * V[j] - q[j] * U[j_0])
  168.  
  169.             V = np.vstack((V, U[j_0]))
  170.             U = np.delete(U, [j_0], axis=0)
  171.  
  172.             if Q.shape == (0, 0):
  173.                 Q = np.matrix([[1]])
  174.             else:
  175.                 Q = np.hstack((Q, np.zeros((Q.shape[0], 1))))
  176.                 Q = np.vstack((Q, [0 for _ in range(Q.shape[1] - 1)] + [1]))
  177.  
  178.         print("ITER {i}: \nU:\n{U} \nV:\n{V} \nQ:\n{Q}".format(
  179.             i=i + 1, U=U, V=V, Q=Q))
  180.  
  181.     return Q, U, V, p, q
  182.  
  183.  
  184. def main():
  185.     if RANDOM:
  186.         matrix = generate_matrix_for_input(d=4)
  187.         print(matrix)
  188.     else:
  189.         with open(FILE_PATH, 'rt') as f:
  190.             matrix = np.matrix([
  191.                 list(map(float, line.split()))
  192.                 for line in f.readlines()
  193.             ])
  194.     print("INPUT MATRIX: {}\n".format(matrix))
  195.     Q, U, V, p, q = DDM_DYN(matrix)
  196.     print("ANSWER: \nQ:\n {Q} \nU:\n {U} \nV:\n {V} \np:\n {p} \nq:\n {q}".format(
  197.         Q=Q, U=U, V=V, p=p, q=q))
  198.  
  199.  
  200. if __name__ == "__main__":
  201.     main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement