Re[3]: Параллельный статистический алгоритм решения задачи о сумме подмножества
От: virusmxa  
Дата: 12.06.13 13:59
Оценка:
Здравствуйте, maxkar, Вы писали:

M>Ну... В таком виде он не нужен. Совсем и полностью. SubsetSumSolver, строки 48-56. Вопрос: раз уж вы динамику применяете, почему бы на ней все и не сделать? Ответ она тоже умеет строить, это несложно. Если усложнить, ей же можно и все ответы построить.


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

M>Кроме того, замечены:

M> * Совершенно ненужные наследования (BitVector, Combination, CombinationSequence, SubsetSizesSequence). Первый вообще не нужен, можно в BitMatrix нужные методы сделать. Длину можно там же хранить. Второй заменяется на обычный construction method. Остальные 2 зачем-то от AbstractCollection наследуются. Хотя достаточно было бы Iterable реализовать.

BitVector, BitMatrix, CombinationSequence реиспользовал, в этой задаче с рефакторингом не заморачивался.

M> * Нарушения контрактов при наследовании (CombinationsSequence.iterator.next() — точно). Там же и еще в SubsetSizesSequence несогласован интерфейс size и размер iterable...

M> * Неоптимальный toString в BitVector

Спасибо за толковые замечания

M>А какого порядка там суммы были и с какой точностью? Если это порядка 10-ка тысяч рублей (и считать в копейках), та же динамика будет работать быстро (секунды). До сотен тысяч — пару минут. С учетом практичности данной задачи ее как раз стоит решать обычным динамическим программированием. Если не торопясь, за час вместе с прогоном и отладкой можно управиться. Ваш код писался явно гораздо дольше, его сложнее отлаживать (многопоточность) и при этом в качестве базы ту же динамику использует. Не окупаются затраты. Окупятся, только если subset sum problem решать десятками, сотнями и тысячами в один день. Может быть, при этом имело бы смысл параллелить динамику (она параллелится, но достаточно хитро и сложно), а не перебор.


Суммы были 100 — 1000 рублей, динамика с извлечением результирующего подмножества была бы в тему, только как?
Ещё можно параллелить перебор сочетаний, если погрешность мощности подмножества достаточно мала. Вычислительная сложность максимальная, когда мощность подмножества составляет половину от мощности исходного набора. В этом случае можно попытаться суммировать элементы в группы и применять алгоритм к группам.

M>P.S. CombinationsSequence.lg2(_sum) > 31 никогда не будет true, так как _sum — int.


Согласен. В первом варианте числа были в long, сопли остались
Спасибо за анализ!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.