DAS_2023_1/senkin_alexander_lab_6/main/main.go

124 lines
3.7 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package main
import (
"fmt"
"math/rand"
"sync"
"time"
)
// SequentialDeterminant рассчитывает детерминант матрицы методом разложения по первой строке
func SequentialDeterminant(matrix [][]float64) float64 {
size := len(matrix)
// Базовый случай: если матрица 1x1, то детерминант равен единственному элементу
if size == 1 {
return matrix[0][0]
}
// Рекурсивно вычисляем детерминант матрицы
det := 0.0
sign := 1.0
for j := 0; j < size; j++ {
// Разложение по первой строке
submatrix := make([][]float64, size-1)
for i := range submatrix {
submatrix[i] = make([]float64, size-1)
}
for i := 1; i < size; i++ {
for k := 0; k < size; k++ {
if k < j {
submatrix[i-1][k] = matrix[i][k]
} else if k > j {
submatrix[i-1][k-1] = matrix[i][k]
}
}
}
// Рекурсивный вызов для подматрицы
det += sign * matrix[0][j] * SequentialDeterminant(submatrix)
// Меняем знак для следующей итерации
sign *= -1
}
return det
}
// ParallelDeterminant рассчитывает детерминант матрицы параллельно с использованием горутин
func ParallelDeterminant(matrix [][]float64, numWorkers int) float64 {
size := len(matrix)
// Базовый случай: если матрица 1x1, то детерминант равен единственному элементу
if size == 1 {
return matrix[0][0]
}
var wg sync.WaitGroup
resultChan := make(chan float64, numWorkers)
// Распределение работы между горутинами
for j := 0; j < size; j++ {
wg.Add(1)
go func(col int) {
defer wg.Done()
// Разложение по первой строке
submatrix := make([][]float64, size-1)
for i := range submatrix {
submatrix[i] = make([]float64, size-1)
}
for i := 1; i < size; i++ {
for k := 0; k < size; k++ {
if k < col {
submatrix[i-1][k] = matrix[i][k]
} else if k > col {
submatrix[i-1][k-1] = matrix[i][k]
}
}
}
// Рекурсивный вызов для подматрицы и отправка результата в канал
resultChan <- matrix[0][col] * ParallelDeterminant(submatrix, numWorkers)
}(j)
}
// Закрываем канал после завершения всех горутин
go func() {
wg.Wait()
close(resultChan)
}()
// Сбор результатов из канала и вычисление итогового детерминанта
det := 0.0
sign := 1.0
for result := range resultChan {
det += sign * result
sign *= -1
}
return det
}
func runTest(matrixSize, numProcesses int) {
matrix := generateRandomMatrix(matrixSize, matrixSize)
startTime := time.Now()
_ = SequentialDeterminant(matrix)
sequentialTime := time.Since(startTime)
fmt.Printf("Sequential matrix Determinant took (%dx%d): %s\n", matrixSize, matrixSize, sequentialTime)
startTime = time.Now()
_ = ParallelDeterminant(matrix, numProcesses)
parallelTime := time.Since(startTime)
fmt.Printf("Parallel matrix Determinant with %d threads took (%dx%d): %s\n", numProcesses, matrixSize, matrixSize, parallelTime)
}
func generateRandomMatrix(rows, cols int) [][]float64 {
matrix := make([][]float64, rows)
for i := range matrix {
matrix[i] = make([]float64, cols)
for j := range matrix[i] {
matrix[i][j] = rand.Float64()
}
}
return matrix
}
func main() {
// Пример использования функций
runTest(6, 2)
runTest(6, 4)
runTest(8, 2)
runTest(8, 4)
runTest(10, 2)
runTest(10, 4)
}