У меня есть разреженный матричный класс, чьи не-нули и соответствующие им индексы столбцов хранятся в строчном порядке, в основном в виде контейнеров типа STL-vector. Они могут иметь неиспользуемую емкость, например векторы; и для вставки/удаления элементов необходимо перемещать существующие элементы.Алгоритм слияния коротких списков в длинный вектор
Скажите, что у меня есть операция, insert_erase_replace
, или ier
для краткости. ier
может сделать следующее, учитывая положение p
, индекс столбца j
, а значение v
:
- если
v==0
,ier
удаляет запись вp
и левой сдвигает все последующие записи. - если
v!=0
иj
уже присутствует вp
,ier
заменяет содержимое ячейки вp
сv
. - , если
v!=0
иj
не присутствует вp
,ier
вставляет записьv
и столбца индексаj
вp
после сдвига вправо все последующие записи.
Так что все это тривиально.
Теперь предположим, что у меня есть ier2
, что делает то же самое, за исключением того, что он принимает список, содержащий несколько индексов столбцов j
и соответствующие значения v
. Он также имеет размер n
, что указывает, сколько пар index/value присутствует в списке. Но поскольку вектор сохраняет только нули, иногда фактический размер вставки меньше, чем n
.
Еще тривиально.
Но теперь предположим, что у меня есть ier3
, который принимает не только один список, например ier2
, но несколько списков. Это означает редактирование среза разреженной матрицы.
В какой-то момент становится более эффективным перебирать векторы, копируя их по частям и вставляя/заменяя/стираем индексы/значения списка ier2
-стиль, когда мы достигаем каждой точки вставки. И если общий размер вставки приведет к тому, что мой вектор будет нуждаться в изменении размера в любом случае, тогда мы это сделаем.
Учитывая, что мой вектор много, намного больше, чем общая длина списков, существует ли алгоритм эффективного слияния списков в вектор?
До сих пор, вот что у меня есть:
Каждого список передается
ier3
представляет собой либо чистое удаление записей (левый сдвиг), чистая замену (без движения, поэтому дешево), или чистая вставка записей (сдвиг вправо). Там также может быть некоторая перегруппировка элементов, но дорогими частями являются чистые удаления и чистые вставки.Нетрудно найти алгоритм для эффективного выполнения ТОЛЬКО чистых вставок или сетевых удалений.
Это труднее, когда любой из двух может произойти.
Единственное, что я могу думать, чтобы сделать это, чтобы справиться с этим в два прохода:
- Erase/заменить
- Вставка/замена
Мы сотрите первый, потому что это делает более вероятно, что для любых вставок потребуется меньше копий.
Это правильный подход? Кто-нибудь знает о лучшем?
Есть ли причина, по которой разреженный матричный класс использует вектор, а не список? Если у вас есть список, то итераторы остаются в силе после вставки, что делает проблему намного проще. –
Это редкая матричная спецификация «yale». Диагоналями являются O (1), начинаются строки и заканчиваются O (1), и вы хотите иметь возможность бинарного поиска столбцов в этих строках. Я подозреваю, что использование списка также испортит некоторые математические операции. –
Мне кажется, что список входных данных для ier3 может быть сопоставим по размеру с существующими матричными элементами в этих строках - можете ли вы просто объединить все соответствующие элементы во временных массивах при удалении нулей, изменить размер большого вектора и скопировать все? –