From 5edeee1b9acef6e1d9f46fb81ccbddd5792bac0f Mon Sep 17 00:00:00 2001 From: Pavel Kuliaka Date: Sun, 12 Oct 2025 15:24:33 +0300 Subject: [PATCH 1/3] Implemented a brute force solution --- .../Queens/brute_force_solution.py | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 src/Homework #3/Queens/brute_force_solution.py diff --git a/src/Homework #3/Queens/brute_force_solution.py b/src/Homework #3/Queens/brute_force_solution.py new file mode 100644 index 0000000..5be544e --- /dev/null +++ b/src/Homework #3/Queens/brute_force_solution.py @@ -0,0 +1,32 @@ +def is_safe_direction(coordinate_1: tuple[int, int], coordinate_2: tuple[int, int]) -> bool: + if coordinate_1[1] == coordinate_2[1] or abs( + coordinate_1[1] - coordinate_2[1] + ) == abs(coordinate_1[0] - coordinate_2[0]): + return False + return True + + +N = int(input("Enter the value N: ")) + +board_size = N**2 + +counter = 0 + +stack: list[list[tuple[int, int]]] = [[]] +while stack: + placements: list[tuple[int, int]] = stack.pop() + + if len(placements) == N: + counter += 1 + else: + current_row = len(placements) + for column in range(N): + for placement_column, placement_row in placements: + if not is_safe_direction( + (placement_column, placement_row), (current_row, column) + ): + break + else: + stack.append(placements + [(current_row, column)]) + +print(f"The number of possible different arrangements is {counter}") From c40336b3ef09356a95ddb17967c611fdff803493 Mon Sep 17 00:00:00 2001 From: Pavel Kuliaka Date: Sun, 12 Oct 2025 15:24:53 +0300 Subject: [PATCH 2/3] Implemented a recursive solution --- src/Homework #3/Queens/recursive_solution.py | 27 ++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 src/Homework #3/Queens/recursive_solution.py diff --git a/src/Homework #3/Queens/recursive_solution.py b/src/Homework #3/Queens/recursive_solution.py new file mode 100644 index 0000000..204648e --- /dev/null +++ b/src/Homework #3/Queens/recursive_solution.py @@ -0,0 +1,27 @@ +def is_safe_placement(coordinate_1: tuple[int, int], coordinate_2: tuple[int, int]) -> bool: + if coordinate_1[0] == coordinate_2[0] or abs( + coordinate_1[1] - coordinate_2[1] + ) == abs(coordinate_1[0] - coordinate_2[0]): + return False + return True + + +N = int(input('Enter the value N: ')) + +board_size = N**2 + +result = 0 +def foo(placements=[]): + if len(placements) == N: + global result + result += 1 + return + current_row = len(placements) + for next_column in range(N): + position = (next_column, current_row) + if all(is_safe_placement(placement, position) for placement in placements): + foo(placements + [position]) + +foo() + +print(f"The number of possible different arrangements is {result}") From 889ee80652325258e51370cb098adba0a0813d78 Mon Sep 17 00:00:00 2001 From: Pavel Kuliaka Date: Sun, 12 Oct 2025 15:25:28 +0300 Subject: [PATCH 3/3] Added algorithm evaluation --- src/Homework #3/Queens/complexity.md | 37 ++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 src/Homework #3/Queens/complexity.md diff --git a/src/Homework #3/Queens/complexity.md b/src/Homework #3/Queens/complexity.md new file mode 100644 index 0000000..8bf9bd1 --- /dev/null +++ b/src/Homework #3/Queens/complexity.md @@ -0,0 +1,37 @@ +# Оценка сложности каждого решения +## Рекурсивное решение (самое быстрое) +**Рассмотрим неконстантную сложность алгоритма** +```Python +for next_column in range(N): # Сложность - O(N) + # Сложность - O(k), где k - глубина вызова + if all(is_safe_placement(placement, position) for placement in placements): + foo(placements + [position]) # Рекурсивный вызов +``` +**Рассмотрим сложность алгоритма на каждой глубине рекурсии** + +- Уровень 0: $N \times O(N)$ +- Уровень 1: $N \times (N - 1) \times O(N)$ +- Уровень 2: $N \times (N - 1) \times (N - 2) \times O(N)$ +- ... +- Уровень $N-1: N \times (N-1) \times (N-2) \times \dots \times 1 \times O(N) = O(N \times N!)$ + +**Сложность алгоритма:** $O(N \times N!)$ + +--- + +## Переборное решение +**Рассмотрим неконстантную сложность алгоритма** +```Python +while stack: # Сложность - O(N!) + ... + else: + for column in range(N): # Сложность - O(N) + for placement_column, placement_row in placements: # Сложность - O(k), где 0 <= k <= N-1 + ... +``` +**Просуммируем оценку** +1. Количество узлов в дереве поиска: $O(N!)$ +2. Работа на узле: $O(N) \times O(k) = O(Nk)$ +3. Итоговая сложность: $\sum_{k=0}^{N-1} \frac{N!}{(N-k)!} \times O(Nk) = O(N \times N!)$ + +**Сложность алгоритма:** $O(N \times N!)$