Страницы

Поиск по вопросам

понедельник, 24 февраля 2020 г.

Повторение результата при возведении в степень

#python #алгоритм #python_3x #математика


Как мне вычислить все возведения в степень с x_min ^ y_min по x_max ^ y_max без повторов
результатов. Например: 


x2 ^ x8 = z
...
x85 ^ y23 = p
...
но x85 ^ y28 = z !


Как видно, результат z повторяется у разных вычислений, каким образом можно  пропускать
все следующие вычисления при условии, что сравнивать с ранее вычисленными результатами
не допустимо?

# code python 3
min_x, max_x = 5, 127
min_y, max_y = 2, 250
result = ''
for x in range(min_x, max_x):
    for y in range(min_y, max_y):
        result += str(x ** y)

    


Ответы

Ответ 1



UPDATE: - только что проверил с вашими числами - Python "занимал" около 1GB памяти, timing я обновил для ваших чисел In [105]: x = np.arange(5, 8800, dtype=np.uint64) In [106]: y = np.arange(2, 8250, dtype=np.uint64) In [107]: r = np.unique(np.array([np.power(x, np.repeat([pw], len(x))) for pw in np.nditer(y)])) In [108]: len(''.join(r.astype(str))) Out[108]: 457656 In [109]: %timeit np.unique(np.array([np.power(x, np.repeat([pw], len(x))) for pw in np.nditer(y)])) 1 loop, best of 3: 11.3 s per loop In [115]: np.version.version Out[115]: '1.10.4' numpy solution: x = np.arange(5, 127, dtype=np.uint64) y = np.arange(2, 250, dtype=np.uint64) r = np.unique(np.array([np.power(x, np.repeat([pw], len(x))) for pw in np.nditer(y)])) # чтобы сэкономить память записываем строку в `r` r = ''.join(r.astype(str)) print(r) Timing для 5000 x 5000 массива: In [102]: %timeit np.unique(np.array([np.power(x, np.repeat([pw], len(x))) for pw in np.nditer(y)])) 1 loop, best of 3: 3.89 s per loop In [103]: x.shape Out[103]: (4995,) In [104]: y.shape Out[104]: (4998,)

Ответ 2



Так как основная проблема автора - недостаток ресурсов (или все-таки какая-то абстрактная задачка?), то можно предложить такой выход из положения: не генерировать сразу все-все значения, а написать генератор, который будет выдавать значения тогда, когда это будет нужно. Эти значения ведь все равно где-то будут использованы - будь то запись в файл или какие-нибудь операции над получившимся вектором - и использованы они будут по-одному. def give_me_square(): first = range(5, 8800) second = range(2, 9000) for i in first: for j in second: yield i**j counter = 0 total = 8800*9000 for square in give_me_square(): if counter % 10000 == 0: print(counter, "of", total) counter += 1 Работает совсем нешустро, зато память не ест. Такой генератор можно сделать асинхронным, можно отдать его в multiprocessing.Pool.map, много чего можно придумать.

Комментариев нет:

Отправить комментарий