Предположим, у меня есть набор объектов, S
. Существует алгоритм f
, который при заданном наборе S
строит на нем определенную структуру данных D
: f(S) = D
. Если S
большой и / или содержит совершенно разные объекты, D
становится большим до такой степени, что становится непригодным для использования (т.е. не помещается в выделенную память). Чтобы преодолеть это, я разделил S
на несколько непересекающихся подмножеств: S = S1 + S2 + ... + Sn
и собрал Di
для каждого подмножества. Использование n
структур менее эффективно, чем использование одного, но, по крайней мере, так я могу вписаться в ограничения памяти. Поскольку размер f(S)
растет быстрее, чем сам S
, объединенный размер Di
намного меньше размера D
.
Однако все еще желательно уменьшить n
, то есть количество подмножеств; или уменьшите объединенный размер Di
. Для этого мне нужно разделить S
таким образом, чтобы каждый Si
содержал «похожие» объекты, потому что тогда f
будет создавать меньшую выходную структуру, если входные объекты «достаточно похожи» друг на друга.
Проблема в том, что хотя «сходство» объектов в S
и размере f(S)
действительно коррелирует, нет другого способа вычислить последнее, кроме как просто оценить f(S)
, а f
не совсем быстр .
Алгоритм, который у меня есть в настоящее время, состоит в том, чтобы итеративно добавлять каждый следующий объект из S
в один из Si
, чтобы это привело к наименьшему (на данном этапе) увеличению комбинированного размера Di
:
for x in S:
i = such i that
size(f(Si + {x})) - size(f(Si))
is min
Si = Si + {x}
Это дает практически полезные результаты, но, безусловно, довольно далеко от оптимальных (то есть минимально возможный объединенный размер). Кроме того, это медленно . Чтобы немного ускорить, я вычисляю size(f(Si + {x})) - size(f(Si))
только для тех i
, где x
«достаточно похож» на объекты, уже находящиеся в Si
.
Есть ли стандартный подход к таким проблемам?
Я знаю семейство алгоритмов ветвления и границ, но здесь его нельзя применить, потому что он будет слишком медленным. Я предполагаю, что просто невозможно вычислить оптимальное распределение S
в Si
за разумное время. Но есть ли какой-то общий итеративно улучшающийся алгоритм?
EDIT:
Как отмечалось в комментариях, я никогда не определял "сходство". На самом деле, все, что я хочу, это разбить на такие подмножества Si
, чтобы объединенный размер Di = f(Si)
был минимальным или, по крайней мере, достаточно маленьким. «Сходство» определяется только как это и, к сожалению, просто не может быть легко вычислено. У меня есть простое приближение, но это только то - приближение.
Итак, мне нужен (вероятно, эвристический) алгоритм, который минимизирует sum f(Si)
, учитывая, что существует нет простой способ вычисления последнего - только приближения, которые я использую, чтобы отбрасывать случаи, которые очень маловероятны дать хорошие результаты.