Реализация алгоритма FAST для сортировки очень маленького списка

Это - проблема, с которой я столкнулся давным-давно. Я думал, что могу попросить у Вашего Ваших идей. предположите, что у меня есть очень маленький список чисел (целые числа), 4 или 8 элементов, которые должны быть отсортированы, быстро. каков был бы лучший подход/алгоритм?

мой подход должен был использовать макс. функции / минимальные функции (10 функций для сортировки 4 чисел, никаких ответвлений, iirc).

// s(i,j) == max(i,j), min(i,j)
i,j = s(i,j)
k,l = s(k,l)
i,k = s(i,k) // i on top
j,l = s(j,l) // l on bottom
j,k = s(j,k)

Я предполагаю, что мой вопрос принадлежит больше реализации, а не типу алгоритма.

В этой точке это становится несколько аппаратно-зависимым, таким образом давайте примем Intel 64-разрядный процессор с SSE3.

Спасибо

36
задан VividD 8 April 2019 в 18:33
поделиться

6 ответов

Для небольших массивов, подобных этому, вам, вероятно, следует изучить сети сортировки . Как вы можете видеть на этой странице, сортировку вставкой можно выразить как сеть сортировки. Однако, если вы заранее знаете размер массива, вы можете разработать оптимальную сеть. Взгляните на этот сайт , который может помочь вам найти оптимальные сети сортировки для заданного размера массива (хотя оптимальность гарантируется только до размера 16, я полагаю). Компараторы даже сгруппированы вместе для операций, которые могут выполняться параллельно. Компараторы по сути такие же, как ваша функция s (x, y), хотя, если вы действительно хотите, чтобы это было быстро, вам не следует использовать min и max, потому что тогда вы делаете в два раза больше необходимых сравнений.

Если вам нужен этот алгоритм сортировки для работы с широким диапазоном размеров, вам, вероятно, следует просто использовать сортировку вставкой, как предлагали другие.

35
ответ дан 27 November 2019 в 05:57
поделиться

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

Самый эффективный способ сортировки, например, четырех элементов - это раскрыть алгоритм сортировки до линейных сравнений, тем самым устраняя все накладные расходы:

function sort(i,j,k,l) {
  if (i < j) {
    if (j < k) {
      if (k < l) return [i,j,k,l];
      if (j < l) return [i,j,l,k];
      if (i < l) return [i,l,j,k];
      return [l,i,j,k];
    } else if (i < k) {
      if (j < l) return [i,k,j,l];
      if (k < l) return [i,k,l,j];
      if (i < l) return [i,l,k,j];
      return [l,i,k,j];
    } else {
      if (j < l) return [k,i,j,l];
      if (i < l) return [k,i,l,j];
      if (k < l) return [k,l,i,j];
      return [l,k,i,j];
    }
  } else {
    if (i < k) {
      if (k < l) return [j,i,k,l];
      if (i < l) return [j,i,l,k];
      if (j < l) return [j,l,i,k];
      return [l,j,i,k];
    } else if (j < k) {
      if (i < l) return [j,k,i,l];
      if (k < l) return [j,k,l,i];
      if (j < l) return [j,l,k,i];
      return [l,j,k,i];
    } else {
      if (i < l) return [k,j,i,l];
      if (j < l) return [k,j,l,i];
      if (k < l) return [k,l,j,i];
      return [l,k,j,i];
    }
  }
}

Однако код значительно увеличивается для каждого добавляемого вами дополнительного элемента. Добавление пятого элемента увеличивает размер кода примерно в четыре раза. В восьми элементах это будет примерно 30000 строк, поэтому, хотя он по-прежнему самый эффективный, это большой объем кода, и вам придется написать программу, которая пишет код, чтобы сделать его правильным.

7
ответ дан 27 November 2019 в 05:57
поделиться

Я вижу, у вас уже есть решение, которое использует 5 сравнений (при условии, что s (i, j) сравнивает два числа один раз и либо меняет их местами, либо нет ). Если вы будете придерживаться сортировки на основе сравнения, то вы не сможете сделать это с помощью менее 5 сравнений.

Это можно доказать, потому что их 4! = 24 возможных способа заказать 4 номера. Каждое сравнение может сократить возможности только наполовину, поэтому с 4 сравнениями вы можете различить только 2 ^ 4 = 16 возможных порядков.

7
ответ дан 27 November 2019 в 05:57
поделиться

Вставная сортировка считается лучшей для небольших массивов. См. Быстрая стабильная сортировка для небольших массивов (менее 32 или 64 элементов)

4
ответ дан 27 November 2019 в 05:57
поделиться

Сортировочные сети могут быть легко реализованы в SIMD, хотя это начинает становиться некрасивым примерно при N = 16. Однако для N = 4 или N = 8 это будет хорошим выбором. В идеале вам нужно много небольших наборов данных для одновременной сортировки, т.е. если вы сортируете 8-битные значения, то вам нужно по крайней мере 16 наборов данных для сортировки - гораздо труднее сделать такую вещь через SIMD-векторы.

См. также: Самая быстрая сортировка массива фиксированной длины 6 int

3
ответ дан 27 November 2019 в 05:57
поделиться

Для такого небольшого набора данных вам нужен как можно более простой алгоритм. Скорее всего, базовая сортировка вставкой подойдет вам так хорошо, как вы могли бы пожелать.

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

3
ответ дан 27 November 2019 в 05:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: