Расчет перестановок занимает слишком много времени - PullRequest
0 голосов
/ 28 июня 2018

Я пытаюсь сгенерировать 20! перестановки и делать некоторые логические операции над ним. Я переключился на многопроцессорность, и с увеличением количества процессов, пропорциональных количеству ядер, производительность увеличивается. Мне удалось время 25 секунд в течение 10! расчеты на 32-х ядерную систему. Моя последняя задача - сделать 20! менее чем за 2 часа я думаю о программировании на GPU. Дайте предложения по подходу, которому я должен следовать

Ответы [ 2 ]

0 голосов
/ 28 июня 2018

Всякий раз, когда я делаю что-либо, что связано с большим количеством перестановок, я думаю о том, как можно избежать повторного вычисления значений, которые я уже вычислил, при генерации перестановок. Одним из таких подходов является использование рекурсии. Используя рекурсию, вы часто можете вычислить первые n возможностей один раз и передать вычисленное значение вперед всем остальным вызовам функций, не пересчитывая его n! раз. Затем следующий вызов функции обрабатывает n-1 возможностей и так далее. Проблема этого подхода заключается в том, что рекурсия сама по себе может добавить довольно большие накладные расходы ко всем вызовам функций и не позволяет компилятору встраивать + применять дальнейшие оптимизации.

Учитывая, что вы говорите, у вас есть n! Перестановки, я бы предположил, что вы, вероятно, переставляет n предметов. Если для создания каждой перестановки требуется некоторое время (это не просто сложение / умножение или что-то в этом роде), вы могли бы подумать о том, чтобы (если возможно) сгенерировать все возможные перестановки k-элементов, то есть k! * (20 выбирают k), все еще намного меньше, чем 20! для малых к. Затем сохраните это в чем-то вроде хеш-таблицы или отсортированного массива, а затем найдите соответствующие значения для всех остальных (20-k)! * (20 выберите k) перестановок. Если вы ищете какое-то оптимальное значение, попробуйте «вычесть» это из каждого запроса в таблицу поиска (снова, если это возможно), если есть запись, то для оптимального значения.

Боюсь, что без дальнейших подробностей о проблеме я не могу предложить больше.

0 голосов
/ 28 июня 2018
10! = 3628800  
20! = 2432902008176640000  
20!/10! = 670442572800  

Если для генерации 10 требуется 25 секунд! перестановки, это потребует около 670442572800 раз 25 сек. Это будет стоить 531490 лет. Пожалуйста, просмотрите ваш вопрос.

...