раздел списка с использованием динамического программирования

Я опубликовал немного здесь, связанный с проектом, над которым я пытался работать, и я продолжаю сталкиваться с проблемами дизайна, и мне приходится проектировать с нуля. Поэтому мне интересно, могу ли я опубликовать то, что я пытаюсь сделать, и кто-нибудь может помочь мне понять, как я могу получить желаемый результат.

Общие сведения:

Я новичок в программировании и пытаюсь учиться. Поэтому я взялся за интересующий меня проект, который включает в себя получение списка и разбивку каждого числа, используя только числа из списка. Я знаю, что мог бы легко переборщить это (что я и сделал), но я также хотел изучить Hbase, Hadoop и параллельную обработку, поэтому я хотел сделать это таким образом, чтобы я мог разбить процесс на разных машинах. Я думал, что способ сделать это — использовать динамическое программирование и рекурсии для создания таблицы возможностей, которую можно было бы разбить еще дальше.

Пример:

Если я отправлю список: [1,2, 4] я должен получить {1: [[1]], 2: [[1, 1]], 4: [[2, 2]]}. В основном это говорит о том, что 2 + 2 = 4, 1 + 1 = 2 и 1 = 1 ... поэтому, пытаясь увидеть все способы сделать 4, я могу просто просмотреть этот список (который будет в базе данных) и см. 2 + 2 = 4, затем разбить 2 ... и так далее .. У меня работает поиск, но с разбивкой у меня проблемы. Использование грубой силы не позволит мне использовать большие числа (скажем, миллион с тысячей чисел в списке) таким образом, чтобы я мог использовать Hadoop или какой-либо другой инструмент для их масштабирования. Вот еще несколько примеров возможных результатов:

[1,2, 3, 4] = {1: [[1]], 2: [[1, 1]], 3: [[1, 2]], 4: [[1, 3], [2, 2]]}
[1,2, 3, 4, 6, 10] = {1: [[1]], 2: [[1, 1]], 3: [[1, 2]], 4: [[1, 3], [2, 2]], 6: [[2, 4], [3, 3]], 10: [[4, 6], [2, 2, 2, 2, 2]]}
[10, 30, 50] = 50: [[10, 10, 30]], 30: [[10, 10, 10]]}

Логика этого подхода заключается в том, что для вычисления следующих возможных данных в списке не потребуется время, поэтому, если я отправлю список с миллионом чисел, он может сделать это быстро и даже масштабироваться до кластера хаупов.

Код, который я создал, чтобы заставить это работать, находится здесь Но этот вопрос был о том, как исправить проблему дизайна. Я получил совет, что это проблема с разделами, и осмотрелся и нашел гораздо более простые версии того, что я пытался сделать ( activestate ), но это не совсем то, что я пытаюсь сделать, потому что он разбивает число и не использует для этого определенный набор данных.

Вопрос:

Итак, надеюсь, я ясно описал, что я пытаюсь сделать. Что мне нужно прочитать/изучить/узнать, чтобы создать таблицу раздела списка в python с использованием динамического программирования, чтобы он мог масштабироваться? Это просто хобби и не зависит от времени, но я чувствую, что работаю над этим более 3 месяцев, и каждый раз я сталкиваюсь с проблемами дизайна, которые заставляют меня начинать с нуля. Как я могу построить это правильно (чтобы увидеть мой неправильный способ, см. мою ссылку выше)? Я погуглил и нашел решения проблемы с рюкзаком и проблем с разделами, но они, похоже, больше подходят для школьной работы и на самом деле не предназначены для масштабирования с большими наборами данных.

Надеюсь, кто-то может дать мне представление, но, тем не менее, спасибо за чтение этого.


person Lostsoul    schedule 06.10.2011    source источник


Ответы (1)


Вы должны знать, что задачи DP сами по себе не оптимальны для независимых и распределенных вычислений.

Когда вы рассматриваете классические формы алгоритмов DP, у вас есть матрица/таблица/массив, и вы последовательно вычисляете новые значения в определенном порядке. Каждое вычисление значения требует других значений, которые должны быть созданы ранее. Следовательно, вы теряете независимость от данных и можете одновременно вычислять максимальное количество полей массива, в зависимости от конкретных алгоритмов DP. Например, многие алгоритмы DP могут обрабатывать весь столбец таблицы параллельно, поскольку каждое поле зависит от полей из предыдущего столбца. Но это уже предел из-за зависимости от данных всех оставшихся полей после этого столбца.

При этом вычисление возможных сумм различных чисел, доступных в вашем списке, НЕ является проблемой DP. Вы вообще не решаете никаких подзадач, а просто собираете все возможные суммы (если они совпадают с одной из записей вашего списка).

Поэтому я предлагаю следующий несколько иной подход:

  • Вычислите новый список со всеми возможными суммами. Это не зависит от данных и может быть распараллелено, но вам нужна некоторая верхняя граница для завершения. Пример: [1,2,4] становится [ [1],[2],[4],[1,1],[1,2],[1,4],...]. Вам не нужно явно создавать этот список, а просто передавать каждую такую ​​комбинацию на следующий шаг.
  • Оцените каждое вычисление, т.е. создайте сумму и проверьте, соответствует ли она значению из исходного списка. Опять же, вы не зависите от данных и можете выполнять все эти вычисления самостоятельно.
  • Объедините положительные результаты в окончательную структуру данных.

Итак, подведем итоги и ответим на ваши вопросы:

  • Подумайте, хотите ли вы вообще расценивать эту проблему как ДП.
  • Вы можете прочитать о параллелизме данных. Это особенно актуально при решении подобных задач с GPU, поэтому может оказаться полезной и соответствующая литература по CUDA/OpenCL.
person Frank    schedule 06.10.2011
comment
Большое спасибо, что нашли время ответить на этот вопрос, Фрэнк. Я думал, что динамическое программирование в основном помогло мне сгенерировать предварительно вычисленную таблицу на основе, но я подумал об этом и подумал, что, может быть, мне не нужно давать динамической функции весь список, может быть, я мог бы разбить список, чтобы он обрабатывался несколько независимо. Например, 4 может разбиваться на [2,2], а 2 может быть [1,1], но мне не нужно делать это на одном процессоре, поскольку они кажутся независимыми. Кроме того, чтобы сэкономить процессорное время, я не вычислял весь список, а думал только о следующей переменной. - person Lostsoul; 06.10.2011
comment
Я не совсем понимаю ваше решение, хотя. Я видел, как другие (говоря о DP) также показывали мне подобную таблицу, но что означает [1,4]? 1 может произвести 4? Если да, то как бы он решил число 5, используя список [1,2,4].. правильный ответ должен быть [4 + 1], но я не уверен, как создать список, чтобы получить этот результат. - person Lostsoul; 06.10.2011
comment
В этом подходе [1,4] является частью вашего решения в том смысле, что оно читается как 1+4, составляющее 5. Обратите внимание, что первый шаг только создает различные возможные суммы, но еще не заботится о значении этой суммы. - person Frank; 07.10.2011
comment
о, хорошо, правильно ли я понимаю, что я создаю столбец с 5, а затем со значением [1,4] и т. д., поэтому я просто ищу 5 в своей таблице, а затем получаю это значение? - person Lostsoul; 07.10.2011
comment
Lostsoul, не забудь принять лучший ответ. Я почти уверен, что ответ @Frank будет лучшим... - person steveha; 07.10.2011
comment
@steveha Я только что принял это. Его ответ был очень полезным. - person Lostsoul; 08.10.2011