Анализ различных сетов и оптимизации. Лучший подход?

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

Сценарий:

Во-первых, у нас есть объект, который мы назовем Individual и который содержит следующие свойства:

  1. Свидание
  2. Пара долгота-широта

Во-вторых, у нас есть еще один объект, который мы назовем Группа. Его определение таково: набор лиц, которые вместе соответствуют следующим условиям:

  • Все особи в наборе имеют даты, которые друг в друге не превосходят 10 дней. Это означает, что все Индивидуумы, если их сравнивать друг с другом, не отличаются друг от друга на 10 дней.

  • Расстояние между каждым объектом меньше Y метров.

Группа может состоять из N>1 индивидуумов, если каждый из индивидуумов соответствует условиям друг друга. Все лица хранятся в базе данных. Все группы также будут храниться в базе данных.

Задача:

Теперь рассмотрим нового человека. Система должна проверить, если новый человек:

  1. Принадлежит к существующей группе или группам

  2. Индивидуум теперь формирует одну или несколько новых групп с другими индивидуумами.

Примечания:

  • Новый человек может состоять в нескольких существующих группах или может создать несколько новых групп.

  • Подгруппы отдельных лиц не допускаются, например, если у нас есть группа, содержащая отдельных лиц {A,B,C}, не может существовать группа, содержащая {A,B}, {A,C} или {B,C}.

Решение (ограничено по времени обработки и памяти)

Во-первых, мы фильтруем базу данных со всеми лицами, которые соответствуют начальным условиям. Это выведет перечисляемое FilteredIndividuals, содержащее всех людей, которые, как мы знаем, образуют группу (из 2) с новым.

Вкратце, Powerset — это набор, содержащий все возможные подмножества определенного набора. Например, набор мощности {A,B,C} будет следующим: {[пусто], A, B, C, AB, AC, BC, ABC}

Примечание. Powerset выведет новый набор из 2^N комбинаций, где N — длина исходного набора.

Идея использования powersets заключается в следующем:

  • Во-первых, мы создаем powerset списка FilteredIndividuals. Это даст все возможные комбинации групп в списке FilteredIndividuals. Для целей анализа и по определению мы можем опустить все комбинации, в которых содержится менее 2 индивидуумов.

  • Мы проверяем, соответствует ли каждое из Индивидуумов в комбинации набора мощности условиям друг друга. Если они совпадают, это означает, что все Индивидуумы в этой комбинации образуют Группу с новым Индивидуумом. Затем, чтобы избежать подгрупп, мы можем исключить все подмножества, содержащие комбинации отмеченной комбинации. Я делаю это, создавая набор мощности из проверенной комбинации, а затем удаляя новый набор мощности из исходного.

  • На данный момент у нас есть список наборов, соответствующих условиям для формирования группы.

Перед формальным созданием группы я сравниваю БД с другими существующими группами, которые содержат те же элементы, что и новые наборы: если я нахожу совпадение, я исключаю вновь созданный набор и добавляю нового индивидуума в старую группу. Если я не нахожу совпадений, это означает, что это новые группы. Итак, я добавляю нового человека в наборы и, наконец, создаю новые группы.

Это решение хорошо работает, когда перечисляемый объект FilteredIndividuals содержит менее 52 отдельных лиц. После этого выбрасываются исключения памяти (я знаю, что это из-за максимального размера, разрешенного для типов данных, но увеличение такого размера не помогает с очень большими наборами. На ваше усмотрение, максимальное количество индивидуумов, соответствующих условиям, я' найдено 345).

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

Я использую .NET framework с C#, но если язык требует изменения, мы можем согласиться с этим, если позже сможем преобразовать результаты в объекты, понятные нашей основной системе.


person RainierMallol    schedule 27.07.2016    source источник
comment
Все особи в наборе имеют дату, которая внутри друг друга не превосходит Х дней - о чем вы? Друг в друге? Не выше X дней? Эти слова не имеют смысла, собранные таким образом в данном контексте.   -  person user2357112 supports Monica    schedule 27.07.2016
comment
Я углубился в подробности @user2357112 Спасибо за внимание!   -  person RainierMallol    schedule 27.07.2016
comment
Думаю, я не понимаю цели: удержание набора мощности становится (слишком) дорогим — но какова цель в первую очередь? Powerset без правильных подмножеств?   -  person greybeard    schedule 06.09.2016
comment
@greybeard Он предназначен для создания групп отдельных лиц без реплик или подгрупп и при условии, что отдельные лица будут анализироваться в порядке FIFO.   -  person RainierMallol    schedule 06.09.2016
comment
[goal is] to create "Groups" of "Individual", with [constraints met] - именно то, что я не понимаю/принимаю: какая польза от Group? Какие операции должны поддерживать? FIFO 1-й пришел, 1-й ушел? Фиксированные верхние/нижние пределы размера? Или FCFS – первый пришел, первым обслужен/обработан?   -  person greybeard    schedule 06.09.2016
comment
Группы являются требованиями бизнес-логики. Они являются таблицей в базе данных и после их создания служат для другой цели. FCFS — это аббревиатура, более подходящая для этой проблемы.   -  person RainierMallol    schedule 10.09.2016
comment
Если у вас есть A, B, C, и D с {A, B}, {B, C}, {C, D} и {D, A} расположены достаточно близко друг к другу, чтобы быть в группах, как показано, но не в группах, содержащих более двух из A, B, C, D (подумайте о квадрате с |side|=Y), подходит ли любая комбинация групп, состоящая из всех членов, или требуются все группы? (Все еще пытаясь выяснить, может ли разница быть больше, чем фактор 4.)   -  person greybeard    schedule 10.09.2016
comment
Пока ВСЕ лица в группе соответствуют критериям, группы должны быть созданы или изменены. AB BC CD DA В этом сценарии будут созданы четыре группы. Если бы, например, совпало и DB, это означало бы, что при вставке D необходимо было бы выполнить модификацию группы AB, преобразовав ее в ABD. У нас не может быть подгрупп, а это означает, что если ABD существует, то AB и DB не должны.   -  person RainierMallol    schedule 10.09.2016
comment
Каков масштаб этой задачи? То есть, сколько человек он должен обрабатывать и сколько групп?   -  person RBarryYoung    schedule 10.09.2016
comment
Кроме того, дата - это только дата или дата-время?   -  person RBarryYoung    schedule 10.09.2016
comment
Он должен обрабатывать людей, когда они входят в систему. Нет фиксированной шкалы. Мы используем тип данных Datetime. Но все наши расчеты основаны и должны основываться на количестве дней.   -  person RainierMallol    schedule 11.09.2016
comment
Спасибо @greybeard   -  person RainierMallol    schedule 11.09.2016
comment
Добавление вашего имени, чтобы вы могли видеть это @RBarryYoung   -  person RainierMallol    schedule 11.09.2016
comment
Каков верхний предел? Если вы хотите, чтобы орблема поместилась в памяти, мы должны знать, насколько она велика и сколько у вас памяти.   -  person RBarryYoung    schedule 11.09.2016
comment
32 ГБ оперативной памяти, несколько терабайт дискового пространства. @RBarryYoung   -  person RainierMallol    schedule 12.09.2016


Ответы (1)


Все особи в наборе имеют даты, которые друг в друге не превосходят 10 дней. Это означает, что все Индивидуумы, если их сравнивать друг с другом, не отличаются друг от друга на 10 дней. Расстояние между каждым объектом меньше Y метров.

Таким образом, ваша проблема заключается в том, как сгруппировать эти точки в трехмерном пространстве, разделении где X и Y — ваши широта и долгота, Z — координата времени, а ваша метрика — это соответствующим образом масштабированный вариант Манхэттенское расстояние. В частности, вы масштабируете Z так, чтобы 10 * Z дней равнялись вашему максимальному расстоянию в Y метров.

Одним из возможных способов быстрого решения может быть использование разделяй и властвуй и классифицируй свои баллы (отдельные) по сегментам, шириной Y метров и высотой 10 дней. Вы делаете это, разделив их координаты на Y и на 10 дней (для этого вы можете использовать юлианские даты). Если особь находится в корзине H { X=5, Y=3, Z=71 }, то это не может быть чем любая особь в корзинах с X ‹ (5-1) или X > (5 +1), Y ‹ (3-1) или Y > (3+1), или Z ‹ (71-1) или Z > (71+1), находится в той же группе, потому что их расстояние было бы конечно быть выше порога. Это означает, что вы можете быстро выбрать подмножество из 27 «сегментов» и работать только с ними.

На этом этапе вы можете перечислить возможные группы, в которые может входить ваш новый человек (если вы используете серверную часть базы данных, они будут SELECT groups.* FROM groups JOIN iig USING (gid) JOIN individuals USING (uid) WHERE individuals.bucketId IN ( @bucketsId )), и сравнить их с группой, которую ваш человек может сформировать из других людей (SELECT individuals.id WHERE bucketId IN ( @bucketsId ) AND ((x-@newX)*(x-@newX)+(y-@newY)*(y-@newY)) < @YSquared AND ABS(z - @newZ) < 10)).

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

В некоторых базах данных с географическими расширениями вы можете захотеть использовать собственные функции широты и долготы вместо неявного преобразования в метры.

person LSerni    schedule 05.09.2016
comment
Привет @Iserni, твой ответ приносит то, о чем мы подумали, но отбросили из-за ограниченных математических и геометрических знаний. Я собираюсь быть более честным, чем следовало бы здесь, но я признаю, что мне трудно понять ваш ответ на первый взгляд, и мне придется прочитать его более одного раза, а также прочитать ссылки, которые вы добавили в ответ. . Еще один вопрос, готовы ли вы принять оплату, чтобы правильно решить эту проблему? Я бы, конечно, дал вам более подробную информацию о проблеме и обо всем, прежде чем принять. Если вы заинтересованы, свяжитесь со мной по адресу rainiermallol[at]gmail[dot]com. - person RainierMallol; 06.09.2016
comment
Скажем, n - это порядок величины точек, которые вы рассматриваете. Во-первых, разделите свое пространство на пол (sqrt (n)) равных частей. Каждое ваше очко попадает ровно в один из этих квадратов, и в среднем на каждый квадрат приходится одно очко. Если ваши очки не распределены в пространстве случайным образом, вы можете изменить это, чтобы учесть ваше распределение. Теперь каждый раз, когда вы добавляете точку P, вам нужно только проверять точки в квадратах, которые могут находиться в пределах Y метров от P. - person Dave; 07.09.2016