Загрузить файлы в «/»

This commit is contained in:
Злата Петракова 2024-06-24 21:19:18 +00:00
parent 20460f30aa
commit 9c0b165a6b

429
tropicZ.py Normal file
View File

@ -0,0 +1,429 @@
# -*- coding: utf-8 -*-
"""tropic.ipynb
Automatically generated by Colab.
Original file is located at
https://colab.research.google.com/drive/14lR3A29PgCuP9jUS9quiNFYPcYhZvxLi
"""
class TropicZ(object):
def __init__(self, infty = 1000, add_op = 'max'):
self.__infty = infty
self._posinf = infty
self._neginf = -infty
self.add_op = max
if add_op == 'min':
self.add_op = min
@property
def neginf(self):
return TropicZ.TropicElement(self, self._neginf)
@property
def posinf(self):
return TropicZ.TropicElement(self, self._posinf)
def elem(self, val = 0):
'''
Формирует тропический элемента из целого числа val
'''
return TropicZ.TropicElement(self, val)
class TropicElement(object):
def __init__(self, outer_instance, val = 0):
self.__outer_instance = outer_instance
self._val = self.bound(val)
def bound(self, val = 0):
neginf = self.__outer_instance._neginf
posinf = self.__outer_instance._posinf
return min(max(int(val), neginf), posinf)
def __repr__(self):
return str(self)
def __str__(self):
return str(self._val)
def __iter__(self):
return self.entries.__iter__()
def add(self, val):
'''
Тропическое сложение текущего элемента с значением val
'''
if isinstance(val, TropicZ.TropicElement):
result = val._val
else:
result = int(val)
op = self.__outer_instance.add_op
result = op(self._val, result)
return TropicZ.TropicElement(self.__outer_instance, result)
def __add__(self, val):
return self.add(val)
def __iadd__(self, val):
self._val = self.add(val)._val
return self
def __neg__(self):
result = self.bound(-self._val)
return TropicZ.TropicElement(self.__outer_instance, result)
def mult(self, val):
'''
Тропическое умножение текущего элемента на val
'''
if isinstance(val, TropicZ.TropicElement):
result = val._val
else:
result = int(val)
result = self._val + result
return TropicZ.TropicElement(self.__outer_instance, result)
def __mul__(self, val):
return self.mult(val)
def __imul__(self, val):
self._val = self.mult(val)._val
return self
def div(self, val):
'''
Тропическое деление текущего элемента на val
'''
if isinstance(val, TropicZ.TropicElement):
result = val._val
else:
result = int(val)
result = self._val - result
return TropicZ.TropicElement(self.__outer_instance, result)
def __truediv__(self, val):
return self.div(val)
def __floordiv__(self, val):
return self.div(val)
TZ = TropicZ(1000, 'max')
TZmin = TropicZ(1000, 'min')
TZmax = TropicZ(1000, 'max')
a = TZ.elem(5)
b = TZ.elem(6)
stroka = TropicZ.TropicElement.__repr__(a)
print(stroka)
print(int(stroka)+5)
print(-a)
print(a * b)
print(a + b)
L = [TZ.elem(i) for i in range(7)]
print(L)
print(sum(L, TZ.neginf))
print(a * TZ.neginf)
import math
class TropicalMatrix:
def __init__(self, entries):
self.entries = entries
def __str__(self):
return str(self.entries)
def get_entry(self, i, j):
return self.entries[i][j]
def dual(self, dual):
n = 2
new_matrix = [[0, 0], [0, 0]]
for i in range(n):
for j in range(n):
new_matrix[i][j] = dual.elem(self[i][j])
return TropicalMatrix(new_matrix)
def add_tropical_matrix(self, matrix, dual):
n = 2
new_matrix = [[0, 0], [0, 0]]
self = TropicalMatrix.dual(self, dual)
matrix = TropicalMatrix.dual(matrix, dual)
for i in range(n):
for j in range(n):
new_matrix[i][j] = self.get_entry(i, j) + matrix.get_entry(i, j)
return TropicalMatrix(new_matrix)
def mult_scalar(self, scalar, dual):
n = 2
new_matrix = [[0, 0], [0, 0]]
self = TropicalMatrix.dual(self, dual)
for i in range(n):
for j in range(n):
new_matrix[i][j] = self.get_entry(i, j) * scalar
return TropicalMatrix(new_matrix)
def mult_tropical_matrix(self, matrix, dual):
n = 2
new_matrix = [[0, 0], [0, 0]]
self = TropicalMatrix.dual(self, dual)
matrix = TropicalMatrix.dual(matrix, dual)
for i in range(n):
for j in range(n):
sum_list = []
for k in range(n):
sum_list.append(self.get_entry(i, k) * matrix.get_entry(k, j))
new_matrix[i][j] = sum_list[0] + sum_list[1]
return TropicalMatrix(new_matrix)
def get_dimension(self):
return len(self.entries)
def __iter__(self): # метод для превращения тропической матрицы в список
return self.entries.__iter__()
if __name__ == "__main__":
M = [[-1000, 10], [5, 3]]
N = [[3, 6], [15, 1000]]
A = [[5, -1000], [-1000, 5]]
B = [[2, -1000], [-1000, 2]]
p = TropicalMatrix.add_tropical_matrix(M, A, TZmax)
t = TropicalMatrix.mult_tropical_matrix(N, N, TZmin)
q = TropicalMatrix.add_tropical_matrix(M, B, TZmax)
r = TropicalMatrix.mult_scalar(N, 3, TZmin)
print('p(x) =', p)
print('t(x) =', t)
print('q(x) =', q)
print('r(x) =', r)
import math
import random
import numpy as np
class TropicalMatrix_without_dual:
def __init__(self, entries):
self.entries = entries
def __str__(self):
return str(self.entries)
def add_tropical_matrix_without_dual(self, matrix):
n = 2
new_matrix = [[0, 0], [0, 0]]
for i in range(n):
for j in range(n):
new_matrix[i][j] = self.get_entry(i, j) + matrix.get_entry(i, j)
return TropicalMatrix_without_dual(new_matrix)
def mult_tropical_matrix_without_dual(self, matrix):
n = 2
new_matrix = [[0, 0], [0, 0]]
for i in range(n):
for j in range(n):
sum_list = []
for k in range(n):
sum_list.append(self.get_entry(i, k) * matrix.get_entry(k, j))
new_matrix[i][j] = sum_list[0] + sum_list[1]
return TropicalMatrix(new_matrix)
def get_entry(self, i, j):
return self.entries[i][j]
def __iter__(self): # метод для превращения тропической матрицы в список
return self.entries.__iter__()
if __name__ == "__main__":
M = TropicalMatrix.dual([[-1000, 10], [5, 3]], TZmax)
N = TropicalMatrix.dual([[3, 6], [15, 1000]], TZmin)
l = TropicalMatrix_without_dual.add_tropical_matrix_without_dual(M, N)
m = TropicalMatrix_without_dual.mult_tropical_matrix_without_dual(M, N)
print(m)
def convert(matrix):
s = list(matrix)
for i in range(2):
for j in range(2):
s[i][j] = int(TropicZ.TropicElement.__repr__(s[i][j]))
return s
def generate_random_matrix(n, min_elem, max_elem):
new_matrix = [[0, 0], [0, 0]]
for i in range(n):
for j in range(n):
new_matrix[i][j] = random.randint(min_elem, max_elem)
return new_matrix
def generate_random_tropical_poly(max_degree, min_coefficient, max_coefficient):
"""
Генерирует случайный (не константу) тропический многочлен с точностью до заданной степени.
"""
coefficients = []
for d in range(0, random.randint(1, max_degree) + 1):
coefficients.append(random.randint(min_coefficient, max_coefficient))
return coefficients
def MatrixMul(a, n):
if (n <= 1):
return a
else:
return TropicalMatrix_without_dual.mult_tropical_matrix_without_dual(MatrixMul(a, n-1), a)
def evaluate_polynomial(tropical_matrix, coefficient_list, dual):
"""
Вычисляет многочлен (списком), заданный тропической матрицей.
"""
identity_matrix_Zmax = [[0, -1000], [-1000, 0]]
identity_matrix_Zmin = [[0, 1000], [1000, 0]]
null_matrix_Zmax = [[-1000, -1000], [-1000, -1000]]
null_matrix_Zmin = [[1000, 1000], [1000, 1000]]
sum_list = []
# свободный член
if coefficient_list[0] != 0:
if dual == TZmin:
sum_list.append(TropicalMatrix.mult_scalar(identity_matrix_Zmin, coefficient_list[0], dual))
else:
sum_list.append(TropicalMatrix.mult_scalar(identity_matrix_Zmax, coefficient_list[0], dual))
if coefficient_list[0] == 0:
if dual == TZmin:
sum_list.append(TropicalMatrix.dual(null_matrix_Zmin, dual))
else:
sum_list.append(TropicalMatrix.dual(null_matrix_Zmax, dual))
# для многочлена первой степени
if (coefficient_list[1] != 0) and (coefficient_list[1] != 1):
sum_list.append(TropicalMatrix.mult_scalar(tropical_matrix, coefficient_list[1], dual))
if coefficient_list[1] == 1:
sum_list.append(TropicalMatrix.dual(tropical_matrix, dual))
if coefficient_list[1] == 0:
if dual == TZmin:
sum_list.append(TropicalMatrix.dual(null_matrix_Zmin, dual))
else:
sum_list.append(TropicalMatrix.dual(null_matrix_Zmax, dual))
# для многочлена второй степени и выше
for i in range(2, len(coefficient_list)):
sum_list.append(TropicalMatrix.dual(tropical_matrix, dual))
sum_list[i] = MatrixMul(sum_list[i], i)
if (coefficient_list[i] != 1) and (coefficient_list[i] != 0):
sum_list[i] = TropicalMatrix.mult_scalar(convert(sum_list[i]), coefficient_list[i], dual)
if coefficient_list[i] == 0:
if dual == TZmin:
sum_list.append(TropicalMatrix.dual(null_matrix_Zmin, dual))
else:
sum_list.append(TropicalMatrix.dual(null_matrix_Zmax, dual))
new_matrix = sum_list[0] # складываем все матрицы в sum_list
for matrix in sum_list:
new_matrix = TropicalMatrix_without_dual.add_tropical_matrix_without_dual(new_matrix, matrix)
return TropicalMatrix(new_matrix)
def get_polynomial_representation(coefficient_list):
term_list = [str(coefficient_list[0])]
for i in range(1, len(coefficient_list)):
term_list.append(str(coefficient_list[i]) + "x^" + str(i))
return " + ".join(term_list)
def generate_key(public_term, public_matrix_a, public_matrix_b):
left_term = TropicalMatrix.mult_tropical_matrix(public_matrix_a, public_term, TZmax)
right_term = TropicalMatrix.mult_tropical_matrix(convert(left_term), public_matrix_b, TZmin)
return right_term
if __name__ == "__main__":
p_x = [5, 1]
t_x = [0, 0, 1]
q_x = [2, 1]
r_x = [0, 3]
X = [[1, 2], [6, 10]]
M = [[-1000, 10], [5, 3]]
N = [[3, 6], [15, 1000]]
p_M = convert(evaluate_polynomial(M, p_x, TZmax))
t_N = convert(evaluate_polynomial(N, t_x, TZmin))
q_M = convert(evaluate_polynomial(M, q_x, TZmax))
r_N = convert(evaluate_polynomial(N, r_x, TZmin))
print('p(x) =', p_M)
print('t(x) =', t_N)
print('q(x) =', q_M)
print('r(x) =', r_N)
Alica = TropicalMatrix.mult_tropical_matrix(p_M, X, TZmax)
alice_public_key = TropicalMatrix.mult_tropical_matrix(convert(Alica), t_N, TZmin)
print('Открытый ключ Алисы: ', alice_public_key)
Bob = TropicalMatrix.mult_tropical_matrix(q_M, X, TZmax)
bob_public_key = TropicalMatrix.mult_tropical_matrix(convert(Bob), r_N, TZmin)
print('Открытый ключ Боба: ', bob_public_key)
print('Секретный ключ Алисы: ', generate_key(convert(bob_public_key), p_M, t_N))
print('Секретный ключ Боба: ', generate_key(convert(alice_public_key), q_M, r_N))
import random
def pprint_matrix(matrix):
print('\n'.join([' '.join([str(cell) for cell in row]) for row in matrix.entries]))
if __name__ == "__main__":
matrix_size = 2
min_matrix_term = -15
max_matrix_term = 15
min_polynomial_coefficient = -10
max_polynomial_coefficient = 10
max_polynomial_degree = 5
print('Генерация многочленов')
print("Секретные многочлены Алисы: ")
p_x = generate_random_tropical_poly(max_polynomial_degree, min_polynomial_coefficient, max_polynomial_coefficient)
t_x = generate_random_tropical_poly(max_polynomial_degree, min_polynomial_coefficient, max_polynomial_coefficient)
print('p(x) =', get_polynomial_representation(p_x))
print('t(x) =', get_polynomial_representation(t_x))
print('Секретные многочлены Боба: ')
q_x = generate_random_tropical_poly(max_polynomial_degree, min_polynomial_coefficient, max_polynomial_coefficient)
r_x = generate_random_tropical_poly(max_polynomial_degree, min_polynomial_coefficient, max_polynomial_coefficient)
print('q(x) =', get_polynomial_representation(q_x))
print('r(x) =', get_polynomial_representation(r_x))
print('Открытая матрица Алисы: ')
#M = generate_random_matrix(matrix_size, min_matrix_term, max_matrix_term)
M = [[68, 1000],[-1000, 11]]
print('M = ', M)
print('Открытая матрица Боба: ')
#N = generate_random_matrix(matrix_size, min_matrix_term, max_matrix_term)
N = [[15, 122],[78, 12]]
print('N = ', N)
X_matrix = generate_random_matrix(matrix_size, min_matrix_term, max_matrix_term)
print('Матрица X: ', X_matrix)
print('Алиса отправляет Бобу следующую матрицу')
p_M = convert(evaluate_polynomial(M, p_x, TZmax))
t_N = convert(evaluate_polynomial(N, t_x, TZmin))
Alica = TropicalMatrix.mult_tropical_matrix(p_M, X, TZmax)
alice_public_key = TropicalMatrix.mult_tropical_matrix(convert(Alica), t_N, TZmin)
print('Открытый ключ Алисы: ')
pprint_matrix(alice_public_key)
print('Боб отправляет Алисе следующую матрицу')
q_M = convert(evaluate_polynomial(M, q_x, TZmax))
r_N = convert(evaluate_polynomial(N, r_x, TZmin))
Bob = TropicalMatrix.mult_tropical_matrix(q_M, X, TZmax)
bob_public_key = TropicalMatrix.mult_tropical_matrix(convert(Bob), r_N, TZmin)
print('Открытый ключ Боба: ')
pprint_matrix(bob_public_key)
print('Алиса и Боб вычисляют секретные ключи')
print('Секретный ключ Алисы: ')
alice_key = generate_key(convert(bob_public_key), p_M, t_N)
pprint_matrix(alice_key)
print('Секретный ключ Боба: ')
bob_key = generate_key(convert(alice_public_key), q_M, r_N)
pprint_matrix(bob_key)