Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 06.04.2024, 21:47   #1
iXNomad
Пользователь
 
Регистрация: 06.01.2021
Сообщений: 52
По умолчанию Какая тут сложность алгоритма?

Вот логи, примечания в скобках написал вручную, также выделил жирным самое важное.
Самое основное это кол-во вызовов функции bitSort (т.к. рекурсия) и количество копирований элементов массива (внутри этой функции, когда делается разбивка). Очень похоже на O(nlogn), с каждым увеличением в 10 раз происходит что-то вроде замедления роста кол-ва операций - увеличение я так понял стремится к 10, что вроде похоже на отношения логарифмов (поправьте плиз).
Код:
Elements: 10
AVG_CALLS: 23.13
AVG_COPIES: 36.01
AVG_ARRAY_COPIES: 8.97
Elements: 20 (*2 относительно 10 элементов)
AVG_CALLS: 47.56 (*2.056 относительно 10 элементов)
AVG_COPIES: 92.99 (*2.056 относительно 10 элементов)
AVG_ARRAY_COPIES: 19
Elements: 50 (*5 относительно 10 элементов)
AVG_CALLS: 121.45 (*5.25 относительно 10 элементов)
AVG_COPIES: 297.86 (*8.272 относительно 10 элементов)
AVG_ARRAY_COPIES: 49
Elements: 100 (*10 относительно 10 элементов)
AVG_CALLS: 242.41 (*10.48 относительно 10 элементов)
AVG_COPIES: 697.79 (*19.378 относительно 10 элементов) (≈10 * 2 (т.к. квадрат)?)
AVG_ARRAY_COPIES: 99
Elements: 200 (*2 относительно 100 элементов)
AVG_CALLS: 484.36 (*1.998 относительно 100 элементов)
AVG_COPIES: 1595.49 (*2,286 относительно 100 элементов)
AVG_ARRAY_COPIES: 199
Elements: 500 (*5 относительно 100 элементов)
AVG_CALLS: 1221.37 (*5.038 относительно 100 элементов)
AVG_COPIES: 4648.8 (*6.662 относительно 100 элементов)
AVG_ARRAY_COPIES: 499
Elements: 1000 (*10 относительно 100 элементов)
AVG_CALLS: 2438.75 (*10.06 относительно 100 элементов)
AVG_COPIES: 10297.5 (*14.757 относительно 100 элементов) (≈10 * 3/2 (n * отношение log_10(1000)/log_10(100))?)
AVG_ARRAY_COPIES: 999
Elements: 2000 (*2 относительно 1000 элементов)
AVG_CALLS: 4890.79 (*2.005 относительно 1000 элементов)
AVG_COPIES: 22598.5 (*2.194 относительно 1000 элементов)
AVG_ARRAY_COPIES: 1999
Elements: 5000 (*5 относительно 1000 элементов)
AVG_CALLS: 12218.2 (*5.01 относительно 1000 элементов)
AVG_COPIES: 63103 (*6.128 относительно 1000 элементов)
AVG_ARRAY_COPIES: 4999
Elements: 10000 (*10 относительно 1000 элементов)
AVG_CALLS: 24441.7 (*10.022 относительно 1000 элементов)
AVG_COPIES: 136202 (*13.227 относительно 1000 элементов) (≈10 * 4/3?)
AVG_ARRAY_COPIES: 9999
Elements: 20000 (*2 относительно 10000 элементов)
AVG_CALLS: 48865.7 (*1.999 относительно 10000 элементов)
AVG_COPIES: 292409 (*2.147 относительно 10000 элементов)
AVG_ARRAY_COPIES: 19998.9
Elements: 50000 (*5 относительно 10000 элементов)
AVG_CALLS: 122135 (*4.997 относительно 10000 элементов)
AVG_COPIES: 797100 (*5.852 относительно 10000 элементов)
AVG_ARRAY_COPIES: 49998.4
Elements: 100000 (*10 относительно 10000 элементов)
AVG_CALLS: 244296 (*9.995 относительно 10000 элементов)
AVG_COPIES: 1.6942e+06 (*12.439 относительно 10000 элементов) (≈10 * 5/4?)
AVG_ARRAY_COPIES: 99996.8 
Elements: 200000 (*2 относительно 100000)
AVG_CALLS: 488475 (*2 относительно 100000)
AVG_COPIES: 3.58843e+06 (*2.118 относительно 100000)
AVG_ARRAY_COPIES: 199989
Elements: 500000 (*5 относительно 100000)
AVG_CALLS: 1.22103e+06 (*4.998 относительно 100000)
AVG_COPIES: 9.63206e+06 (*5.685 относительно 100000)
AVG_ARRAY_COPIES: 499940
Elements: 1000000 (*10 относительно 100000)
AVG_CALLS: 2.44103e+06 (*9.992 относительно 100000)
AVG_COPIES: 2.0264e+07 (*11.96 относительно 100000) (≈10 * 6/5?)
AVG_ARRAY_COPIES: 999767
Вот код, сама сортировка в функции bitSort + две вспомогательные для получения бита и копирования массива:

Код:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define TEST_DEPTH 100

void arr_cpy(int* array0, int* array1, unsigned int length);
void bitSort(int* array, unsigned int length, int element_size);
int getBit(int* number, int bit_index);

void test(int number_of_elements);

int copies;
int array_copies;
int calls;
float avg_copies = 0;
float avg_array_copies = 0;
float avg_calls = 0;

int main() {

    test(10);
    test(20);
    test(50);
    test(100);
    test(200);
    test(500);
    test(1000);
    test(2000);
    test(5000);
    test(10000);
    test(20000);
    test(50000);
    test(100000);
    test(200000);
    test(500000);
    test(1000000);

    return 0;
}

void test(int size) {

    for (int tst = 0; tst < TEST_DEPTH; tst++) {

        calls = 0;
        copies = 0;
        array_copies = 0;

        for (int i = 0; i < size; i++) {
            arr[i] = rand();
        }
        
        bitSort(arr, size, sizeof(int) * 8);

        avg_calls += (float) calls;
        avg_copies += (float) copies;
        avg_array_copies += (float) array_copies;
    }

    avg_calls /= TEST_DEPTH;
    avg_copies /= TEST_DEPTH;
    avg_array_copies /= TEST_DEPTH;

    printf("Elements: %d\nAVG_CALLS: %g\nAVG_COPIES: %g\nAVG_ARRAY_COPIES: %g\n",
            size, avg_calls, avg_copies, avg_array_copies);
    
    avg_calls = 0;
    avg_copies = 0;
    avg_array_copies = 0;
}

void bitSort(int* array, unsigned int length, int bits) {

    static int subsets = 1;
    if (subsets == length) {
        return;
    }
    static int start_length;
    calls++;
    if (calls == 1) {
        start_length = length;
        for(int j = bits-1; j >= 0; j--) {
            for(int i = 0; i < length; i++) {
                if (getBit(&(array[i]), j) == 1) {
                    bits = j + 1;
                    goto found_max;
                }
                if (j == 0) {
                    return;
                }
            }
        }
    }
found_max:;
    
    int aux_arr[length];
    int zeroes = 0;
    int ones = 0;

    for (int i = 0; i < length; i++) {
        if (getBit(&(array[i]), bits-1) == 0) {
            zeroes++;
        } else {
            ones++;
        }
    }
//    printf("Op: %d, L: %d, S: %d, B: %d, Z: %d, O: %d\n", ops, length, subsets, bits, zeroes, ones);
    bits--;
    if ((zeroes != 0) && (ones != 0)) {
        subsets++;
        int j = 0;
        int k = 0;
        for(int i = 0; i < length; i++) {
            if (getBit(&(array[i]), bits) == 0) {
                aux_arr[j] = array[i];
                j++;
            } else {
                aux_arr[zeroes+k] = array[i];
                k++;
            }
            copies++;
        }
        array_copies++;
        arr_cpy(aux_arr, array, length);
        if (length == 1 || subsets == start_length || bits == 0) {
    //        printf("OP: %d\n", ops);
            return;
        }
        bitSort(array, zeroes, bits);
        bitSort(array+zeroes, ones, bits);
    } else {
        if (length == 1 || subsets == start_length || bits == 0) {
    //        printf("OP: %d\n", ops);
            return;
        }
        bitSort(array, length, bits);
    }
}

void arr_cpy(int* arr_src, int* arr_dst, unsigned int len) {
    for(int i = 0; i < len; i++) {
        arr_dst[i] = arr_src[i];
    }
}

int getBit(int* number, int bit_index) {
   return (*number >> bit_index) % 2;
}
P.S. Я понял что скорее всего завалил рандомайзер потому что он наверное менял зерно лишь раз в секунду чего не достаточно, хотя тут это думаю не суть важно (большие тесты длились довольно долго, несколько раз точно менял зерно).
iXNomad вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Определить сложность алгоритма - C# Keniro Помощь студентам 0 30.11.2016 19:25
Сложность алгоритма Маркова iYoung Фриланс 0 31.05.2011 18:30
Определить сложность алгоритма serj-07 Помощь студентам 5 10.08.2010 07:54
сложность алгоритма NiCola999 Помощь студентам 14 22.11.2009 19:33
Сложность Алгоритма PChEL@ Помощь студентам 3 26.05.2007 07:56