From 8ef719726882bcabe93edef7731a43f8d6c872e4 Mon Sep 17 00:00:00 2001 From: maxnes3 Date: Sat, 14 Dec 2024 01:03:28 +0400 Subject: [PATCH] bondarenko_max_lab_6_is_ready --- bondarenko_max_lab_6/README.md | 34 ++++++++++++ bondarenko_max_lab_6/benchmark.js | 37 +++++++++++++ bondarenko_max_lab_6/benchmark.png | Bin 0 -> 63366 bytes bondarenko_max_lab_6/det.worker.js | 8 +++ bondarenko_max_lab_6/matrix.operations.js | 60 ++++++++++++++++++++++ 5 files changed, 139 insertions(+) create mode 100644 bondarenko_max_lab_6/README.md create mode 100644 bondarenko_max_lab_6/benchmark.js create mode 100644 bondarenko_max_lab_6/benchmark.png create mode 100644 bondarenko_max_lab_6/det.worker.js create mode 100644 bondarenko_max_lab_6/matrix.operations.js diff --git a/bondarenko_max_lab_6/README.md b/bondarenko_max_lab_6/README.md new file mode 100644 index 0000000..f71aea3 --- /dev/null +++ b/bondarenko_max_lab_6/README.md @@ -0,0 +1,34 @@ +# Лабораторная работа 6 - Определение детерминанта матрицы с помощью параллельных вычислений +### ПИбд-42 || Бондаренко Максим + +# Описание работы + +## Задание +> [!NOTE] +> Кратко: реализовать нахождение детерминанта квадратной матрицы. +> +> Подробно: в лабораторной работе требуется сделать два алгоритма: обычный и параллельный (задание со * - реализовать это в рамках одного алгоритма). В параллельном алгоритме предусмотреть ручное задание количества потоков (число потоков = 1 как раз и реализует задание со *), каждый из которых будет выполнять нахождение отдельной группы множителей. + +## Краткое описание модулей и их работа +1. matrix.operations.js +- getMinor(matrix, row, col): Получает минор матрицы для заданной строки и столбца. +- determinant(matrix): Вычисляет детерминант матрицы рекурсивно (последовательный алгоритм). +- determinantParallel(matrix, numThreads): Вычисляет детерминант матрицы параллельно, распределяя задачи по заданному количеству потоков. + +2. det.worker.js +- Получает данные о своей части работы (миноры и знаки) и вычисляет частичный детерминант, который затем отправляет обратно главному потоку. + +3. benchmark.js +- generateMatrix(size): Генерирует случайную квадратную матрицу заданного размера. +- benchmark(): Выполняет бенчмарки для матриц различных размеров, сравнивая время выполнения последовательного и параллельного алгоритмов с различным количеством потоков. + +## Запуск +``` +node benchmark.js +``` + +## Результат работы +> [!IMPORTANT] +> ![benchmark.png](./benchmark.png) + +Ссылка на видео: https://cloud.mail.ru/public/9Bky/mjwK7bqBL \ No newline at end of file diff --git a/bondarenko_max_lab_6/benchmark.js b/bondarenko_max_lab_6/benchmark.js new file mode 100644 index 0000000..a9baf34 --- /dev/null +++ b/bondarenko_max_lab_6/benchmark.js @@ -0,0 +1,37 @@ +const { determinant, determinantParallel } = require('./matrix.operations'); + +function generateMatrix(size) { + const matrix = new Array(size); + for (let i = 0; i < size; i++) { + matrix[i] = new Array(size); + for (let j = 0; j < size; j++) { + matrix[i][j] = Math.floor(Math.random() * 20) - 10; + } + } + return matrix; +} + +async function benchmark() { + const sizes = [5, 7, 10]; + const numThreads = [2, 4, 8]; + + for (const size of sizes) { + const matrix = generateMatrix(size); + + console.log(`\nМатрица (${size}x${size}):`); + + console.time('Последовательно'); + const detSeq = determinant(matrix); + console.timeEnd('Последовательно'); + console.log(`Детерминант: ${detSeq}`); + + for (const threads of numThreads) { + console.time(`Параллельно (${threads} потоков)`); + const detPar = await determinantParallel(matrix, threads); + console.timeEnd(`Параллельно (${threads} потоков)`); + console.log(`Детерминант: ${detPar}`); + } + } +} + +benchmark(); diff --git a/bondarenko_max_lab_6/benchmark.png b/bondarenko_max_lab_6/benchmark.png new file mode 100644 index 0000000000000000000000000000000000000000..86ab7f66441df813a81296ef351904f1512dc948 GIT binary patch literal 63366 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 { + return acc + job.value * determinant(job.minor) * job.sign; +}, 0); + +parentPort.postMessage(partialDet); diff --git a/bondarenko_max_lab_6/matrix.operations.js b/bondarenko_max_lab_6/matrix.operations.js new file mode 100644 index 0000000..87591c7 --- /dev/null +++ b/bondarenko_max_lab_6/matrix.operations.js @@ -0,0 +1,60 @@ +const { Worker, isMainThread, parentPort, workerData } = require('worker_threads'); + +function getMinor(matrix, row, col) { + return matrix + .filter((_, i) => i !== row) + .map(row => row.filter((_, j) => j !== col)); +} + +function determinant(matrix) { + const n = matrix.length; + if (n === 1) return matrix[0][0]; + if (n === 2) return matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0]; + + let det = 0; + for (let j = 0; j < n; j++) { + det += matrix[0][j] * determinant(getMinor(matrix, 0, j)) * (j % 2 === 0 ? 1 : -1); + } + return det; +} + +function determinantParallel(matrix, numThreads) { + return new Promise((resolve, reject) => { + const n = matrix.length; + if (n === 1) return resolve(matrix[0][0]); + if (n === 2) return resolve(matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0]); + + let det = 0; + let completed = 0; + const jobs = []; + + for (let j = 0; j < n; j++) { + const sign = j % 2 === 0 ? 1 : -1; + const minor = getMinor(matrix, 0, j); + jobs.push({ minor, sign, value: matrix[0][j] }); + } + + const chunkSize = Math.ceil(jobs.length / numThreads); + const results = Array(numThreads).fill(0); + + for (let i = 0; i < numThreads; i++) { + const chunk = jobs.slice(i * chunkSize, (i + 1) * chunkSize); + const worker = new Worker('./det.worker.js', { workerData: chunk }); + + worker.on('message', (partialDet) => { + results[i] = partialDet; + completed++; + if (completed === numThreads) { + resolve(results.reduce((acc, val) => acc + val, 0)); + } + }); + + worker.on('error', reject); + worker.on('exit', (code) => { + if (code !== 0) reject(new Error(`Worker stopped with exit code ${code}`)); + }); + } + }); +} + +module.exports = { determinant, determinantParallel };