Измерение временной сложности некоторых алгоритмов сортировки

1

Я пишу демо-класс в Java для анализа следующих алгоритмов сортировки:

  1. сортировка вставками
  2. сортировка выбор
  3. BubbleSort
  4. Сортировка слиянием
  5. QuickSort

которые я реализовал как статические методы в другом классе с именем Sort.

Я хочу сравнить Best-, Average- и Worst-Cases каждого алгоритма, определив время выполнения с аналитической сложностью, используя формулу омикрона.

В демо-классе я хочу только определить время (в наносекундах), каждый алгоритм должен сортировать массив целых чисел с разной длиной в порядковых номерах Best-, Average- и Worst-Case в массиве.

        //Best-Case
    int[] arrbc0 = {1};
    int[] arrbc1 = {1, 2};
    int[] arrbc2 = {1, 2, 3};
    int[] arrbc3 = {1, 2, 3, 4, 5};
    int[] arrbc4 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    int[] arrbc5 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};

    //Average-Case
    int[] arrac1 = {1, 2};
    int[] arrac2 = {3, 1, 2};
    int[] arrac3 = {4, 2, 3, 1, 5};
    int[] arrac4 = {9, 1, 10, 6, 2, 4, 8, 3, 7, 5};
    int[] arrac5 = {13, 12, 1, 15, 5, 6, 7, 2, 14, 10, 3, 8, 4, 9, 11};

    //Worst-Case
    int[] arrwc1 = {2, 1};
    int[] arrwc2 = {3, 2, 1};
    int[] arrwc3 = {5, 4, 3, 2, 1};
    int[] arrwc4 = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
    int[] arrwc5 = {15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1};

    //InsertionSort:
    isNanoTime(arrbc0); //first load
    isNanoTime(arrbc1);
    isNanoTime(arrbc2);
    //...

    public static void isNanoTime(int[] arr) {
    long a1 = System.nanoTime();
    Sort.insertionSort(arr);
    long a2 = System.nanoTime() - a1;
    System.out.println(a2);
    }

Теперь у меня есть некоторые вопросы:

  1. Могу ли я использовать эти массивы для всех Best-, Average- и наихудших случаев этих алгоритмов или имеет худший пример MergeSort другого порядка?!
  2. Есть ли простой способ отменить массивы после их сортировки один раз?
  3. Это в любом случае "правильный путь", чтобы определить сложность времени (может быть, у кого-то есть лучшая идея)?
  • 0
    Он может (вроде) демонстрировать сложность времени, но я не думаю, что он может это определить. Время выполнения и сложность времени связаны между собой, но разные животные.
  • 1
    По многим причинам это будет непросто , не в последнюю очередь это stackoverflow.com/questions/504103/…
Теги:
arrays
algorithm
sorting
time-complexity

3 ответа

1
  1. Массивы слишком короткие: для любого "современного" процессора не потребуется времени для сортировки, даже в худшем случае
  2. Чтобы иметь соответствующие временные вариации, основанные на случайной случайности ввода, вам необходимо установить фиксированный размер входного сигнала и дать вам измеримое время (вероятно, в секундах)
  3. Вероятно, вам нужно сгенерировать набор из тысяч случайных массивов, добавить, возможно, какой-то конкретный массив в этот набор (отсортированный, отменивший сортировку,...). Затем вы можете запускать каждый алгоритм на каждом массиве из этого набора и измерять время, необходимое для их сортировки. Таким образом, вы можете получить хороший график распределения для каждого алгоритма, по которому вы можете видеть поведение каждого алгоритма (сортировка пузырьков очень высока, в то время как heapsort довольно стабилен...). Наихудший вход для одного алгоритма не обязательно является одним и тем же для другого алгоритма, следовательно, множество.
0

@MBo @Jean Logeart

Что ты об этом думаешь:

//Main:
for(int n = 100_000; n <= 1_000_000; n = n + 100_000) {
    //f.e. average case of insertion sort:
    int[] arr = randomArray(n);
    insertionSortWithRuntime(arr);
}

/**
 * For best cases using sorted numbers.
 * @param n- the length in which the array should be created.
 * @return
 */
public static int[] sortedArray(int n) {
    int[] arr = new int[n];

    for (int i = 0; i < n; i++) {
        arr[i] = i;
    }
    return arr;
}

/**
 * For average cases using random numbers.
 * @param n - the length in which the array should be created.
 * @return
 */
public static int[] randomArray(int n) {
    int[] arr = new int[n];

    for (int i = 0; i < n; i++) {
        arr[i] = (int) (Math.random() * 9 + 1);
    }
    return arr;
}

/**
 * For worst cases using reversed sorted numbers.
 * @param n - the length in which the array should be created.
 * @return
 */
public static int[] reversedSortedArray(int n) {
    int[] arr = new int[n];

    int length = n - 1;

    for (int i = 0; i < n; i++) {
        arr[i] = length;
        length--;
    }
    return arr;
}

Вы представляли это так?

  • 0
    Я предложил слишком большой размер для квадратичных алгоритмов (вставка / пузырьковые сортировки). Размер 1000-10000 будет разумным.
  • 0
    Хорошо, я использую это сейчас: для (int n = 10_000; n <= 100_000; n = n + 10_000) {...} У меня есть еще один вопрос: теперь я хочу сравнить эмпирические с аналитическими данными путем передачи данных вручную в Excel (и показать график), например, для вставки сортировки Average- и Worst-Case, большие обозначения O: O (n²), поэтому для массива длиной 10.000 вы ожидаете время 100.000.000 миллионов ( какой блок ?!) и я получаю, например, 93 миллисекунды ?! Я сейчас немного растерялся .. @Жан Ложарт
Показать ещё 5 комментариев
0
  1. Такие массивы могут демонстрировать худшие и лучшие случаи для InsertionSort и BubbleSort. Типичные реализации MergeSort и SelectionSort имеют одинаковую сложность для всех массивов. Наихудший пример для простой реализации QuickSort - сортированный (или отсортированный) массив.
    Страница Wiki с полезной таблицей
    Обратите внимание, что эти массивы слишком короткие, чтобы заметить разницу во времени выполнения. Создавайте массивы с 10 ^ 3-10 ^ 6 элементами (для медленных и быстрых алгоритмов соответственно).

  2. Посмотрите на Fisher-Yates, чтобы получить случайную последовательность

Ещё вопросы

Сообщество Overcoder
Наверх
Меню