-
Notifications
You must be signed in to change notification settings - Fork 0
06oct25 Homework #2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
db1766d
721a5e5
ef8ce8d
6c8f646
6500663
13bccee
5b4593e
2b788a3
81a56fa
78298f1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| ## Переборный алгоритм | ||
| ### Скорость | ||
| Количество комбинаций во внешнем цикле $C_{n^2}^{n} = \frac{(n^2)!}{((n^2−n)!(n^2)!)}$. | ||
| Внутри вычисление rows и columns за $O(n)$. | ||
| Проверка диагоналей за $O(n^2)$ и прямых за 2 * O(n). | ||
| Итоговая сложность $O(\frac{n^2 * n^2!}{n! * (n^2-n)!})$. | ||
| $\to O(\frac{n^{2n+2}}{n!})$ | ||
|
|
||
| ## Рекурсивный алгоритм | ||
| ### Скорость | ||
| Глубина рекурсии n. | ||
| В каждом вызове перебирается n вариантов. | ||
| Проверкка выполняется за O(n). Итоговая сложность O(n * n^2) = O(n^3). | ||
|
Comment on lines
+11
to
+13
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Итоговая сложность не такая. Вы же делаете рекурсивный вызов в цикле. В общем, вы сильно оптимистичную оценку дали |
||
| ### Память | ||
| Рекурсия O(n) и O(n). Общая O(n) | ||
|
|
||
| ## Третий алгоритм | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Предполагается, что вы реализуете сильно более быстрый алгоритм. Проявите социальность, спросите у одногруппников
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Кажется, что вы не проявили социальность. Предполагается другое |
||
| ### Скорость | ||
| Перебирается n, n-1, n-2 и т.д. решений, в каждом из них проверка O(n). В итоге O(n * n!) | ||
| ### Память | ||
| Глубина рекурсии O(n), все переменные занимают O(1). Итого O(n) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| from itertools import combinations | ||
|
|
||
| def check_queen_combination(cell_numbers, n): | ||
| rows = [cell // n for cell in cell_numbers] | ||
| columns = [cell % n for cell in cell_numbers] | ||
| for i in range(1, n): | ||
| for j in range(i): | ||
| # проверяем что не на одной диагонали | ||
| if abs(rows[i] - rows[j]) == abs(columns[i] - columns[j]): | ||
| return False | ||
| if len(set(rows)) != n: | ||
| return False # если есть свопадающие ряды | ||
| if len(set(columns)) != n: | ||
| return False # если есть совпадающие колонки | ||
| return True | ||
|
|
||
| def queen_permutations(n): | ||
| count = 0 | ||
| # номера клеток с ферзем слева направо сверху вниз | ||
| for cell_numbers in combinations(range(n * n), n): | ||
| if check_queen_combination(cell_numbers, n): | ||
| count += 1 | ||
| return count | ||
|
|
||
| if __name__ == "__main__": | ||
| print(queen_permutations(7)) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| def queen_permutations(n): | ||
| def helper(row, board): | ||
| # если все ферзи расставлены найдено корректное решение | ||
| if row == n: | ||
| return 1 | ||
| count = 0 | ||
| # пробуем поставить ферзя в каждом столбце текущей строки | ||
| for column in range(n): | ||
| correct = True | ||
| # проверка что с новым ферзем все остается нормально | ||
| for i in range(row): | ||
| if board[i] == column or board[i] - i == column - row or board[i] + i == column + row: | ||
| correct = False | ||
| break | ||
| if correct: | ||
| board[row] = column | ||
| # добавляем к счетчику все комбинции ферзя со следующего ряда | ||
| count += helper(row + 1, board) | ||
| return count | ||
|
|
||
| # начинаем с первого ряда и пустой доски | ||
| return helper(0, [-1] * n) | ||
|
|
||
| print(queen_permutations(7)) | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| def queen_permutations(n): | ||
| def backtrack(row, columns, diag1, diag2): | ||
| """ | ||
| один шаг подсчета расстановок | ||
| :param row: номер ряда, на котором мы фокусируемся | ||
| :param columns: занятые колнки в двоичном числе. 0 - свободно, 1 - занято | ||
| :param diag1: двоичное число диагонали в обозначении ряд + колнка | ||
| :param diag2: двоичное число диагонали ряд - колонка | ||
| :return: количество расстановок с текущего ряда | ||
| """ | ||
| if row == n: | ||
| return 1 | ||
| count = 0 | ||
| # число, обозначающее занятые позиции. в начале это n единиц | ||
| all_positions = (1 << n) - 1 | ||
| # объединяем все недоступные поля (которые биты двоичного числа) | ||
| attacked = columns | diag1 | diag2 | ||
| # убираем из всех единиц недоступные и получаем доступные поля | ||
| available = all_positions & ~attacked | ||
| # выбираем свободные позиции пока такие есть | ||
| while available: | ||
| # самый правый в свободных бит (- меняет все 1 на 0 и дабавляет 1) | ||
| cell = available & -available | ||
| # убираем его из свободных | ||
| available -= cell | ||
| # ищем расстановки с уже занятой этой клеткой для следующего ряда | ||
| count += backtrack(row + 1, columns | cell, (diag1 | cell) << 1, (diag2 | cell) >> 1) | ||
| return count | ||
| # вначале доска пустая | ||
| return backtrack(0, 0, 0, 0) | ||
|
|
||
| if __name__ == "__main__": | ||
| print(queen_permutations(7)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Можно значительно лучше с точки зрения асимптотики