Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > C/C++: Общие вопросы > Как лучше всего хранить коэффициенты? |
Автор: hello19 26.2.2012, 12:58 |
Мне нужно работать с матрицей порядка 100 000. Она сильно разреженная, по этому хранить все коэффициенты - не вижу смысла. Стало быть нужно хранить только не нулевые элементы матрицы. Но вот как это сделать лучше всего, чтобы было задействовано как можно меньше памяти? Элементы матрицы типа double |
Автор: hello19 26.2.2012, 13:58 |
Нет, матрица обычная 100 000 * 100 000 Что-то не соображу как реализовать поиск элементов... |
Автор: feodorv 26.2.2012, 14:34 | ||||
Если размер матрицы фиксирован, то её можно превратить в линейный список: [i][j] => [i*N+j], хотя 100 000 * 100 000 в int уже не влезают... Тогда можно хранить два набора индексов:
Список индексов - отсортированный, поэтому можно воспользоваться бинарным поиском:
Если элемент [x][y] не найден, значит его значение 0.0, иначе m->values[*pindex]. Добавлено @ 14:48 Аналогично пишется spmatrixAdd( m, x, y, value):
|
Автор: feodorv 26.2.2012, 14:52 |
Если нет желания возиться с отсортированным списком индексов, тогда можно в лоб сравнивать все пары m->x[i], m->y[i] с x, y. Но это потребует много времени... Если же ненулевых значений мотрицы не так уж и мало (>10000), то можно воспользоваться (например) красно-чёрным деревом для хранения ненулевых значений матрицы, тогда каждый лист дерева будет содержать набор (x,y,value). Дерево удобнее тем, что при добавлении новых ненулевых элементов не нужно будет перезаказывать память (правда, и потребует больше памяти по сравнению со списками). |
Автор: rumit7 26.2.2012, 14:55 | ||
Может быть вам будет интересно решение описанное здесь http://evgeny-lazin.blogspot.com/2011/06/blog-post.html |
Автор: feodorv 26.2.2012, 15:04 | ||
Да, решение интересное (подобно можно организовать нечёткий поиск подстроки длинной не более 32 символов в строке произвольной длины). Но:
|
Автор: rumit7 26.2.2012, 15:37 | ||||
Что-то я не очень понимаю в чем проблема? std::bitset и разные другие готовые штучки уже не в моде? |
Автор: Фантом 26.2.2012, 15:52 |
Технически, наверное, проще всего будет организовать массив 10^5 указателей (так что доступ по одной координате будет "прямым"), на которые повесить деревья (те же красно-черные или сразу B-), обеспечивающие поиск по второй координате. Скорость доступа по сравнению с чисто древесным вариантом будет в среднем в два раза больше, а одномерный массив из 10^5 указателей - это пустяк даже при 64-битной адресации. В принципе, если памяти не очень жалко, можно сделать аналогичную вещь, "сбросив" в линейный доступ еще и часть второй координаты (когда каждое дерево будет содержать не полную строку или столбец, а лишь некоторую часть). |
Автор: volatile 26.2.2012, 20:12 |
Я бы первом делом попробовал на std::map, (или лучше на хеш.мап), что нибудь организовать. на записи поставить иф. если нулевой коэф, просто не записывать в мап. на чтении, обратное, если нет в мапе, возвращать 0. |
Автор: Earnest 27.2.2012, 11:38 |
Ну да, map (хэш-мап) с ключом pair <int, int>. |
Автор: azesmcar 27.2.2012, 11:55 | ||
Тут вопрос в том, насколько она разреженная? Если там допустим половина элементов НЕ нулевые, то в итоге с map мы только теряем. std::map - это +3 указателя для каждого НЕ нулевого элемента да еще плюс к нему сам индекс, а это немало, в итоге может выйти так, что расход будет больше, чем при обычной матрице, да еще и поиск становиться не константным. В данном случае опять такие теряется константность поиска, но если хранить массив индексов отсортированным, то можно будет применить бинарный поиск. Мне кажется данных мало для однозначного ответа. hello19 Что для тебя важнее? Скорость нахождения элемента или размер расходуемой памяти, какой процент нулевых элементов ожидается в матрице? Что предполагается делать с матрицей? Какие действия? |
Автор: math64 29.2.2012, 15:03 | ||||||
Ещё зависит от того, где расположен ненулевые элементы. Если ненулевые элементы находятся около главной диалогали - хранить по диагоналям полностью. индекс диагонали - (x-y-minDiagonal), индекс на диагонали - max(x,y);
Если ненулевые элементы расположены блоками возле определеных координат
Добавлено через 12 минут и 50 секунд При делении на блоки для поиска удобно, чтобы они были одного размера и выравнены по своему размеру:
|
Автор: baldina 29.2.2012, 16:59 |
http://math.nist.gov/sparselib++/ |