import tkinter as tk from tkinter import ttk import numpy as np from multiprocessing import cpu_count, Pool import time class DeterminantCalculator: def __init__(self, root): self.root = root self.root.title("Determinant Calculator") self.matrix_size_label = ttk.Label(root, text="Matrix Size:") self.matrix_size_label.grid(row=0, column=0, padx=10, pady=10) self.matrix_size_entry = ttk.Entry(root) self.matrix_size_entry.grid(row=0, column=1, padx=10, pady=10) self.algorithm_label = ttk.Label(root, text="Algorithm:") self.algorithm_label.grid(row=1, column=0, padx=10, pady=10) self.algorithm_var = tk.StringVar() self.algorithm_var.set("Normal") self.algorithm_menu = ttk.Combobox(root, textvariable=self.algorithm_var, values=["Normal", "Parallel"]) self.algorithm_menu.grid(row=1, column=1, padx=10, pady=10) self.num_threads_label = ttk.Label(root, text="Number of Threads:") self.num_threads_label.grid(row=2, column=0, padx=10, pady=10) self.num_threads_entry = ttk.Entry(root) self.num_threads_entry.insert(0, str(cpu_count())) self.num_threads_entry.grid(row=2, column=1, padx=10, pady=10) self.generate_and_calculate_button = ttk.Button(root, text="Generate Matrix and Calculate Determinant", command=self.generate_and_calculate_determinant) self.generate_and_calculate_button.grid(row=3, column=0, columnspan=2, pady=10) self.result_label = ttk.Label(root, text="Result:") self.result_label.grid(row=4, column=0, padx=10, pady=10) self.time_label = ttk.Label(root, text="Time (s):") self.time_label.grid(row=5, column=0, padx=10, pady=10) self.matrix_label = ttk.Label(root, text="") self.matrix_label.grid(row=6, column=0, columnspan=2, pady=10) self.det_result = None # Глобальная переменная для хранения результата def generate_matrix(self, size): matrix = np.random.randint(1, 10, size=(size, size)) return matrix def show_random_matrix(self, matrix): self.matrix_label.config(text=f"Random Matrix:\n{matrix}") def calculate_determinant_parallel(self, matrix, num_threads): size = len(matrix) if size == 1: return matrix[0, 0], 0 result = RawArray('d', [0.0]) # Разделяемый массив для хранения результата lock_object = np.ones(1) # Использование numpy для создания объекта блокировки def calculate_submatrix(i): nonlocal result sub_matrix = self.get_submatrix(matrix, i) sub_determinant = matrix[0, i] * self.calculate_determinant(sub_matrix) with lock_object.get_lock(): result[0] += (-1) ** i * sub_determinant with Pool(processes=num_threads) as pool: start_time = time.time() pool.map(calculate_submatrix, range(size)) end_time = time.time() return result[0], end_time - start_time # ваш существующий код def get_submatrix(self, matrix, column_index): size = len(matrix) sub_matrix = np.zeros((size - 1, size - 1)) for i in range(1, size): for j in range(size): if j < column_index: sub_matrix[i - 1, j] = matrix[i, j] elif j > column_index: sub_matrix[i - 1, j - 1] = matrix[i, j] return sub_matrix def calculate_determinant_group(self, matrix, row, col): sign = (-1) ** (row + col) minor = np.delete(np.delete(np.array(matrix), row, axis=0), col, axis=1) det_minor = self.calculate_determinant(minor) return sign * matrix[row][col] * det_minor def calculate_determinant(self, matrix=None): if matrix is None: matrix_size = int(self.matrix_size_entry.get()) matrix = self.generate_matrix(matrix_size) size = len(matrix) if size == 1: return matrix[0][0] elif size == 2: return matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0] else: det = 0 for col in range(size): sign = (-1) ** col minor = np.delete(np.array(matrix), 0, axis=0) minor = np.delete(minor, col, axis=1) det += sign * matrix[0][col] * self.calculate_determinant(minor) return det def generate_and_calculate_determinant(self): matrix_size = int(self.matrix_size_entry.get()) algorithm = self.algorithm_var.get() num_threads = int(self.num_threads_entry.get()) random_matrix = self.generate_matrix(matrix_size) self.show_random_matrix(random_matrix) if algorithm == "Parallel": det, time_taken = self.calculate_determinant_parallel(random_matrix, num_threads) else: start_time = time.time() det = self.calculate_determinant(random_matrix) time_taken = time.time() - start_time result_str = f"Determinant: {det}" self.result_label.config(text=result_str) time_str = f"Time (s): {time_taken:.6f}" self.time_label.config(text=time_str) # Используем глобальную переменную для отображения результата в методе generate_and_calculate_determinant self.det_result = det if __name__ == "__main__": root = tk.Tk() app = DeterminantCalculator(root) root.mainloop()