Форум сайта python.su
Добрый день!
Только начал изучать алгоритмы. Для закрепления решаю задачи на сайте.
Написал код для генерации перестановок по алгоритму Хипа.
Код ниже проходит все тесты без ошибок, но выдает превышение времени выполнения.
Прошу Вас подсказать, как можно ускорить этот код. Что можно почитать для самостоятельного изучения этой темы?
Всем Большое Спасибо!
def permutations(string): a = list(string) lst = [] return generate_arr(a, len(a), lst) def generate_arr(lst, k, arr): if k == 1 and ''.join(lst[:]) not in arr: arr.append(''.join(lst[:])) else: for i in range(k): generate_arr(lst, k - 1, arr) if k % 2 == 0: lst[i], lst[k-1] = lst[k-1], lst[i] else: lst[0], lst[k-1] = lst[k-1], lst[0] return arr string = 'baab' print(permutations(string))
Офлайн
artemu88Тебе надо представить просто, как эти тесты проводятся. Вот он берёт и подаёт туда миллион элементов в списке. Ты этого не делал, а он взял и сделал. Соответственно, все твои копирования списков через срезы дадут большой прирост и по памяти, и по времени. То же самое относится к формированию строк внутри функции. Каждое формирование строки занимает много времени, потому что строки занимают больше места в памяти, чем числа.
Прошу Вас подсказать, как можно ускорить этот код.
>>> import sys >>> >>> sys.getsizeof(1) 28 >>> sys.getsizeof('1') 50 >>> >>> sys.getsizeof(123) 28 >>> sys.getsizeof('123') 52 >>> >>> sys.getsizeof(123) + sys.getsizeof(456) 56 >>> sys.getsizeof('123') + sys.getsizeof('456') 104 >>>
Отредактировано py.user.next (Фев. 12, 2023 15:25:32)
Офлайн
py.user.nextСогласен, можно сделать и при помощи модуля itertools, но интересно самому реализовать алгоритм и понять его.
множество кодов этой генерации, где нет никаких списков, где их вообще не надо делать в функции.
Офлайн
artemu88Без itertools там есть алгоритмы. Полинтернета этих алгоритмов есть, уже реализованных. Ты же не первый, кто этот алгоритм пытается написать. Там тысячи таких учеников, которые писали и написали.
можно сделать и при помощи модуля itertools
Офлайн
Спасибо! Пойду мучить Поиск
Офлайн
py.user.nextвот к примеру даже, набрал запрос в поисковике, там выдало сайты, в несколько заглянул мельком, там примеры с рекурсией
Полинтернета этих алгоритмов есть, уже реализованных.
def heap_permutation(data, n): if n == 1: yield data else: for i in range(n - 1): yield from heap_permutation(data, n - 1) if n % 2 == 0: data[i], data[n - 1] = data[n - 1], data[i] else: data[0], data[n - 1] = data[n - 1], data[0] yield from heap_permutation(data, n - 1) # пример использования data = [1, 2, 3] for permutation in heap_permutation(data, len(data)): print(permutation)
Отредактировано xam1816 (Фев. 12, 2023 18:36:59)
Офлайн
xam1816
вот к примеру даже, набрал запрос в поисковике, там выдало сайты, в несколько заглянул мельком, там примеры с рекурсией
и этот же запрос в чате выдал результат
>>> def f(n): ... if n > 0: ... yield from f(n - 1) ... yield n ... >>> list(f(10)) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] >>> >>> list(f(1000)) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 3, in f File "<stdin>", line 3, in f File "<stdin>", line 3, in f [Previous line repeated 993 more times] File "<stdin>", line 2, in f RecursionError: maximum recursion depth exceeded in comparison >>>
>>> def heap_permutation(data, n): ... if n == 1: ... yield data ... else: ... for i in range(n - 1): ... yield from heap_permutation(data, n - 1) ... if n % 2 == 0: ... data[i], data[n - 1] = data[n - 1], data[i] ... else: ... data[0], data[n - 1] = data[n - 1], data[0] ... yield from heap_permutation(data, n - 1) ... >>> list(heap_permutation([1, 2, 3, 4, 5, 6, 7, 8, 9, 10] * 100, 1000)) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 6, in heap_permutation File "<stdin>", line 6, in heap_permutation File "<stdin>", line 6, in heap_permutation [Previous line repeated 992 more times] File "<stdin>", line 5, in heap_permutation RecursionError: maximum recursion depth exceeded in comparison >>>
Отредактировано py.user.next (Фев. 13, 2023 22:06:14)
Офлайн
Решил отсавить решение тут, вдруг кому пригодится:
def swap(a, b, c): ''' функция для обмена значениями двух элемонтов списка ''' a[b], a[c] = a[c], a[b] return a def permute(s, j, a): ''' функция для генерации перестановок ''' if j == len(s): a.append(''.join(s)) else: for i in range(len(s[:j+1])): s = swap(s, j, i) permute(s, j + 1, a) s = swap(s, j, i) return a def permutations(s): ''' основна функция ''' s = list(s) a = [] return list(set(permute(s, 0, a)))
Отредактировано artemu88 (Фев. 15, 2023 08:01:16)
Офлайн