Кіріспе
Алгоритмдер қолданатын ресурстарды зерттеу
Компьютерлік ғылымда алгоритмдерді талдау – алгоритмдердің есептеу күрделілігін анықтау процесі, яғни оларды орындау үшін қажетті уақыт, жад немесе басқа да ресурстар мөлшерін табу. Әдетте, бұл алгоритмнің кіріс көлемі мен оның қадамдарының саны (уақыт күрделілігі) немесе пайдаланатын жад мөлшері (кеңістік күрделілігі) арасындағы байланысты анықтайтын функцияны табуды қамтиды. Алгоритм тиімді деп есептеледі, егер осы функцияның мәндері кішкентай болса немесе кіріс көлемі өскенде олар баяу өссе. Бірдей көлемдегі әртүрлі кірістер алгоритмнің әртүрлі жұмыс істеуіне әкелуі мүмкін, сондықтан ең жақсы, ең нашар және орташа жағдайлар туралы сипаттамалар маңызды болуы мүмкін. Басқаша көрсетілмесе, алгоритмнің өнімділігін сипаттайтын функция әдетте ең нашар жағдайдағы кірістер бойынша анықталған жоғарғы шек болып табылады. "Алгоритмдерді талдау" термині Дональд Кнутпен енгізілген. Алгоритмдерді талдау – есептеу күрделілігі теориясының маңызды бөлігі, ол белгілі бір есептеу мәселесін шешетін кез келген алгоритмге қажетті ресурстардың теориялық бағалауын ұсынады. Бұл бағалаулар тиімді алгоритмдерді іздеудің дұрыс бағыттарын анықтауға көмектеседі. Алгоритмдерді теориялық талдағанда, олардың күрделілігін асимптотикалық тұрғыдан бағалау жиі кездеседі, яғни кез келген үлкен кіріс үшін күрделік функциясын бағалау. Осы мақсатта Big O, Big Omega және Big Theta нотациялары қолданылады. Мысалы, бинарлық іздеу сұрыпталған тізімнің n мөлшерінің логарифміне пропорционалды қадамдар санымен немесе O(log n) – «логарифмдік уақытта» орындалады деп айтуға болады. Асимптотикалық бағалаулар көбінесе қолданылады, өйткені бір алгоритмнің әртүрлі іске асырылуы тиімділік жағынан өзгеше болуы мүмкін. Дегенмен, берілген алгоритмнің екі «ақылға қонымды» іске асырылуының тиімділігі жасырын тұрақты деп аталатын тұрақты көбейткіш фактормен байланысты. Тиімділіктің нақты (асимптотикалық емес) өлшемдерін есептеуге болады, бірақ олар көбінесе алгоритмнің нақты іске асырылуына қатысты белгілі бір болжамдарды, яғни есептеу моделін қажет етеді. Есептеу моделі абстрактілі компьютер, мысалы, Тьюринг машинасы, және/немесе кейбір операциялар бірлік уақытта орындалады деген постулаттар арқылы анықталуы мүмкін. Мысалы, егер біз бинарлық іздеуді қолданатын сұрыпталған тізімде n элемент болса және тізімдегі элементтің әрбір іздеуін бірлік уақытта орындауға кепілдік бере аламыз, онда жауапты қайтару үшін ең көп дегенде log2(n) + 1 уақыт бірлігі қажет болады.
Орындау уақытын талдау
Жүргізу уақытын талдау – алгоритмнің кіріс мөлшері (әдетте n деп белгіленеді) артқан сайын, оның жұмыс істеу уақытының (немесе орындалу уақытының) өсуін бағалау және болжауға мүмкіндік беретін теориялық жіктеме. Орындалу уақытының тиімділігі – компьютер ғылымында маңызды мәселе: Бағдарламаның орындалуына секундтар, сағаттар, тіпті жылдар қажет болуы мүмкін, бұл қолданылған алгоритмге байланысты. Бағдарламалық профильдеу техникаларын алгоритмнің орындалу уақытын тәжірибеде өлшеу үшін пайдалануға болады, бірақ олар барлық мүмкін кірістер үшін уақыт деректерін қамтамасыз ете алмайды; мұндай деректерді алуға тек жүргізу уақытын талдаудың теориялық әдістері ғана мүмкіндік береді.
Өсу реті
Бейресми түрде, алгоритм математикалық функция ретіндегі өсу деңгейін көрсетеді деп айтуға болады, егер белгілі бір кіріс мөлшері n-ден асып кеткенде, f(n) функциясын оң тұрақтыға көбейту сол алгоритмнің орындалу уақытының жоғарғы шегін немесе лимитін беретін болса. Яғни, белгілі бір n0-ден үлкен n және c тұрақтысы үшін, алгоритмнің орындалу уақыты c × f(n)-нан артық болмайды. Бұл түсінік көбінесе Big O нотациясы арқылы көрсетіледі. Мысалы, енгізу сұрыптау алгоритмінің орындалу уақыты кіріс мөлшері арта келе квадраттық түрде өседі, сондықтан енгізу сұрыптау O(n²) ретінде сипатталады. Big O нотациясы – берілген алгоритм үшін ең нашар жағдайды көрсетудің ыңғайлы тәсілі, бірақ оны орташа жағдайды көрсету үшін де қолдануға болады. Мысалы, жылдам сұрыптау алгоритмінің ең нашар жағдайы O(n²), ал орташа жағдайдағы орындалу уақыты O(n log n).
Өсудің эмпирикалық реті
Егер орындалу уақыты қуат заңына бағынса, t ≈ kn^(a) болса, a коэффициентін кейбір мәселе өлшемдері {n1, n2} үшін орындалу уақытының {t1, t2} эмпирикалық өлшемдерін алып, 1 = t2/t1 = (n2/n1)^(a) есебі арқылы табуға болады, осылайша 1 = a = log(t2/t1)/log(n2/n1). Басқаша айтқанда, бұл орындалу уақытының логарифм-логарифм графигіндегі эмпирикалық түзудің кейбір өлшем нүктесіндегі еңісін өлшейді. Егер өсу реті шын мәнінде қуат заңына бағынса (яғни логарифм-логарифм графигіндегі түзу шын мәнінде түзу болса), эмпирикалық мән әртүрлі диапазондықта тұрақты болады, ал егер бағынбаса, онда өзгереді (және түзу қисық болады) – бірақ бәрібір кез келген екі алгоритмді олардың эмпирикалық жергілікті өсу реті бойынша салыстыруға болады. Жоғарыдағы кестеге қолданылған: n (тізім мөлшері) Компьютер A орындалу уақыты (наносекундтарда) Жергілікті өсу реті (n^ ) Компьютер B орындалу уақыты (наносекундтарда) Жергілікті өсу реті (n^ ) 15 7 100,000 65 32 1.04 150,000 0.28 250 125 1.01 200,000 0.21 1,000 500 1.00 250,000 0.16 1,000,000 500,000 1.00 500,000 0.10 4,000,000 2,000,000 1.00 550,000 0.07 16,000,000 8,000,000 1.00 600,000 0.06 Бірінші алгоритм шын мәнінде қуат заңына бағынатын сызықтық өсу ретін көрсетеді. Екіншісі үшін эмпирикалық мәндер тез төмендеп барады, бұл оның өсудің басқа заңына бағынатынын және кез келген жағдайда өсудің әлдеқайда төмен жергілікті реті бар екенін (және одан да жақсарып жатқанын) эмпирикалық тұрғыдан көрсетеді.
n (list size) Computer A run time(in nanoseconds) Local order of growth(n^ ) Computer B run time(in nanoseconds) Local order of growth(n^ ) 15 7 100,000 65 32 1.04 150,000 0.28 250 125 1.01 200,000 0.21 1,000 500 1.00 250,000 0.16 1,000,000 500,000 1.00 500,000 0.10 4,000,000 2,000,000 1.00 550,000 0.07 16,000,000 8,000,000 1.00 600,000 0.06
It is clearly seen that the first algorithm exhibits a linear order of growth indeed following the power rule. The empirical values for the second one are diminishing rapidly, suggesting it follows another rule of growth and in any case has much lower local orders of growth (and improving further still), empirically, than the first one.
Қатысуы
Алгоритмдік талдау практикада маңызды, себебі тиімсіз алгоритмді кездейсоқ немесе ойсыз пайдалану жүйе жұмысына елеулі әсер ете алады. Уақытқа сезімтал қолданбаларда алгоритмнің орындалуына тым көп уақыт кетсе, оның нәтижелері қарт болып, немесе қолдануға жарамсыз болуы мүмкін. Тиімсіз алгоритм сондай-ақ жұмыс істеу үшін тым көп есептеу қуаты мен жадты қажет етуі мүмкін, осылайша оны іс жүзінде пайдасыз етеді.
Тұрақты факторлар
Алгоритмдерді талдау көбінесе асимптотикалық өнімділікке, әсіресе қарапайым жағдайларда назар аударады, бірақ практикалық қолданыстарда тұрақты коэффициенттер маңызды, ал нақты деректер көлемі әрқашан шектеулі болады. Көлемі әдетте қолжетімді жадтың мөлшерімен шектеледі, сондықтан 32 биттік машиналарда 232 = 4 ГиБ (сегменттелген жад қолданылса, одан да көп) және 64 биттік машиналарда 264 = 16 ЭиБ. Осылайша, шектеулі көлемді ескере отырып, өсу реті (уақыт немесе кеңістік) тұрақты коэффициентпен алмастырылуы мүмкін, және осы тұрғыдан алғанда, барлық практикалық алгоритмдер жеткілікті үлкен тұрақты мән үшін немесе жеткілікті кішкентай деректер үшін O(1) болып табылады. Бұл түсіндіру, ең алдымен, өте баяу өсетін функциялар үшін пайдалы: (бинарлық) итерациялық логарифм (log*) барлық практикалық деректер үшін 5-тен кем; (бинарлық) лог лог (log log n) барлық практикалық деректер үшін 6-дан кем (264 бит); және бинарлық лог (log n) барлық практикалық деректер үшін 64-тен кем (264 бит). Тұрақты емес күрделілікке ие алгоритм, егер тұрақты уақыт алгоритмінің қосымша шығындары үлкен тұрақты коэффициентке әкелсе, практикалық деректерде тұрақты күрделілікке ие алгоритмге қарағанда тиімдірек болуы мүмкін, мысалы, болуы мүмкін, егер және болса. Үлкен деректер үшін сызықтық немесе квадраттық коэффициенттерді елемеуге болмайды, бірақ кішкентай деректер үшін асимптотикалық тұрғыдан тиімсіз алгоритм тиімдірек болуы мүмкін. Бұл әсіресе гибридті алгоритмдерде қолданылады, мысалы, Timsort, ол асимптотикалық тұрғыдан тиімді алгоритмді (осы жерде біріктіру сұрыптау, уақыт күрделілігімен ) пайдаланады, бірақ кішкентай деректер үшін асимптотикалық тұрғыдан тиімсіз алгоритмға (осы жерде енгізу сұрыптау, уақыт күрделілігімен ) ауысады, себебі қарапайым алгоритм кішкентай деректерде жылдамырақ жұмыс істейді.
For large data linear or quadratic factors cannot be ignored, but for small data an asymptotically inefficient algorithm may be more efficient. This is particularly used in hybrid algorithms, like Timsort, which use an asymptotically efficient algorithm (here merge sort, with time complexity ), but switch to an asymptotically inefficient algorithm (here insertion sort, with time complexity ) for small data, as the simpler algorithm is faster on small data.