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) }