forked from sevastyan_b/SSPR_25
gorskov_evgeniu_lab_3 ready
This commit is contained in:
29
gorskov_evgeniu_lab_1/LabWork01/.gitignore
vendored
29
gorskov_evgeniu_lab_1/LabWork01/.gitignore
vendored
@@ -1,29 +0,0 @@
|
|||||||
### IntelliJ IDEA ###
|
|
||||||
out/
|
|
||||||
!**/src/main/**/out/
|
|
||||||
!**/src/test/**/out/
|
|
||||||
|
|
||||||
### Eclipse ###
|
|
||||||
.apt_generated
|
|
||||||
.classpath
|
|
||||||
.factorypath
|
|
||||||
.project
|
|
||||||
.settings
|
|
||||||
.springBeans
|
|
||||||
.sts4-cache
|
|
||||||
bin/
|
|
||||||
!**/src/main/**/bin/
|
|
||||||
!**/src/test/**/bin/
|
|
||||||
|
|
||||||
### NetBeans ###
|
|
||||||
/nbproject/private/
|
|
||||||
/nbbuild/
|
|
||||||
/dist/
|
|
||||||
/nbdist/
|
|
||||||
/.nb-gradle/
|
|
||||||
|
|
||||||
### VS Code ###
|
|
||||||
.vscode/
|
|
||||||
|
|
||||||
### Mac OS ###
|
|
||||||
.DS_Store
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
package sspr1;
|
|
||||||
|
|
||||||
import java.util.concurrent.ForkJoinPool;
|
|
||||||
import java.util.concurrent.RecursiveTask;
|
|
||||||
|
|
||||||
public class ForkJoinMaxFinder {
|
|
||||||
private static class MaxFinderTask extends RecursiveTask<Integer> {
|
|
||||||
private final int[][] matrix;
|
|
||||||
private final int startRow;
|
|
||||||
private final int endRow;
|
|
||||||
|
|
||||||
public MaxFinderTask(int[][] matrix, int startRow, int endRow) {
|
|
||||||
this.matrix = matrix;
|
|
||||||
this.startRow = startRow;
|
|
||||||
this.endRow = endRow;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Integer compute() {
|
|
||||||
if (endRow - startRow <= 1) {
|
|
||||||
int max = Integer.MIN_VALUE;
|
|
||||||
for (int j = startRow + 1; j < matrix.length; j++) {
|
|
||||||
if (matrix[startRow][j] > max) {
|
|
||||||
max = matrix[startRow][j];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return max;
|
|
||||||
} else {
|
|
||||||
int mid = (startRow + endRow) / 2;
|
|
||||||
MaxFinderTask leftTask = new MaxFinderTask(matrix, startRow, mid);
|
|
||||||
MaxFinderTask rightTask = new MaxFinderTask(matrix, mid, endRow);
|
|
||||||
leftTask.fork();
|
|
||||||
int rightResult = rightTask.compute();
|
|
||||||
int leftResult = leftTask.join();
|
|
||||||
return Math.max(leftResult, rightResult);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int findMax(int[][] matrix) {
|
|
||||||
ForkJoinPool pool = new ForkJoinPool();
|
|
||||||
return pool.invoke(new MaxFinderTask(matrix, 0, matrix.length));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
package sspr1;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Scanner;
|
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
|
|
||||||
public class Main {
|
|
||||||
public static void main(String[] args) throws InterruptedException, ExecutionException, IOException {
|
|
||||||
Scanner scanner = new Scanner(System.in);
|
|
||||||
System.out.print("Введите размер матрицы: ");
|
|
||||||
int size = scanner.nextInt();
|
|
||||||
scanner.close();
|
|
||||||
|
|
||||||
int[][] matrix = MatrixGeneration.generateMatrix(size);
|
|
||||||
|
|
||||||
// Запись матрицы в файл
|
|
||||||
MatrixGeneration.writeMatrixToFile(matrix, "matrix.txt");
|
|
||||||
System.out.println("Матрица записана в файл matrix.txt");
|
|
||||||
|
|
||||||
// Однопоточный алгоритм
|
|
||||||
long startTime = System.currentTimeMillis();
|
|
||||||
int singleThreadedMax = SingleThreadedMaxFinder.findMax(matrix);
|
|
||||||
long endTime = System.currentTimeMillis();
|
|
||||||
System.out.println("Single-threaded max: " + singleThreadedMax + ", Time: " + (endTime - startTime) + " ms");
|
|
||||||
|
|
||||||
// Многопоточный алгоритм с ThreadPoolExecutor
|
|
||||||
startTime = System.currentTimeMillis();
|
|
||||||
int threadPoolMax = ThreadPoolMaxFinder.findMax(matrix, Runtime.getRuntime().availableProcessors());
|
|
||||||
endTime = System.currentTimeMillis();
|
|
||||||
System.out.println("ThreadPool max: " + threadPoolMax + ", Time: " + (endTime - startTime) + " ms");
|
|
||||||
|
|
||||||
// Многопоточный алгоритм с ForkJoinPool
|
|
||||||
startTime = System.currentTimeMillis();
|
|
||||||
int forkJoinMax = ForkJoinMaxFinder.findMax(matrix);
|
|
||||||
endTime = System.currentTimeMillis();
|
|
||||||
System.out.println("ForkJoin max: " + forkJoinMax + ", Time: " + (endTime - startTime) + " ms");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
package sspr1;
|
|
||||||
|
|
||||||
import java.io.FileWriter;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
public class MatrixGeneration {
|
|
||||||
public static int[][] generateMatrix(int size) {
|
|
||||||
int[][] matrix = new int[size][size];
|
|
||||||
Random random = new Random();
|
|
||||||
for (int i = 0; i < size; i++) {
|
|
||||||
for (int j = 0; j < size; j++) {
|
|
||||||
matrix[i][j] = random.nextInt(1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return matrix;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void writeMatrixToFile(int[][] matrix, String filename) throws IOException {
|
|
||||||
try (FileWriter writer = new FileWriter(filename)) {
|
|
||||||
for (int[] row : matrix) {
|
|
||||||
for (int value : row) {
|
|
||||||
writer.write(value + " ");
|
|
||||||
}
|
|
||||||
writer.write("\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
package sspr1;
|
|
||||||
|
|
||||||
public class SingleThreadedMaxFinder {
|
|
||||||
public static int findMax(int[][] matrix) {
|
|
||||||
int max = -999999999;
|
|
||||||
int size = matrix.length;
|
|
||||||
for (int i = 0; i < size; i++) {
|
|
||||||
for (int j = i + 1; j < size; j++) {
|
|
||||||
if (matrix[i][j] > max) {
|
|
||||||
max = matrix[i][j];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return max;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
package sspr1;
|
|
||||||
|
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
import java.util.concurrent.Future;
|
|
||||||
|
|
||||||
public class ThreadPoolMaxFinder {
|
|
||||||
public static int findMax(int[][] matrix, int numThreads) throws InterruptedException, ExecutionException {
|
|
||||||
int size = matrix.length;
|
|
||||||
ExecutorService executor = Executors.newFixedThreadPool(numThreads);
|
|
||||||
Future<Integer>[] futures = new Future[size];
|
|
||||||
|
|
||||||
for (int i = 0; i < size; i++) {
|
|
||||||
final int row = i;
|
|
||||||
futures[i] = executor.submit(() -> {
|
|
||||||
int max = Integer.MIN_VALUE;
|
|
||||||
for (int j = row + 1; j < size; j++) {
|
|
||||||
if (matrix[row][j] > max) {
|
|
||||||
max = matrix[row][j];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return max;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
int globalMax = Integer.MIN_VALUE;
|
|
||||||
for (Future<Integer> future : futures) {
|
|
||||||
int localMax = future.get();
|
|
||||||
if (localMax > globalMax) {
|
|
||||||
globalMax = localMax;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
executor.shutdown();
|
|
||||||
return globalMax;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,82 +0,0 @@
|
|||||||
Лабораторная работа №1.
|
|
||||||
|
|
||||||
Разработка многопоточного приложения с использованием Java Concurrency согласно варианту задания.
|
|
||||||
|
|
||||||
Необходимо выполнить следующие задачи:
|
|
||||||
|
|
||||||
Разработать однопоточный вариант алгоритма и замерить время его работы.
|
|
||||||
Разработать параллельный вариант алгоритма с использованием ThreadPoolExecutor и замерить время его работы
|
|
||||||
Разработать параллельный вариант алгоритма с использованием ForkJoinPoll и замерить время его работы.
|
|
||||||
|
|
||||||
Вариант задания
|
|
||||||
8)Найти максимальный элемент выше главной диагонали.
|
|
||||||
|
|
||||||
Как запустить программу
|
|
||||||
Необходиом запустить башфайл, где уже прописаны необходимые настройки для запуска программы
|
|
||||||
/root/sspr1.sh
|
|
||||||
|
|
||||||
Инструменты
|
|
||||||
|
|
||||||
Язык программирования: Java
|
|
||||||
Пакеты:
|
|
||||||
java.util.concurrent — используется для реализации многопоточности через ThreadPoolExecutor и ForkJoinPool
|
|
||||||
Среда разработки: IntelliJ IDEA
|
|
||||||
Версия JDK: 21
|
|
||||||
|
|
||||||
Описание работы программы
|
|
||||||
|
|
||||||
Генерация матрицы
|
|
||||||
Программа генерирует случайную матрицу заданного размера (количество строк и столбцов передается как аргументы командной строки).
|
|
||||||
Матрица заполняется случайными целыми числами.
|
|
||||||
|
|
||||||
Однопоточный алгоритм
|
|
||||||
|
|
||||||
Алгоритм проходит по всем элементам матрицы, находящимся выше главной диагонали.
|
|
||||||
Для каждого элемента проверяется, больше ли он текущего максимума.
|
|
||||||
Время выполнения зависит от размера матрицы и выполняется последовательно.
|
|
||||||
|
|
||||||
Многопоточный алгоритм с использованием ThreadPoolExecutor
|
|
||||||
|
|
||||||
Каждая строка матрицы обрабатывается в отдельном потоке.
|
|
||||||
Используется пул потоков, где количество потоков равно количеству доступных ядер процессора.
|
|
||||||
Каждый поток находит максимум в своей строке выше главной диагонали.
|
|
||||||
После завершения всех потоков находится глобальный максимум.
|
|
||||||
|
|
||||||
Многопоточный алгоритм с использованием ForkJoinPool
|
|
||||||
|
|
||||||
Используется рекурсивное разделение задачи на подзадачи.
|
|
||||||
Матрица делится на две части, и каждая часть обрабатывается отдельно.
|
|
||||||
После завершения обработки всех частей находится глобальный максимум.
|
|
||||||
Подходит для больших матриц, так как эффективно использует многопоточность.
|
|
||||||
|
|
||||||
Замер времени
|
|
||||||
|
|
||||||
Для каждого алгоритма замеряется время выполнения.
|
|
||||||
Результаты выводятся на экран.
|
|
||||||
|
|
||||||
Результаты работы на матрице 10000 × 10000
|
|
||||||
|
|
||||||
Тест Однопоточный алгоритм ThreadPoolExecutor ForkJoinPool
|
|
||||||
Тест №1 1615 мс 740 мс 1040 мс
|
|
||||||
Тест №2 1789 мс 743 мс 1020 мс
|
|
||||||
Тест №3 1613 мс 696 мс 1068 мс
|
|
||||||
|
|
||||||
Результаты работы на матрице 5000 × 5000
|
|
||||||
|
|
||||||
Тест Однопоточный алгоритм ThreadPoolExecutor ForkJoinPool
|
|
||||||
Тест №1 420 мс 210 мс 280 мс
|
|
||||||
Тест №2 435 мс 205 мс 275 мс
|
|
||||||
Тест №3 410 мс 215 мс 290 мс
|
|
||||||
|
|
||||||
Результаты работы на матрице 2000 × 2000
|
|
||||||
|
|
||||||
Тест Однопоточный алгоритм ThreadPoolExecutor ForkJoinPool
|
|
||||||
Тест №1 65 мс 35 мс 45 мс
|
|
||||||
Тест №2 68 мс 34 мс 46 мс
|
|
||||||
Тест №3 67 мс 36 мс 44 мс
|
|
||||||
|
|
||||||
Вывод
|
|
||||||
|
|
||||||
Для небольших матриц (например, 100 × 100) разница во времени выполнения может быть незначительной.
|
|
||||||
Для больших матриц (например, 10000 × 10000) многопоточные подходы (ThreadPoolExecutor и ForkJoinPool) значительно ускоряют выполнение.
|
|
||||||
Выбор между ThreadPoolExecutor и ForkJoinPool зависит от специфики задачи. Если задача легко делится на независимые части, лучше использовать ThreadPoolExecutor. Если задача требует рекурсивного разделения, подойдет ForkJoinPool.
|
|
||||||
240
gorskov_evgeniu_lab_3/readme.md
Normal file
240
gorskov_evgeniu_lab_3/readme.md
Normal file
@@ -0,0 +1,240 @@
|
|||||||
|
Лабораторная работа №3
|
||||||
|
|
||||||
|
Разработка распределенного приложения с использованием фреймворка Spring Boot
|
||||||
|
|
||||||
|
Действия по варианту должны производиться в LXC контейнерах. Необходимо разработать параллельный вариант алгоритма с применением сервис - ориентированного подхода и фреймворка Spring Boot, замерить время его работы
|
||||||
|
|
||||||
|
Вариант задания:
|
||||||
|
|
||||||
|
8)Найти максимальный элемент выше главной диагонали
|
||||||
|
|
||||||
|
Как запустить программу:
|
||||||
|
|
||||||
|
Необходимо запустить bash-файлы в обоих контейнерах, где уже прописаны необходимые настройки для запуска программы:
|
||||||
|
/root/sspr3.sh
|
||||||
|
После этого в командной строке прописать данную команду:
|
||||||
|
curl -X POST "http://localhost:8080/api/matrix/findMaxAboveDiagonal?size=5"
|
||||||
|
|
||||||
|
В неё мы передаём порт, который слушаем и название запускаемого файла, указываем размер нашей матрицы, которую будем создавать(size)
|
||||||
|
|
||||||
|
Инструменты:
|
||||||
|
|
||||||
|
Пакеты:
|
||||||
|
java.util.concurrent — для реализации многопоточности
|
||||||
|
org.springframework.web.client.RestTemplate — для взаимодействия с удалённым сервисом
|
||||||
|
|
||||||
|
Язык программирования: Java
|
||||||
|
фреймворка Spring Boot
|
||||||
|
Среда разработки: IntelliJ IDEA
|
||||||
|
Версия JDK: 11
|
||||||
|
|
||||||
|
Описание работы программы:
|
||||||
|
|
||||||
|
Метод generateMatrix в классе MatrixUtils создаёт квадратную матрицу заданного размера, заполненную случайными числами
|
||||||
|
|
||||||
|
public double[][] generateMatrix(int rows, int cols) {
|
||||||
|
Random rand = new Random();
|
||||||
|
double[][] matrix = new double[rows][cols];
|
||||||
|
for (int i = 0; i < rows; i++) {
|
||||||
|
for (int j = 0; j < cols; j++) {
|
||||||
|
matrix[i][j] = Math.round((rand.nextDouble() * 100) * 100.0) / 100.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return matrix;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Метод findMaxAboveDiagonal в классе MatrixUtils выполняет поиск максимального элемента выше главной диагонали(Однопоточный алгоритм)
|
||||||
|
|
||||||
|
public double findMaxAboveDiagonal(double[][] matrix) {
|
||||||
|
double max = Double.NEGATIVE_INFINITY;
|
||||||
|
for (int i = 0; i < matrix.length; i++) {
|
||||||
|
for (int j = i + 1; j < matrix[i].length; j++) {
|
||||||
|
max = Math.max(max, matrix[i][j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
|
||||||
|
Метод findMaxAboveDiagonal в классе MatrixService разделяет матрицу на две части(Многопоточный алгоритм):
|
||||||
|
|
||||||
|
Верхняя половина отправляется в удалённый сервис для обработки
|
||||||
|
Нижняя половина обрабатывается локально
|
||||||
|
|
||||||
|
public ProcessingResult findMaxAboveDiagonal(int size) {
|
||||||
|
double[][] matrix = matrixUtils.generateMatrix(size, size);
|
||||||
|
log.info("Matrix generated");
|
||||||
|
matrixUtils.saveToFile(matrix, "/root/sspr3/src/main/resources/matrix.txt");
|
||||||
|
log.info("Matrix saved to file /root/sspr3/src/main/resources/matrix.txt");
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
|
|
||||||
|
// Разделяем верхнюю часть на две области
|
||||||
|
double[][] topHalf = matrixUtils.extractTopHalfAboveDiagonal(matrix);
|
||||||
|
double[][] bottomHalf = matrixUtils.extractBottomHalfAboveDiagonal(matrix);
|
||||||
|
|
||||||
|
// Отправляем верхнюю часть во второй контейнер
|
||||||
|
ResponseEntity<Double> response = restTemplate.postForEntity(
|
||||||
|
"http://second-container:8081/api/matrix/findMax",
|
||||||
|
new MatrixData(topHalf),
|
||||||
|
Double.class
|
||||||
|
);
|
||||||
|
log.info("Send the matrix first cont");
|
||||||
|
|
||||||
|
// Локальный максимум в нижней части
|
||||||
|
double localMax = matrixUtils.findMaxAboveDiagonal(bottomHalf);
|
||||||
|
|
||||||
|
// Получаем максимум от второго контейнера
|
||||||
|
double remoteMax = response.getBody();
|
||||||
|
log.info("Get the matrix to second container");
|
||||||
|
// Вычисляем финальный максимум
|
||||||
|
double finalMax = Math.max(localMax, remoteMax);
|
||||||
|
long totalTime = System.currentTimeMillis() - startTime;
|
||||||
|
|
||||||
|
return new ProcessingResult(finalMax, totalTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Класс FindMaxController принимает запросы на поиск максимального элемента в матрице
|
||||||
|
|
||||||
|
@PostMapping("/findMax")
|
||||||
|
public ResponseEntity<Double> findMax(@RequestBody MatrixData requestData) {
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
|
double max = findMaxService.findMaxAboveDiagonal(requestData.getMatrix());
|
||||||
|
log.info("Second cont finish the process matrix");
|
||||||
|
long totalTime = System.currentTimeMillis() - startTime;
|
||||||
|
return ResponseEntity.ok(max);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Класс для передачи матрицы между компонентами системы
|
||||||
|
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class MatrixData {
|
||||||
|
private double[][] matrix;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Класс MatrixUtils
|
||||||
|
Утилиты для работы с матрицами: генерация, поиск максимума, разделение и сохранение в файл.
|
||||||
|
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.io.BufferedWriter;
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class MatrixUtils {
|
||||||
|
|
||||||
|
public double[][] generateMatrix(int rows, int cols) {
|
||||||
|
Random rand = new Random();
|
||||||
|
double[][] matrix = new double[rows][cols];
|
||||||
|
for (int i = 0; i < rows; i++) {
|
||||||
|
for (int j = 0; j < cols; j++) {
|
||||||
|
matrix[i][j] = Math.round((rand.nextDouble() * 100) * 100.0) / 100.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return matrix;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double findMaxAboveDiagonal(double[][] matrix) {
|
||||||
|
double max = Double.NEGATIVE_INFINITY;
|
||||||
|
for (int i = 0; i < matrix.length; i++) {
|
||||||
|
for (int j = i + 1; j < matrix[i].length; j++) { // Только выше главной диагонали
|
||||||
|
max = Math.max(max, matrix[i][j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double[][] extractTopHalfAboveDiagonal(double[][] matrix) {
|
||||||
|
int size = matrix.length;
|
||||||
|
double[][] topHalf = new double[size / 2][size];
|
||||||
|
|
||||||
|
for (int i = 0; i < size / 2; i++) {
|
||||||
|
System.arraycopy(matrix[i], i + 1, topHalf[i], i + 1, size - (i + 1));
|
||||||
|
}
|
||||||
|
return topHalf;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double[][] extractBottomHalfAboveDiagonal(double[][] matrix) {
|
||||||
|
int size = matrix.length;
|
||||||
|
double[][] bottomHalf = new double[size - size / 2][size];
|
||||||
|
|
||||||
|
for (int i = size / 2; i < size; i++) {
|
||||||
|
System.arraycopy(matrix[i], i + 1, bottomHalf[i - size / 2], i + 1, size - (i + 1));
|
||||||
|
}
|
||||||
|
return bottomHalf;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void saveToFile(double[][] matrix, String filename) {
|
||||||
|
try (BufferedWriter writer = new BufferedWriter(new FileWriter(filename))) {
|
||||||
|
for (double[] row : matrix) {
|
||||||
|
writer.write(Arrays.stream(row)
|
||||||
|
.mapToObj(Double::toString)
|
||||||
|
.collect(Collectors.joining(" ")));
|
||||||
|
writer.newLine();
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Класс для хранения результата обработки матрицы
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class ProcessingResult {
|
||||||
|
private double maxElement;
|
||||||
|
private long totalTimeMillis;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Замер времени:
|
||||||
|
|
||||||
|
Для каждого этапа выполняется замер времени с использованием System.currentTimeMillis().
|
||||||
|
|
||||||
|
Результаты работы
|
||||||
|
|
||||||
|
Матрица 10000 × 10000
|
||||||
|
|
||||||
|
Тест Однопоточный алгоритм Многопоточный алгоритм
|
||||||
|
Тест №1 1615 мс 740 мс
|
||||||
|
Тест №2 1789 мс 743 мс
|
||||||
|
Тест №3 1613 мс 696 мс
|
||||||
|
|
||||||
|
Матрица 5000 × 5000
|
||||||
|
|
||||||
|
Тест Однопоточный алгоритм Многопоточный алгоритм
|
||||||
|
Тест №1 420 мс 210 мс
|
||||||
|
Тест №2 435 мс 205 мс
|
||||||
|
Тест №3 410 мс 215 мс
|
||||||
|
|
||||||
|
Матрица 2000 × 2000
|
||||||
|
|
||||||
|
Тест Однопоточный алгоритм Многопоточный алгоритм
|
||||||
|
Тест №1 65 мс 35 мс
|
||||||
|
Тест №2 68 мс 34 мс
|
||||||
|
Тест №3 67 мс 36 мс
|
||||||
|
|
||||||
|
Вывод:
|
||||||
|
|
||||||
|
Такая реализация демонстрирует эффективное использование многопоточности и распределённых вычислений для ускорения выполнения задачи
|
||||||
|
Для небольших матриц (до 2000 × 2000) разница во времени выполнения между однопоточным и многопоточным подходами незначительна, но для больших матриц многопоточный подход будет работать значительно быстрее
|
||||||
|
Использование удалённого сервиса для обработки части матрицы является хорошим подходом, однако наша реализация зависит от него, в случае возникновения на удалённом сервисе каких-то проблем, программа не будет выполнена
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package org.example.sspr3Evgeni;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/matrix")
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class FindMaxController {
|
||||||
|
|
||||||
|
private final FindMaxService findMaxService;
|
||||||
|
|
||||||
|
@PostMapping("/findMax")
|
||||||
|
public ResponseEntity<Double> findMax(@RequestBody MatrixData requestData) {
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
|
double max = findMaxService.findMaxAboveDiagonal(requestData.getMatrix());
|
||||||
|
log.info("Second cont finish the process matrix");
|
||||||
|
long totalTime = System.currentTimeMillis() - startTime;
|
||||||
|
return ResponseEntity.ok(max);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package org.example.sspr3Evgeni;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class FindMaxService {
|
||||||
|
|
||||||
|
public double findMaxAboveDiagonal(double[][] matrix) {
|
||||||
|
double max = Double.NEGATIVE_INFINITY;
|
||||||
|
for (int i = 0; i < matrix.length; i++) {
|
||||||
|
for (int j = i + 1; j < matrix[i].length; j++) { // Выше главной диагонали
|
||||||
|
max = Math.max(max, matrix[i][j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package org.example.sspr3Evgeni;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/matrix")
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class MatrixController {
|
||||||
|
|
||||||
|
private final MatrixService matrixService;
|
||||||
|
|
||||||
|
@PostMapping("/findMaxAboveDiagonal")
|
||||||
|
public ResponseEntity<ProcessingResult> findMaxAboveDiagonal(@RequestParam int size) {
|
||||||
|
ProcessingResult result = matrixService.findMaxAboveDiagonal(size);
|
||||||
|
return ResponseEntity.ok(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package org.example.sspr3Evgeni;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class MatrixData {
|
||||||
|
private double[][] matrix;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
package org.example.sspr3Evgeni;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class MatrixService {
|
||||||
|
|
||||||
|
private final RestTemplate restTemplate;
|
||||||
|
private final MatrixUtils matrixUtils;
|
||||||
|
|
||||||
|
public ProcessingResult findMaxAboveDiagonal(int size) {
|
||||||
|
double[][] matrix = matrixUtils.generateMatrix(size, size);
|
||||||
|
log.info("Matrix generated");
|
||||||
|
matrixUtils.saveToFile(matrix,"/root/sspr3/src/main/resources/matrix.txt");
|
||||||
|
log.info("Matrix saved to file /root/sspr3/src/main/resources/matrix.txt");
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
|
|
||||||
|
// Разделяем верхнюю часть на две области
|
||||||
|
double[][] topHalf = matrixUtils.extractTopHalfAboveDiagonal(matrix);
|
||||||
|
double[][] bottomHalf = matrixUtils.extractBottomHalfAboveDiagonal(matrix);
|
||||||
|
|
||||||
|
// Отправляем верхнюю часть во второй контейнер
|
||||||
|
ResponseEntity<Double> response = restTemplate.postForEntity(
|
||||||
|
"http://second-container:8081/api/matrix/findMax",
|
||||||
|
new MatrixData(topHalf),
|
||||||
|
Double.class
|
||||||
|
);
|
||||||
|
log.info("Send the matrix first cont");
|
||||||
|
|
||||||
|
// Локальный максимум в нижней части
|
||||||
|
double localMax = matrixUtils.findMaxAboveDiagonal(bottomHalf);
|
||||||
|
|
||||||
|
// Получаем максимум от второго контейнера
|
||||||
|
double remoteMax = response.getBody();
|
||||||
|
log.info("Get the matrix to second container");
|
||||||
|
// Вычисляем финальный максимум
|
||||||
|
double finalMax = Math.max(localMax, remoteMax);
|
||||||
|
long totalTime = System.currentTimeMillis() - startTime;
|
||||||
|
|
||||||
|
return new ProcessingResult(finalMax, totalTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
package org.example.sspr3Evgeni;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.io.BufferedWriter;
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class MatrixUtils {
|
||||||
|
|
||||||
|
public double[][] generateMatrix(int rows, int cols) {
|
||||||
|
Random rand = new Random();
|
||||||
|
double[][] matrix = new double[rows][cols];
|
||||||
|
for (int i = 0; i < rows; i++) {
|
||||||
|
for (int j = 0; j < cols; j++) {
|
||||||
|
matrix[i][j] = Math.round((rand.nextDouble() * 100) * 100.0) / 100.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return matrix;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double findMaxAboveDiagonal(double[][] matrix) {
|
||||||
|
double max = Double.NEGATIVE_INFINITY;
|
||||||
|
for (int i = 0; i < matrix.length; i++) {
|
||||||
|
for (int j = i + 1; j < matrix[i].length; j++) { // Только выше главной диагонали
|
||||||
|
max = Math.max(max, matrix[i][j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double[][] extractTopHalfAboveDiagonal(double[][] matrix) {
|
||||||
|
int size = matrix.length;
|
||||||
|
double[][] topHalf = new double[size / 2][size];
|
||||||
|
|
||||||
|
for (int i = 0; i < size / 2; i++) {
|
||||||
|
System.arraycopy(matrix[i], i + 1, topHalf[i], i + 1, size - (i + 1));
|
||||||
|
}
|
||||||
|
return topHalf;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double[][] extractBottomHalfAboveDiagonal(double[][] matrix) {
|
||||||
|
int size = matrix.length;
|
||||||
|
double[][] bottomHalf = new double[size - size / 2][size];
|
||||||
|
|
||||||
|
for (int i = size / 2; i < size; i++) {
|
||||||
|
System.arraycopy(matrix[i], i + 1, bottomHalf[i - size / 2], i + 1, size - (i + 1));
|
||||||
|
}
|
||||||
|
return bottomHalf;
|
||||||
|
}
|
||||||
|
public void saveToFile(double[][] matrix, String filename) {
|
||||||
|
try (BufferedWriter writer = new BufferedWriter(new FileWriter(filename))) {
|
||||||
|
for (double[] row : matrix) {
|
||||||
|
writer.write(Arrays.stream(row)
|
||||||
|
.mapToObj(Double::toString)
|
||||||
|
.collect(Collectors.joining(" ")));
|
||||||
|
writer.newLine();
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package org.example.sspr3Evgeni;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class ProcessingResult {
|
||||||
|
private double maxElement;
|
||||||
|
private long totalTimeMillis;
|
||||||
|
}
|
||||||
|
|
||||||
20
gorskov_evgeniu_lab_3/sspr3/src/main/java/test/Main.java
Normal file
20
gorskov_evgeniu_lab_3/sspr3/src/main/java/test/Main.java
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
package org.example;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.ComponentScan;
|
||||||
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
@ComponentScan("org.example.sspr3Parallel")
|
||||||
|
public class Main {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(Main.class, args);
|
||||||
|
}
|
||||||
|
@Bean
|
||||||
|
public RestTemplate restTemplate() {
|
||||||
|
return new RestTemplate();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
server.port=8080
|
||||||
@@ -1,82 +0,0 @@
|
|||||||
Лабораторная работа №2
|
|
||||||
|
|
||||||
Разработка параллельного MPI приложения на языке Java.
|
|
||||||
|
|
||||||
Необходимо разработать параллельный вариант алгоритма с применением MPI и замерить время его работы. В рамках работы программы должно быть две копии приложения, которые соединяются друг с другом по сети. Сообщения о статусе соединения (например, что соединение установлено) должны выводиться в консоль. Запуск каждого экземпляра MPI происходит в своём LXC контейнере. Такие сервисы, как Docker, использовать нельзя.
|
|
||||||
|
|
||||||
Необходимо выполнить следующие задачи:
|
|
||||||
|
|
||||||
Разработать параллельный вариант алгоритма с использованием MPI.
|
|
||||||
Замерить время его работы.
|
|
||||||
Обеспечить взаимодействие двух копий приложения через сеть.
|
|
||||||
Выводить сообщения о статусе соединения в консоль.
|
|
||||||
Запускать каждый экземпляр MPI в отдельном LXC контейнере.
|
|
||||||
|
|
||||||
Вариант задания
|
|
||||||
|
|
||||||
8)Найти максимальный элемент выше главной диагонали
|
|
||||||
|
|
||||||
Как запустить программу
|
|
||||||
|
|
||||||
Необходимо запустить bash-файл, где уже прописаны необходимые настройки для запуска программы:
|
|
||||||
/root/sspr2.sh
|
|
||||||
|
|
||||||
Инструменты
|
|
||||||
|
|
||||||
Язык программирования: Java
|
|
||||||
Пакеты:
|
|
||||||
mpi — используется для реализации параллельных вычислений с использованием MPI.
|
|
||||||
Среда разработки: IntelliJ IDEA
|
|
||||||
Версия JDK: 21
|
|
||||||
|
|
||||||
Описание работы программы
|
|
||||||
|
|
||||||
Генерация матрицы
|
|
||||||
Программа генерирует случайную матрицу заданного размера (количество строк и столбцов передается как аргументы командной строки)
|
|
||||||
|
|
||||||
Матрица заполняется случайными целыми числами
|
|
||||||
|
|
||||||
Параллельный алгоритм с использованием MPI
|
|
||||||
|
|
||||||
Матрица разделяется на две части
|
|
||||||
Каждая часть обрабатывается в отдельном LXC контейнере
|
|
||||||
Каждый контейнер находит максимальный элемент выше главной диагонали в своей части матрицы
|
|
||||||
Результаты передаются между контейнерами, и определяется глобальный максимум
|
|
||||||
|
|
||||||
Взаимодействие между контейнерами
|
|
||||||
|
|
||||||
Используется MPI для передачи данных между контейнерами
|
|
||||||
Сообщения о статусе соединения (например, "Соединение установлено") выводятся в консоль
|
|
||||||
|
|
||||||
Замер времени
|
|
||||||
|
|
||||||
Для параллельного алгоритма замеряется время выполнения
|
|
||||||
Результаты выводятся на экран
|
|
||||||
|
|
||||||
Результаты работы на матрице 10000 × 10000
|
|
||||||
|
|
||||||
Тест Время выполнения
|
|
||||||
Тест №1 520 мс
|
|
||||||
Тест №2 530 мс
|
|
||||||
Тест №3 510 мс
|
|
||||||
|
|
||||||
Результаты работы на матрице 5000 × 5000
|
|
||||||
|
|
||||||
Тест Время выполнения
|
|
||||||
Тест №1 130 мс
|
|
||||||
Тест №2 135 мс
|
|
||||||
Тест №3 128 мс
|
|
||||||
|
|
||||||
Результаты работы на матрице 2000 × 2000
|
|
||||||
|
|
||||||
Тест Время выполнения
|
|
||||||
Тест №1 22 мс
|
|
||||||
Тест №2 24 мс
|
|
||||||
Тест №3 21 мс
|
|
||||||
|
|
||||||
Вывод
|
|
||||||
|
|
||||||
Параллельный алгоритм с использованием MPI показывает значительное ускорение по сравнению с однопоточным и многопоточными подходами (например, ThreadPoolExecutor и ForkJoinPool).
|
|
||||||
Взаимодействие между контейнерами через MPI позволяет эффективно распределить нагрузку и ускорить выполнение задачи.
|
|
||||||
Для больших матриц (например, 10000 × 10000) MPI демонстрирует высокую производительность благодаря параллельной обработке данных.
|
|
||||||
Для небольших матриц (например, 2000 × 2000) время выполнения значительно меньше, но MPI все равно остается эффективным.
|
|
||||||
@@ -1,83 +0,0 @@
|
|||||||
package sspr2;
|
|
||||||
|
|
||||||
import mpi.MPI;
|
|
||||||
import mpi.MPIException;
|
|
||||||
|
|
||||||
import java.io.FileWriter;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
public class CTFirst {
|
|
||||||
public static void main(String[] args) throws MPIException, IOException {
|
|
||||||
try {
|
|
||||||
MPI.Init(args);
|
|
||||||
String name = MPI.Get_processor_name();
|
|
||||||
int row = Integer.parseInt(args[args.length - 4]);
|
|
||||||
int col = Integer.parseInt(args[args.length - 5]);
|
|
||||||
if (row % 2 != 0 || col % 2 != 0) {
|
|
||||||
System.out.println("Row or col not even");
|
|
||||||
MPI.Finalize();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
System.out.println("Row = " + row);
|
|
||||||
System.out.println("Column = " + col);
|
|
||||||
int[][] matrix = generateMatrix(row, col);
|
|
||||||
String filenameMatrixStart = "/root/sspr2/res/matrixStart.txt";
|
|
||||||
int[][] secondPartMatrix = new int[row / 2][col];
|
|
||||||
int iterator = 0;
|
|
||||||
for (int i = row / 2; i < row; i++) {
|
|
||||||
System.arraycopy(matrix[i], 0, secondPartMatrix[iterator], 0, col);
|
|
||||||
iterator++;
|
|
||||||
}
|
|
||||||
System.out.println("Matrix write to file with name '" + filenameMatrixStart + "'");
|
|
||||||
writeMatrixByFile(filenameMatrixStart, matrix, row, col);
|
|
||||||
int[] responseArray = ParserMPI.convertMatrixToArray(matrix, row / 2, col);
|
|
||||||
int[] responseIndexColumn = SortMatrix.getIndexColumn(matrix, col);
|
|
||||||
System.out.println(responseIndexColumn.length);
|
|
||||||
int[] sizeMatrix = {row / 2, col};
|
|
||||||
MPI.COMM_WORLD.Send(sizeMatrix, 0, 2, MPI.INT, 1, 0);
|
|
||||||
System.out.println("Началась отправка массива с размерами с " + name + "процессора");
|
|
||||||
MPI.COMM_WORLD.Send(responseArray, 0, responseArray.length, MPI.INT, 1, 0);
|
|
||||||
System.out.println("Началась асинхронная отправка половины массива с " + name + " контейнера");
|
|
||||||
int ourPartMax = SortMatrix.searchMaxAboveMainDiagonal(secondPartMatrix, 0, row / 2, col, name);
|
|
||||||
int[] requestMax = new int[1];
|
|
||||||
MPI.COMM_WORLD.Recv(requestMax, 0, 1, MPI.INT, 1, 0);
|
|
||||||
int secondMax = requestMax[0];
|
|
||||||
if(ourPartMax < secondMax) {
|
|
||||||
System.out.println("Max element " + secondMax + " is greater than " + ourPartMax);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
System.out.println("Max element " + ourPartMax + " is greater than " + secondMax);
|
|
||||||
}
|
|
||||||
MPI.Finalize();
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int[][] generateMatrix(int row, int col) {
|
|
||||||
int[][] matrix = new int[row][col];
|
|
||||||
for (int i = 0; i < row; i++) {
|
|
||||||
for (int j = 0; j < col; j++) {
|
|
||||||
matrix[i][j] = (int) (Math.random() * 100);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return matrix;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void writeMatrixByFile(String filename, int[][] matrix, int row, int col) throws IOException {
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
FileWriter fw = new FileWriter(filename);
|
|
||||||
fw.write(row + "\n");
|
|
||||||
fw.write(col + "\n");
|
|
||||||
for (int i = 0; i < row; i++) {
|
|
||||||
for (int j = 0; j < col; j++) {
|
|
||||||
String s = Math.round(matrix[i][j] * 100.0) / 100.0 + "";
|
|
||||||
sb.append(s).append(" ");
|
|
||||||
}
|
|
||||||
sb.append("\n");
|
|
||||||
}
|
|
||||||
fw.write(sb.toString());
|
|
||||||
fw.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
package sspr2;
|
|
||||||
|
|
||||||
public class ParserMPI {
|
|
||||||
|
|
||||||
public static int[][] parseMatrix(int[] requestMatrix, int row, int col) {
|
|
||||||
int iterator = 0;
|
|
||||||
int[][] matrix = new int[row][col];
|
|
||||||
for (int i = 0; i < row; i++) {
|
|
||||||
System.arraycopy(requestMatrix, iterator, matrix[i], 0, col);
|
|
||||||
iterator += col;
|
|
||||||
}
|
|
||||||
return matrix;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int[] convertMatrixToArray(int[][] matrix, int row, int col) {
|
|
||||||
int iterator = 0;
|
|
||||||
int[] response = new int[row * col];
|
|
||||||
for (int i = 0; i < row; i++) {
|
|
||||||
System.arraycopy(matrix[i], 0, response, iterator, col);
|
|
||||||
iterator += col;
|
|
||||||
}
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
package sspr2;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Comparator;
|
|
||||||
|
|
||||||
public class SortMatrix {
|
|
||||||
|
|
||||||
public static int[][] sortMatrix(int[][] matrix, int startRow, int endRow, int column, int[] indexColumn, String name) {
|
|
||||||
int[][] tempMatrix = new int[endRow][column];
|
|
||||||
int iterator = 1;
|
|
||||||
for (int i = 0; i < column; i++) {
|
|
||||||
for (int j = startRow; j < endRow; j++) {
|
|
||||||
tempMatrix[j][i] = matrix[j][indexColumn[i]];
|
|
||||||
}
|
|
||||||
iterator++;
|
|
||||||
// System.out.println(name + "закончил обрабатывать " + iterator + " колонку");
|
|
||||||
}
|
|
||||||
System.out.println(name + "закончил обрабатывать целиком свою половину");
|
|
||||||
return tempMatrix;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int searchMaxAboveMainDiagonal(int[][] matrix, int startRow, int endRow, int column, String name) {
|
|
||||||
int max = 0;
|
|
||||||
System.out.println(name + "начал обрабатывать свою половину");
|
|
||||||
for (int i = startRow; i < endRow; i++) {
|
|
||||||
for (int j = i; j < column; j++) {
|
|
||||||
if (matrix[i][j] > max) {
|
|
||||||
max = matrix[i][j];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
System.out.println(name + "закончил обрабатывать целиком свою половину");
|
|
||||||
return max;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int[] getIndexColumn(int[][] matrix, int column) {
|
|
||||||
int[] maxElements = new int[column];
|
|
||||||
for (int i = 0; i < column; i++) {
|
|
||||||
for (int[] ints : matrix) {
|
|
||||||
if (ints[i] > maxElements[i]) {
|
|
||||||
maxElements[i] = ints[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Integer[] indexColumn = new Integer[column];
|
|
||||||
for (int i = 0; i < column; i++) {
|
|
||||||
indexColumn[i] = i;
|
|
||||||
}
|
|
||||||
Arrays.sort(indexColumn, Comparator.comparingInt((Integer j) ->
|
|
||||||
Arrays.stream(matrix).mapToInt(rows -> rows[j]).max().orElse(Integer.MIN_VALUE)).reversed()
|
|
||||||
);
|
|
||||||
return Arrays.stream(indexColumn).mapToInt(integer -> integer).toArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
192.168.28.250
|
|
||||||
192.168.28.129
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
10
|
|
||||||
10
|
|
||||||
27.0 30.0 99.0 59.0 17.0 41.0 80.0 53.0 68.0 68.0
|
|
||||||
53.0 77.0 10.0 22.0 83.0 72.0 56.0 31.0 23.0 17.0
|
|
||||||
28.0 23.0 88.0 31.0 60.0 82.0 49.0 87.0 18.0 67.0
|
|
||||||
12.0 64.0 95.0 55.0 22.0 0.0 47.0 54.0 18.0 86.0
|
|
||||||
65.0 36.0 45.0 93.0 92.0 79.0 22.0 71.0 25.0 82.0
|
|
||||||
40.0 96.0 71.0 6.0 83.0 1.0 58.0 11.0 28.0 31.0
|
|
||||||
30.0 40.0 7.0 19.0 4.0 28.0 6.0 71.0 13.0 84.0
|
|
||||||
81.0 13.0 70.0 83.0 75.0 3.0 94.0 80.0 43.0 80.0
|
|
||||||
20.0 78.0 6.0 81.0 42.0 57.0 49.0 74.0 26.0 55.0
|
|
||||||
48.0 40.0 47.0 55.0 74.0 35.0 24.0 39.0 9.0 17.0
|
|
||||||
Reference in New Issue
Block a user