Ответ 1
Никакой алгоритм действительно не должен "вписываться в память" - вы всегда можете вставлять страницы туда и сюда по мере необходимости. Но вы не хотите, чтобы вычисления выполнялись неоправданно долго, а глобальное разбиение графов в общем случае представляет собой NP-полную проблему, которая является "необоснованно длинной" для большинства проблем, которые даже не вписываются в память.
К счастью, вы хотите выполнить поиск по ширине, что означает, что вы хотите формат, в котором вначале это простое вычисление. Я не знаю никаких алгоритмов, которые делают это, но вы можете создать свой собственный макет ширины, если вы готовы разрешить немного дополнительного дискового пространства.
Если ребра не смещены в сторону локальных взаимодействий, то распутать граф будет сложно. Если они предвзяты к локальным взаимодействиям, я предлагаю такой алгоритм, как:
- Выберите случайный набор вершин в качестве отправных точек из всего набора данных.
- Для каждой вершины собирайте все соседние вершины (выполняется одна прокрутка по набору данных).
- Для каждого набора соседних вершин собирайте множество соседей-соседей и оценивайте их в соответствии с тем, сколько ребер связано с ними. Если у вас нет места на странице, чтобы сохранить их все, сохраните наиболее связанные вершины. Если у вас есть место, чтобы сохранить их все, вы можете захотеть выбросить наименее полезные (например, если фракция ребер, содержащихся в пределах страницы/доли вершин, требующих коэффициента хранения, падает "слишком низко" - где "слишком мало", будет зависеть от того, насколько сильно нужны ваши поиски, и можете ли вы сделать обрезку и т.д. - тогда не включайте тех, кто находится по соседству.
- Повторите процесс сбора и ранжирования соседей, пока ваш район не будет заполнен (например, заполняет какой-то размер страницы, который вам подходит). Затем проверьте повторы между случайно выбранными запусками. Если у вас есть небольшое количество вершин, появляющихся в обоих случаях, удалите их из одного или другого, в зависимости от того, что нарезает меньше ребер. Если у вас есть большое количество вершин, появляющихся в обоих, сохраните окрестности с наилучшим соотношением (вершины в окрестности/сломанной кромке) и выбросьте другую сторону.
Теперь у вас есть некоторые локальные окрестности, которые примерно локально оптимальны в том, что поиск по ширине обычно падает внутри. Если ваш поиск по ширине практически неэффективен, то это, вероятно, достаточно хорошо. Если нет, вы, вероятно, захотите, чтобы соседние районы группировались.
Если вам не нужны соседние районы для слишком большого кластера, вы отложите вершины, которые вы сгруппировали в окрестности, и повторите процесс по оставшимся данным до тех пор, пока не будут учтены все вершины. Вы меняете каждый идентификатор вершины на (вершину, окрестности), и все готово: при следующих краях вы точно знаете, какую страницу захватывать, и большинство из них будут близки по заданной конструкции.
Если вам понадобятся соседние районы, вам нужно будет отслеживать растущие кварталы. Вы повторяете предыдущий процесс (выбирайте наугад, выращивайте окрестности), но теперь оценивайте соседей как по количеству ребер, которые они удовлетворяют внутри окрестности, так и по какой части их ребер, покидающих окрестности, находятся в существующей группе. Вам могут потребоваться весовые коэффициенты, но что-то вроде
score = (# edges within) - (# neighborhoods outside) - (# neighborhoodless edges outside)
вероятно, сделает трюк.
Теперь это не глобально или даже локально оптимально, но это или что-то очень похожее должно дать хорошо локально связанную структуру и должно позволить вам создать покрывающий набор окрестностей, которые имеют относительно высокую взаимосвязь.
Опять же, это зависит от того, будет ли ваш поиск в черно-белом разрезе ветвями или нет. Если это так, недорогая вещь - максимизировать локальную взаимосвязь. Если дело не в том, чтобы свести к минимуму внешние подключения, и в этом случае я бы предложил просто собрать широкие настройки до некоторого размера и сохранить их (с дублированием по краям наборов - вы "Не сильно ли ограничено пространством на жестком диске, не так ли?).