Помогите мне ускорить мой код/алгоритм Python
Я новичок как в языке, так и в алгоритмах, чувствительных к производительности, так что до сих пор это было действительно сложно, и я думаю, что это хорошо.
Так или иначе, задача была следующая:
У меня есть x сумма (в данном случае 24) буквы и список слов.
Я должен был найти все это. сочетание слов("предложения"), которые используют данные буквы с помощью ни одного письма не осталось.
Обновление: Слово может появиться в предложении более одного раза, например "the the the" - это прекрасно, если буквы позволяют это сделать.
Например:
вход:
данное письмо:
IFSNIHLSTA
И список слов:
nice guys finish last
(Максимальное количество слов, которое мы ищем, в данном случае не имеет значения.)
Выход есть:
finish last last finish
Я почти уверен, что есть некоторые существующие алгоритмы, которые я мог бы использовать, но на данный момент я не знаю ни одного, поэтому я решил написать один с нуля, и, как вы можете догадаться, он оказался настолько медленным, что его невозможно использовать.
Что я уже пробовал:
То самое первое, что делать было очевидно, чтобы сократите количество слов во-первых, поэтому я отфильтровал те, которые точно не нужны.
Затем первый основная идея он должен был взять слово, использовать буквы для него, затем взять следующее слово и использовать оставшиеся буквы, и так далее, пока все буквы не будут израсходованы, или больше слов не может быть создано. Если все буквы израсходованы, то ура, мы получили предложение.
Повторение вышеописанного процесса для всех слов и снова для каждого слова(после действительного) в конце концов даст нам все комбинации, верно?
То проблема с ним это скорость, поиск предложений, содержащих одно слово, потребует повторения списка один раз, однако два предложения слов потребуют еще одной итерации после каждого слова в худшем случае, и если мы ищем предложения из 6 слов, то о боже... вы поняли идею.
Поэтому я искал способы сделать его достаточно эффективным, чтобы его можно было использовать (если бы я добился успеха, я бы не писал это):
Я решил, что, поскольку я ищу только комбинации, порядок не имеет значения, поэтому у меня гораздо меньше слов для начала (если я ищу предложения из 6 слов, то мне нужно смотреть только на 1/6 слов для первой итерации).
Реализация это действительно спагетти-код, так как еще день назад я даже не знал, как выглядит python, извините за это.
В любом случае он следует логике, написанной выше, с той разницей, что он разбивает слова на части и запускает процесс для каждого ядра процессора.
Так как это около 200 строк, я положил его на pastebin вместо того, чтобы вставить его сюда:
Код на Pastebin[^]
У меня есть 2 вида вопросов:
Теоретический:
Как улучшить алгоритм или какие другие алгоритмы использовать, которые могли бы быть более эффективными? (и еще, что я упускаю?)
Обновление: В выходных данных все еще есть несколько дубликатов, и мне нужно будет найти способ их удалить.
О самом спектакле:
Несмотря на то, что каждый процесс работает на собственном потоке процессора, и нет никакого дискового ввода-вывода, процессоры не используются на 100%, почему бы и нет?
Кроме того, продвинулся бы я дальше с CUDA или openCL, если да, то как?
Заранее спасибо
Patrice T
Покажите пример ввода/вывода.
fecka97
Пример, который я только что собрал:
Ввод:
Даны буквы: "IFSNIHLSTA"
И список слов:
милый
парни
заканчивать
последний
(Максимальное количество слов, которое мы ищем, в данном случае не имеет значения.)
Выход есть:
- финишируй последним"
"последний финиш"
Эти слова вместе используют точные данные буквы.
Я тоже собираюсь обновить этот вопрос.
Patrice T
насколько велик список слов?
Используется ли он повторно или каждый раз новый список?
При повторном использовании вы можете хранить дополнительную информацию с помощью слов?
fecka97
Я каждый раз использую список "всех" английских слов, который составляет около ~500 тысяч слов, но он фильтруется в начале в зависимости от букв, обычно это максимум 9-10 тысяч слов, Чем меньше букв, тем меньше слов мне придется работать. Я повторяю этот же отфильтрованный список для каждого слова.
Сейчас это просто список(или массив, если хотите) строк, но хранение большего количества данных со словами не должно быть проблемой.
Кроме того, я забыл упомянуть, что одно слово может встречаться в предложении более одного раза, так что "the the the" может быть абсолютно возможным, если буквы позволяют это сделать.
Также в текущей версии дубликаты являются проблемой, например "asd bsd csd" и "asd csd bsd" считаются дубликатами. Увеличение количества просматриваемых слов (... listSize/3, listSize/2, listSize/1) решило бы эту проблему, но это не сработает, если максимальное количество слов для предложения неизвестно, и это не позволит одному и тому же слову появиться более одного раза.
Patrice T
Воспользуйся Улучшить вопрос чтобы обновить ваш вопрос.
Чтобы каждый мог обратить внимание на эту информацию.
fecka97
Спасибо, я уже сделал это.