Мне нужен очень быстрый алгоритм для следующей задачи. Я уже реализовал несколько алгоритмов, которые завершают его, но они слишком медленны для производительности, в которой я нуждаюсь. Он должен быть достаточно быстрым, чтобы алгоритм мог работать не менее 100 000 раз в секунду на современном процессоре. Он будет реализован на C++.Помощь с алгоритмом слияния векторов
Я работаю с диапазонами/диапазонами, структурой, которая имеет начало и конечную координату на линии.
У меня есть два вектора (динамические массивы) пролетов, и мне нужно их объединить. Один вектор - src, а другой dst. Векторы сортируются по начальным координатам диапазона, а пролеты не перекрываются внутри одного вектора.
Пространства в векторе src должны быть объединены с пролетами вектора dst, так что результирующий вектор по-прежнему сортируется и не имеет перекрытий. То есть. если во время слияния обнаруживаются перекрытия, два пролета объединяются в один. (Слияние двух пролетов - это просто вопрос изменения координат в структуре.)
Теперь есть еще один улов, пролеты в векторе src должны быть «расширены» во время слияния. Это означает, что константа будет добавлена в начало и другая (большая) константа в конечную координату каждого интервала в src. Это означает, что после расширения пространств src они могут перекрываться.
То, что я прибыл в до сих пор является то, что она не может быть сделано полностью в месте, своего рода временного хранения не требуется. Я думаю, что это должно выполняться в линейном времени по количеству элементов src и dst, суммированных.
Любое временное хранилище, вероятно, может быть разделено между несколькими прогонами алгоритма.
Два основных подхода я пытался, которые слишком медленно, являются:
Append все элементы ЦСИ к целевой_адрес, расширяя каждый элемент перед добавлением его. Затем запустите сортировку на месте. Наконец, итерации по результирующему вектору, используя указатель «читать» и «писать», с указателем чтения, работающим впереди указателя записи, слияния с интервалами по мере их поступления. Когда все элементы объединены (указатель чтения достигает конца) dst усекается.
Создайте временный рабочий вектор. Сделайте наивное слияние, как описано выше, путем многократного выбора следующего элемента из src или dst и слияния в рабочий вектор. Когда закончите, скопируйте рабочий вектор в dst, заменив его.
Первый способ имеет проблему, что сортировка является O ((т + п) * лог (т + п)) вместо O (M + N) и имеет несколько накладных расходов. Это также означает, что вектор dst должен расти намного больше, чем ему действительно нужно.
Вторая проблема связана с большим количеством копирования и повторного выделения/освобождения памяти.
Структуры данных, используемые для хранения/управления пролетами/векторами, могут быть изменены, если вы считаете, что это необходимо.
Обновление: Забыл сказать, насколько велики наборы данных. Наиболее распространенными случаями являются от 4 до 30 элементов в любом векторе, и либо dst пуст, либо имеется большое количество перекрытий между пролетами в src и dst.
100k действительно может быть недосказанным, я действительно не подсчитал число. Также, когда я сказал «современный» процессор, я на самом деле думал «что-то до 5 лет», Athlon XP 3000+ не является нереалистичной целью. – jfs 2008-09-18 02:38:24