Основываясь на описании проблемы, которую вы предоставили, и ответах, которые вы предоставили в комментариях, я думаю, что самый простой способ сделать это может заключаться в использовании такого подхода, как описанный описанный @dreamzor. (
)
Основная идея состоит в том, чтобы преобразовать данные в более сжатый формат, который вписывается в память, запускать алгоритм регулярных подключенных компонентов для этих данных, а затем распаковывать его. Обратите внимание, что если вы назначаете каждый узла 32-разрядный цифровой идентификатор, тогда общее пространство, необходимое для хранения всех узлы не более чем на четыре миллиарда узлов и восемь миллиардов краев (при условии, что вы храните две копии каждого края), что составляет пространство для двенадцати миллиардов 32-разрядных целых чисел, всего около 48 ГБ пространства, ниже вашего порога памяти.
Для начала напишите сценарий, который читает в файле edge, назначает числовой идентификатор каждому узлу (возможно, последовательно в том порядке, в котором они появляются). Попросите этот сценарий записать это сопоставление в файл и, как говорится, напишите новый файл ребер, который использует числовые идентификаторы узлов, а не имена строк. Когда вы закончите, у вас будут идентификаторы сопоставления имен имен для имен и файл ребер, занимающий гораздо меньше места, чем раньше. Вы упомянули в комментариях, что вы можете поместить все имена узлов в память, поэтому этот шаг должен быть очень разумным. Обратите внимание, что вам не нужно хранить все ребра в памяти - вы можете передавать их через программу - так что это не должно быть узким местом.
Далее, напишите программу, которая считывает файл ребер, но не файл имен, в память и находит подключенные компоненты с использованием любого разумного алгоритма (BFS или DFS здесь будет замечательно).Если вы будете осторожны с вашей памятью (использование чего-то типа C или C++ здесь будет хорошим вызовом), это должно удобно вписываться в основную память. Когда все будет готово, выпишите все кластеры во внешний файл с помощью числового идентификатора. Теперь у вас есть список всех CCs по ID.
Наконец, напишите программу, которая читает в идентификаторе сопоставление узлов из файла имен, затем передает в идентификаторы кластера и записывает имена всех узлов в каждом кластере в конечный файл.
Этот подход должен быть относительно прост в реализации, поскольку ключевая идея состоит в том, чтобы сохранить существующие алгоритмы, к которым вы привыкли, но просто измените представление графика, чтобы быть более эффективным с точки зрения памяти. Раньше я использовал такие подходы, когда занимался огромными графиками (Wikipedia), и он прекрасно работал даже на системах с меньшим объемом памяти, чем ваш.
Сколько у вас вершин? – dreamzor
@ dreamzor Около 2 миллиардов. – eleanora
Я полагаю, вам нужны простые компоненты связи, а не «сильно», так как граф неориентирован? – dreamzor