Как эффективно хранить матрицу с сильно избыточными значениями - PullRequest
17 голосов
/ 23 июня 2010

У меня очень большая матрица (100M строк на 100M столбцов), в которой много повторяющихся значений рядом друг с другом.Например:

8 8 8 8 8 8 8 8 8 8 8 8 8
8 4 8 8 1 1 1 1 1 8 8 8 8
8 4 8 8 1 1 1 1 1 8 8 8 8
8 4 8 8 1 1 1 1 1 8 8 8 8
8 4 8 8 1 1 1 1 1 8 8 8 8
8 4 8 8 1 1 1 1 1 8 8 8 8
8 8 8 8 8 8 8 8 8 8 8 8 8
8 8 3 3 3 3 3 3 3 3 3 3 3

Я хочу, чтобы структура данных / алгоритм хранили такие матрицы как можно более компактно.Например, вышеприведенная матрица должна занимать только пространство O (1) (даже если матрица была растянута произвольно большой), потому что существует только постоянное количество прямоугольных областей, где каждая область имеет только одно значение.

Повторение происходит как по строкам, так и по столбцам вниз, поэтому простой подход сжатия матрицы строка за строкой недостаточно хорош.(Для этого потребуется минимум O (num_rows) места для хранения любой матрицы.)

Представление матрицы также должно быть доступно построчно, чтобы я мог выполнять умножение матрицы на столбецвектор.

Ответы [ 14 ]

0 голосов
/ 23 июня 2010

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

0 голосов
/ 23 июня 2010

Многие из вышеперечисленных решений хороши.

Если вы работаете с файлом, считайте, что файл ориентирован инструменты сжатия, такие как сжатие, bzip, zip, bzip2 и друзья. Они работают очень хорошо, особенно если данные содержат избыточные Символы ASCII. Использование внешнего инструмента сжатия исключает проблемы и проблемы внутри вашего кода и будет сжимать как двоичные данные, так и данные ASCII.

В вашем примере вы отображаете цифры одного символа. Числа 0-9 могут быть представлены меньшими четырьмя битами шаблон кодирования. Вы можете использовать дополнительные биты в байт как количество. Четыре бита дают вам дополнительные коды бежать к статистам ... Но есть предостережение, которое достигает вернуться к старым ошибкам Y2K, где использовались два символа в течение года. Байтовая кодировка из офсета дала бы 255 лет и те же два байта будут охватывать все написанное история, а затем некоторые.

0 голосов
/ 23 июня 2010

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

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

Я бы начал с кодирования длин серий, посмотрим, как это работает в первую очередь.Как только это сработает, попробуйте добавить некоторые трюки, такие как ссылки на разделы предыдущего ряда.Таким образом, строка может быть закодирована как: 126 нулей, 8 единиц, 1000 записей, скопированных непосредственно из строки выше, 32 нуля.Похоже, что это может быть очень эффективно с вашим примером.

0 голосов
/ 23 июня 2010

У меня нет конкретного ответа для матрицы, которую вы показали.В анализе методом конечных элементов (FEA) у вас есть матрицы с избыточными данными.При реализации пакета FEA в моем проекте «Град» я использовал метод хранения Skyline.

Некоторые ссылки:

Страница Intel для хранения с разреженной матрицей

Ссылка на Википедию

...