Сжатие данных без потерь для чрезвычайно больших данных — Планетарный искусственный интеллект

Я хочу создать среду для искусственного интеллекта планетарных размеров. Он будет имитировать подземную жизнь в очень большом мире. Согласно Википедии, площадь поверхности планеты Земля составляет 510 072 000 км ^ 2, я хочу создать квадрат таких же пропорций, может быть, больше. Я буду хранить один метр на каждом бите, где 0 означает грязь, а 1 означает стену грязи.

Давайте сначала посчитаем, как хранить одну строку этого квадрата. Одна строка будет 510072000000m, а каждый байт может хранить 8 метров, поэтому одна строка будет 59,38 ГБ, а весь мир будет 3,44 ПБ. А хотелось бы добавить хотя бы воду и лаву на каждый квадратный метр, что бы умножить результаты на 2.

Мне нужно сжать эту информацию с помощью алгоритмов сжатия данных без потерь. Сначала я попробовал очень прямой подход с 7zip и попробовал его с меньшим миром, где одна строка будет 6375B. По идее в мире должно быть 6375^2Б = 38.76Мб, но когда пробую получаю файл 155Мб, не знаю почему такая разница. Но когда я сжимаю его с помощью 7Zip, я получаю файл размером 40,1 МБ. Это огромная разница, и с таким соотношением я бы преобразовал свой файл мира размером 3,44 ПБ в файл размером 912,21 ГБ.

Моя первая мысль: почему у меня такой большой файл, когда математика говорит мне, что он должен быть меньше? Может проблема в коде, может проблема в том, что у меня были ошибки по математике. Код выглядит следующим образом: (С#)

// 510072000000m each line = 63759000000B
const long SIZE = 6375;

// Create the new, empty data file.
string fileName = tbFile.Text;

FileStream fs = new FileStream(fileName, FileMode.Create);

// Create the writer for data.
BinaryWriter w = new BinaryWriter(fs);

// Use random numbers to fill the data
Random random = new Random();
// Write data to the file.
for (int i = 0; i < SIZE; i++)
{
    for (int j = 0; j < SIZE; j++)
    {
        w.Write(random.Next(0,256));
    }
}

w.Close();

fs.Close();

И математика настолько проста, что если я сделал что-то не так, я не могу этого увидеть.

Можете ли вы дать мне какой-нибудь совет? Просто сосредоточьтесь на сжатии данных, искусственный интеллект не проблема, потому что у меня есть опыт работы с эволюционными алгоритмами, и мир не должен быть в реальном времени, он может занять столько времени, сколько ему нужно.

Спасибо всем за ваше время.


person user1506205    schedule 06.07.2012    source источник
comment
Для 2D-данных вы должны изучить дерево квадрантов.   -  person nhahtdh    schedule 06.07.2012
comment
Это как-то связано с тем, что всякий раз, когда вы записываете, вы записываете 4 байта, а затем переходите к следующим 4 байтам. Поэтому для каждого SIZE вы пишете 4 байта, а не один?   -  person Davos555    schedule 06.07.2012
comment
Поскольку кажется, что вы пишете 4 байта целых чисел, 3 из которых являются нулями, а последний является случайным, фактическая степень сжатия (155/40 ~= 0,25) намного выше, чем то, что вы должны закончить (это 0,25, потому что все серии из трех нулей случается много и, вероятно, представлены с использованием только 1 бита в финальном файле).   -  person Scharron    schedule 06.07.2012


Ответы (2)


@Scharron правильно ответил на особенности вашего вопроса, но я думаю, что есть более фундаментальная проблема:

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

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

person tobyodavies    schedule 06.07.2012
comment
И затраты ЦП на сжатие, безусловно, не стоят нескольких битов, которые вы получите (если вы их получите). - person Scharron; 06.07.2012
comment
Спасибо. Что ж, мне придется подождать, пока у меня появится жесткий диск на 10 ТБ, или я создам мир поменьше :D - person user1506205; 06.07.2012

Я не знаю насчет C#, но, похоже, вы сейчас каждый раз пишете 4 байта (6375 * 6375 * 4 байта в МБ = 155 МБ). Итак, я предполагаю, что метод Write в настоящее время записывает 32-битное целое число.

person Scharron    schedule 06.07.2012
comment
Спасибо, это проблема. А также я должен переосмыслить, как создать мир, я не создаю квадрат, и одна линия из 510 072 000 км ^ 2 будет квадратным корнем из этого числа, а не из этого числа. - person user1506205; 06.07.2012