neshina_anastasiia_lab_1 is ready

This commit is contained in:
korbwest 2025-02-25 21:00:17 +04:00
parent 4661f77f23
commit ba95b7215f
7 changed files with 285 additions and 65 deletions

View File

@ -1,65 +0,0 @@
# SSPR_25
ПРАВИЛА ИГРЫ при сдаче лабораторных работ по предмету "ССПР".
Всем Доброго времени суток! Настоятельно прошу прочитать этот файл от начала и до конца.
**Задание на л/р**
0. Требования к языку программирования: java, как указано в л/р. Но если вы нашли аналогичные технологии в других языках - Welcome! Но это нужно будет доказать.
Для выполнения лабораторных работ можно использовать любую IDE или текстовый редактор.
1. Файл с заданиями находится в [Я.Диске](https://vk.com/away.php?to=https%3A%2F%2Fdisk.yandex.ru%2Fd%2F0f-odCaIXYdHuA&utf=1).
**Воркфлоу по сдаче лабораторных работ**
0. Клонируем себе репозиторий на компьютер
> git clone https://git.is.ulstu.ru/sevastyan_b/SSPR_25.git
1. Для выполнения очередной лабораторной работы необходимо завести отдельную ветку (перед этим необходимо выполнить команду git checkout master). Указанный формат наименования ветки <фамилия_имя_lab_номерабораторной> ОБЯЗАТЕЛЕН, в противном случае лабораторная работа не проверяется!
> git checkout -b "basharin_sevastyan_lab_1"
При этом Вы окажетесь в своей ветке, в которой Вам и предстоит выполнять лабораторную работу.
2. В ветке создаём папку в аналогичном формате <фамилия_имя_lab_номерабораторной>, формат также ОБЯЗАТЕЛЕН, в противном случае лабораторная работа не проверяется!
> mkdir basharin_sevastyan_lab_1
3. Весь код лабораторной работы и отчет должны находится внутри этой папки! То есть файловая структура репозитория должна иметь такой вид
> ivanov_ivan_lab_1 basharin_sevastyan_lab_1 README.md
4. Отчет к лабораторной работе должен быть оформлен в виде файла readme.md, в котором Вы сможете дать краткое описание того, что делает Ваша программа. Очень хорошо (большой плюс при сдаче), если Вы опишите следующие пункты:
* как запустить лабораторную работу
* какие технологии использовали
* что она делает
* тесты, то есть несколько примеров входных и выходных значений
Небольшой [гайд](https://guides.github.com/features/mastering-markdown/) по синтаксису для оформления отчёта.
P.S. я знаю про хак "хочу скопировать у товарища этот волшебный readme и ничего не делать", но пожалуйста не делайте так (я буду обязательно проверять это)
4. Как только Вы закончили работу над лабораторной работой, то находясь в своей ветке (убедитесь в этом пожалуйста, использую команду git branch - ваша текущая ветка будет подсвечена), вы должны закоммитить и запушить свои изменения в репозиторий, другими словами сохранить их в репозиторий.
> git commit -m "basharin_sevastyan_lab_1 is ready"
> git push origin
P.S. я знаю про хак "скопируй у товарища и закоммить - все равно он (я) смотреть не будет" - не сработает - давайте быть честными и делать все самостоятельно. А во-вторых, на реальной работе так не прокатит - скорее всего Вас просто уволят.
5. После этого Вы должны перейти в наш git и создать merge request, назначив его на меня. Дополнительно можно маякнуть меня в нашем телеграм-чате (особенно в четверг). Я проведу ревью и отпишу замечания, которые нужно будет исправить. Если все хорошо, то вмержу ваш pull-request в мастер-ветку. Данное состояние говорит о том, что ваша л/р принята.
6. **Важный момент**: Это делается для того, чтобы вы привыкали к воркфлоу, который применяется практически всеми IT-компаниями, где между разработчиками в основном общение идет через "текст". Что касается лабораторных работ в расписании - они используются в качестве консультаций, сдачи теории и демонстрации работоспособности л/р, а сдача и проверка л/р идет только через репозиторий (то есть все замечания вы получаете на code review). Проверять лабораторную буду стараться в течение 1-3 дней после создания pull-request-а (всегда можно маякнуть меня в нашем telegram-чате).
**Чек-лист для старост групп**
0. Убедиться, что все зарегистрировались на университетском [git](http://git.is.ulstu.ru/) и добавились для работы с нашим репозиторием. А добавляться в этот [репозиторий](http://https://git.is.ulstu.ru/sevastyan_b/SSPR_25).
**Полезные ссылки:**
0. Отличный тьюториал по гиту (рекомендую всем его пройти), вот [тут](https://learngitbranching.js.org/)
1. Гайд по markdown [тут](https://guides.github.com/features/mastering-markdown/)
БОЛЬШОЕ СПАСИБО, что дочитали этот README до конца! И Удачи Вам в сдаче л/р и не только!

View File

@ -0,0 +1,58 @@
# Лабораторная работа №1. Вариант 16.
**Упорядочить столбцы матрицы по возрастанию суммы их элементов.**
Для работы используем:
1) Однопоточный алгоритм.
2) Многопоточный алгоритм с использованием ThreadPoolExecutor.
3) Многопоточный алгоритм с использованием ForkJoinPool.
## Как запустить лабораторную работу
Сначала компилируем наш код коммандой: javac Main.java
Затем запускаем: java Main
## Технологии
Стандартные библиотеки Java: java.util.concurrent для работы с многопоточностью.
ThreadPoolExecutor: Используется для управления пулом потоков, тут каждый поток вычисляет сумму для отдельного столбца.
ForkJoinPool: Используется для рекурсивного разбиения задачи: делим матрицу пополам рекурсивно, и каждый поток работает с несколькими столбцами.
## Что программа делает
Задача — упорядочить столбцы матрицы по возрастанию суммы их элементов.
Посмотрим поэтапно:
1) Генерируем матрицу случайным образом в зависимости от указанной размерности, диапазон значений может быть от 0 до 99.
2) Записываем в файл input_matrix.txt.
3) Далее используем сначала однопоточный алгоритм: Суммы столбцов вычисляются последовательно, и только потом столбцы сортируются по этим суммам.
4) Теперь посмотрим как работает многопоточный алгоритм с ThreadPoolExecutor: Суммы столбцов вычисляются параллельно с использованием пула потоков, потом столбцы сортируются.
5) Многопоточный алгоритм с ForkJoinPool: Суммы столбцов вычисляются параллельно с использованием ForkJoinPool, который разбивает задачу на подзадачи.
6) Время выполнения каждого алгоритма замеряется и выводится в консоль.
7) Отсортированная матрица записывается в файлы: output_single_thread.txt, output_thread_pool.txt и output_fork_join.txt для каждого из алгоритмов.
Хотя результат работы сортировки и будет одинаковым, итоги всё равно запишем в отдельные файлы.
## Примеры входных и выходных значений
Input lines: 1000
Input columns: 1000
One thread: 611 mc
ThreadPoolExecutor: 128 mc
ForkJoinPool: 76 mc
Input lines: 500
Input columns: 500
One thread: 305 mc
ThreadPoolExecutor: 116 mc
ForkJoinPool: 15 mc
Input lines: 100
Input columns: 100
One thread: 489 mc
ThreadPoolExecutor: 91 mc
ForkJoinPool: 30 mc
Input lines: 10
Input columns: 10
One thread: 186 mc
ThreadPoolExecutor: 20 mc
ForkJoinPool: 4 mc

View File

@ -0,0 +1,10 @@
39 1 79 60 61 92 42 42 30 12
18 70 0 30 83 84 10 47 49 62
89 82 23 15 22 10 76 12 21 50
18 89 96 62 84 48 46 48 29 25
31 53 11 64 68 35 3 73 33 20
38 23 88 49 84 33 45 20 33 17
84 56 49 43 74 44 62 94 7 15
9 70 50 15 74 82 19 55 20 16
3 92 89 76 66 36 68 2 97 94
38 60 87 8 43 60 93 30 72 43

View File

@ -0,0 +1,10 @@
12 39 30 60 42 42 92 79 1 61
62 18 49 30 47 10 84 0 70 83
50 89 21 15 12 76 10 23 82 22
25 18 29 62 48 46 48 96 89 84
20 31 33 64 73 3 35 11 53 68
17 38 33 49 20 45 33 88 23 84
15 84 7 43 94 62 44 49 56 74
16 9 20 15 55 19 82 50 70 74
94 3 97 76 2 68 36 89 92 66
43 38 72 8 30 93 60 87 60 43

View File

@ -0,0 +1,10 @@
12 39 30 60 42 42 92 79 1 61
62 18 49 30 47 10 84 0 70 83
50 89 21 15 12 76 10 23 82 22
25 18 29 62 48 46 48 96 89 84
20 31 33 64 73 3 35 11 53 68
17 38 33 49 20 45 33 88 23 84
15 84 7 43 94 62 44 49 56 74
16 9 20 15 55 19 82 50 70 74
94 3 97 76 2 68 36 89 92 66
43 38 72 8 30 93 60 87 60 43

View File

@ -0,0 +1,10 @@
12 39 30 60 42 42 92 79 1 61
62 18 49 30 47 10 84 0 70 83
50 89 21 15 12 76 10 23 82 22
25 18 29 62 48 46 48 96 89 84
20 31 33 64 73 3 35 11 53 68
17 38 33 49 20 45 33 88 23 84
15 84 7 43 94 62 44 49 56 74
16 9 20 15 55 19 82 50 70 74
94 3 97 76 2 68 36 89 92 66
43 38 72 8 30 93 60 87 60 43

View File

@ -0,0 +1,187 @@
import java.io.*;
import java.util.*;
import java.util.concurrent.*; // <EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
public class Main {
public static int[][] generateMatrix(int rows, int cols) {
int[][] matrix = new int[rows][cols];
Random random = new Random();
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
matrix[i][j] = random.nextInt(100);
}
}
return matrix;
}
public static void writeMatrixToFile(int[][] matrix, String filename) throws IOException {
try (BufferedWriter writer = new BufferedWriter(new FileWriter(filename))) {
for (int[] row : matrix) {
for (int value : row) {
writer.write(value + " ");
}
writer.newLine();
}
}
}
public static int[][] readMatrixFromFile(String filename, int rows, int cols) throws IOException {
int[][] matrix = new int[rows][cols];
try (BufferedReader reader = new BufferedReader(new FileReader(filename))) {
for (int i = 0; i < rows; i++) {
String[] values = reader.readLine().trim().split(" ");
for (int j = 0; j < cols; j++) {
matrix[i][j] = Integer.parseInt(values[j]);
}
}
}
return matrix;
}
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
public static void singleThreadedSort(int[][] matrix) {
int cols = matrix[0].length;
int rows = matrix.length;
int[] columnSums = new int[cols];
for (int j = 0; j < cols; j++) {
for (int i = 0; i < rows; i++) {
columnSums[j] += matrix[i][j]; // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> j
}
}
sortColumns(matrix, columnSums); // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
}
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
public static void multiThreadedSortWithThreadPool(int[][] matrix, int numThreads) throws InterruptedException {
int cols = matrix[0].length;
int rows = matrix.length;
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
ExecutorService executor = Executors.newFixedThreadPool(numThreads);
int[] columnSums = new int[cols];
for (int j = 0; j < cols; j++) {
final int col = j;
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
executor.submit(() -> {
for (int i = 0; i < rows; i++) {
columnSums[col] += matrix[i][col];
}
});
}
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
executor.shutdown();
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
executor.awaitTermination(1, TimeUnit.MINUTES);
sortColumns(matrix, columnSums);
}
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
public static void multiThreadedSortWithForkJoin(int[][] matrix) {
int cols = matrix[0].length;
int rows = matrix.length;
int[] columnSums = new int[cols];
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
ForkJoinPool pool = new ForkJoinPool();
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD>ޣ<EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
pool.invoke(new ColumnSumTask(matrix, columnSums, 0, cols - 1));
sortColumns(matrix, columnSums);
}
static class ColumnSumTask extends RecursiveAction {
private final int[][] matrix;
private final int[] columnSums;
private final int start;
private final int end;
public ColumnSumTask(int[][] matrix, int[] columnSums, int start, int end) {
this.matrix = matrix;
this.columnSums = columnSums;
this.start = start;
this.end = end;
}
@Override
protected void compute() {
if (end - start <= 10) {
for (int j = start; j <= end; j++) {
for (int i = 0; i < matrix.length; i++) {
columnSums[j] += matrix[i][j];
}
}
} else {
int mid = (start + end) / 2;
ColumnSumTask leftTask = new ColumnSumTask(matrix, columnSums, start, mid);
ColumnSumTask rightTask = new ColumnSumTask(matrix, columnSums, mid + 1, end);
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
invokeAll(leftTask, rightTask);
}
}
}
private static void sortColumns(int[][] matrix, int[] columnSums) {
int cols = matrix[0].length;
int rows = matrix.length;
Integer[] columnIndices = new Integer[cols];
for (int j = 0; j < cols; j++) {
columnIndices[j] = j;
}
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD> columnSums
Arrays.sort(columnIndices, Comparator.comparingInt(j -> columnSums[j]));
int[][] sortedMatrix = new int[rows][cols];
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
sortedMatrix[i][j] = matrix[i][columnIndices[j]];
}
}
for (int i = 0; i < rows; i++) {
System.arraycopy(sortedMatrix[i], 0, matrix[i], 0, cols);
}
}
public static void main(String[] args) throws IOException, InterruptedException {
Scanner scanner = new Scanner(System.in);
System.out.print("Input lines: ");
int rows = scanner.nextInt();
System.out.print("Input columns: ");
int cols = scanner.nextInt();
int[][] matrix = generateMatrix(rows, cols);
writeMatrixToFile(matrix, "input_matrix.txt");
int[][] matrix1 = readMatrixFromFile("input_matrix.txt", rows, cols);
int[][] matrix2 = readMatrixFromFile("input_matrix.txt", rows, cols);
int[][] matrix3 = readMatrixFromFile("input_matrix.txt", rows, cols);
long startTime = System.currentTimeMillis();
singleThreadedSort(matrix1);
long endTime = System.currentTimeMillis();
System.out.println("One thread: " + (endTime - startTime) + " mc");
writeMatrixToFile(matrix1, "output_single_thread.txt");
startTime = System.currentTimeMillis();
multiThreadedSortWithThreadPool(matrix2, 4);
endTime = System.currentTimeMillis();
System.out.println("ThreadPoolExecutor: " + (endTime - startTime) + " mc");
writeMatrixToFile(matrix2, "output_thread_pool.txt");
startTime = System.currentTimeMillis();
multiThreadedSortWithForkJoin(matrix3);
endTime = System.currentTimeMillis();
System.out.println("ForkJoinPool: " + (endTime - startTime) + " mc");
writeMatrixToFile(matrix3, "output_fork_join.txt");
}
}