Algoritmų analizės specialieji skyriai

Similar documents
Vango algoritmo analizė

VILNIAUS UNIVERSITETAS PAGRINDAI. Mokymo priemonė

Turinys. Geometrinės diferencialinių lygčių teorijos savokos. Diferencialinės lygties sprendiniai. Pavyzdžiai. CIt, (- 00,0) C'It, (0, (0);

Stochastinės analizės egzaminas MIF magistrantūra, FDM I kursas, 2018 m. ruduo (1 semestras), X s db s, t 0.

Kurso tikslai. 1 Įgyti galimybę skaitiškai spręsti taikomuosius uždavinius; 2 Įvertinti skirtingus skaitinius sprendimo metodus (žinant jų

DISKREČIOJI MATEMATIKA

GARSĄ SUGERIANČIŲ MEDŽIAGŲ IŠDĖSTYMO VIETŲ ĮTAKA SKAIČIUOJANT SALĖS AIDĖJIMO TRUKMĘ SKIRTINGOMIS FORMULĖMIS

DISKREČIOJI MATEMATIKA

GLOBALUSIS OPTIMIZAVIMAS SU SIMPLEKSINIAIS POSRIČIAIS

1 Kompiuterių aritmetika ir algoritmai. 2 Tiesinių lygčių sistemų sprendimo metodai: 3 Duomenų aproksimacija: 4 Tikrinių reikšmių uždavinys.

PAGERINTAS EURISTINIS ALGORITMAS DVIEJŲ SEKŲ BENDRO ILGIAUSIO POSEKIO PAIEŠKAI

ADAPTYVIOSIOS TECHNOLOGIJOS TAIKYMAS SANDĖLIO UŽDAVINIUI SPRĘSTI

ANALIZĖ 0: TEORINĖ ARITMETIKA

Turinys. Kurso struktūra. 2 Diferencialinės lygtys. 4 Matematinių modelių pavyzdžiai

Turinys. Turinys: Kurso tikslai. Olga Štikonienė. privalumus ir trūkumus); Tiesines algebros uždaviniai

KAUNO TECHNOLOGIJOS UNIVERSITETAS MATLAB/SIMULINK PROGRAMŲ TIPINIŲ OPTIMIZAVIMO METODŲ TYRIMUI SUKŪRIMAS

Rinktiniai informacijos saugos skyriai. 3. Kriptografija ir kriptografijos protokolai: Klasikinė kriptografija

METHODS FOR GENERATION OF RANDOM NUMBERS IN PARALLEL STOCHASTIC ALGORITHMS FOR GLOBAL OPTIMIZATION

Cheminė kinetika: reakcijų mechanizmai

EURISTINIŲ METODŲ TYRIMAS IR TAIKYMAS RIBOTŲ IŠTEKLIŲ TVARKARAŠČIAMS OPTIMIZUOTI

Optimizavimas ekonomikoje. Optimizavimas ekonomikoje 1 / 121

Iracionalieji skaičiai

Reklamos internete vartotojų segmentavimas taikant latentinį Dirichlė paskirstymo modelį

Computerized Laboratory in Science and Technology Teaching: Course in Machine Elements

Lloyd Max s Algorithm Implementation in Speech Coding Algorithm Based on Forward Adaptive Technique

LR Seimo narių elgsenos tyrimas, naudojant klasterinę analizę ir daugiamačių skalių metodą

CALCULATION OF ELECTROMAGNETIC WAVE ATTENUATION DUE TO RAIN USING RAINFALL DATA OF LONG AND SHORT DURATION

LIETUVOS ENERGETIKOS STRATEGIJA: OPTIMALIOS RENOVACIJOS MODELIS (ORM) (projektas pastaboms)

The minimizer for the second order differential problem with one nonlocal condition

Algebraic and spectral analysis of local magnetic field intensity

ŠIAULIŲ UNIVERSITETAS MATEMATIKOS IR INFORMATIKOS FAKULTETAS INFORMATIKOS KATEDRA. Remigijus Valčiukas

STABILIZATION OF UNSTABLE PERIODIC ORBIT IN CHAOTIC DUFFING HOLMES OSCILLATOR BY SECOND ORDER RESONANT NEGATIVE FEEDBACK

NUOTOLINIŲ KURSŲ OPTIMIZAVIMAS

DIRBTINIO INTELEKTO METODŲ TAIKYMAS KREDITO RI- ZIKOS VERTINIME

The Burg Algorithm with Extrapolation for Improving the Frequency Estimation

VILNIAUS UNIVERSITETAS JONAS JANKAUSKAS POLINOMŲ AUKŠČIAI. Daktaro disertacijos santrauka Fiziniai mokslai, matematika (01P)

VILNIAUS UNIVERSITETAS. Haroldas Giedra ĮRODYMŲ SISTEMA KORELIATYVIŲ ŽINIŲ LOGIKAI. Daktaro disertacijos santrauka Fiziniai mokslai, informatika (09P)

S. Tamošiūnas a,b, M. Žilinskas b,c, A. Nekrošius b, and M. Tamošiūnienė d

Random Factors in IOI 2005 Test Case Scoring

LANDAU SĄRAŠAS: NEĮVEIKIAMI SKAIČIŲ TEORIJOS UŽDAVINIAI

Užklausų kompiliavimas

PROTEOMIKA. Rūta Navakauskienė. El.paštas:

Tranzistoriai. 1947: W.H.Brattain and J.Bardeen (Bell Labs, USA)

Structural integrity verification of polycarbonate type personal identity documents

pn diodo griūtinio pramušimo tyrimas

The Euler Mascheroni constant in school

VILNIUS UNIVERSITY. Alma Molytė INVESTIGATION OF COMBINATIONS OF VECTOR QUANTIZATION METHODS WITH MULTIDIMENSIONAL SCALING

Matematikos ir informatikos institutas. Informatikos doktorantūros modulis Statistinis modeliavimas ir operacijų tyrimas

Optimal Segmentation of Random Sequences

VGTU EF ESK.

MATEMATINIO MODELIAVIMO KATEDRA

Dynamic-Programming-Based Inequalities for the Unbounded Integer Knapsack Problem

THE EIGENVALUE PROBLEM FOR DIFFERENTIAL OPERATOR WITH NONLOCAL INTEGRAL CONDITIONS

Struktūrinė geologija

Multi-Criteria Inventory Classification Using a New Method of Evaluation Based on Distance from Average Solution (EDAS)

Signalų analizė ir apdorojimas

Published online: 26 Jul 2012.

TIME PERIODIC PROBLEMS FOR NAVIER-STOKES EQUATIONS IN DOMAINS WITH CYLINDRICAL OUTLETS TO INFINITY

Programų sistemų inžinerija

Skaičiavimai matematiniu paketu Mathcad

Elektronų tarpusavio sąveikos grafene modeliavimas sklaidos matricos metodu

Iš Lietuvos matematikos istorijos 1. Jonas Kubilius ANTANAS BARANAUSKAS IR MATEMATIKA

Nullity of the second order discrete problem with nonlocal multipoint boundary conditions

A. Žukauskaitė a, R. Plukienė a, A. Plukis a, and D. Ridikas b

MATHEMATICAL MODELS FOR SCIENTIFIC TERMINOLOGY AND THEIR APPLICATIONS IN THE CLASSIFICATION OF PUBLICATIONS

Kiekviename šio vadovo skyrių pristatoma bendra ArcGIS funkcijų grupė, yra aprašomi įrankių naudojimo žingsniai, jie iliustruojami ekrano kopijomis.

Lietuvių šnekos balsių aprašymo autoregresijos modeliu adekvatumo tyrimas

Projektas. SFMIS Nr. VP1-3.1-ŠMM-02-V SEMINARO INFERENCINĖ STATISTIKA SOCIALINIUOSE MOKSLUOSE MEDŽIAGA. Vydas Čekanavičius

MATEMATINöS PROGRAMINöS ĮRANGOS MATHCAD TAIKYMAS DöSTANT APRAŠOMĄJĄ STATISTIKĄ Audrius Kabašinskas Kauno kolegija

DAUGIAMAČIŲ DUOMENŲ VIZUALIZAVIMO METODAI

INTELEKTUALAUS KOMPIUTERINIO RAŠTINGUMO TESTŲ KONSTRAVIMO METODO TYRIMAS

Esterio hidrolizės greičio tyrimas.

LOGISTIKOS CENTRO CILINDRINIŲ AUTOMATIZUOTŲ TRANSPORTAVIMO SISTEMŲ KŪRIMAS IR TYRIMAS

A Modified Simulated Annealing Algorithm for the Quadratic Assignment Problem

Testavimo su naudotojais metodai Panaudojamumo vertinimai Dr. Kristina Lapin

An Effective Method for Initialization of Lloyd Max s Algorithm of Optimal Scalar Quantization for Laplacian Source

OPTINöS ELEKTRONIKOS ĮTAISAI

VILNIUS UNIVERSITY LIJANA STABINGIENĖ IMAGE ANALYSIS USING BAYES DISCRIMINANT FUNCTIONS

Simulation Model of System Enabled to Serve n Types of Messages

Matematikos. 8 klasė TIMSS uždavinių pavyzdžiai

The Minimum Density Power Divergence Approach in Building Robust Regression Models

V. Palenskis, J. Matukas, and B. Šaulys

THe use of mathematical models for modelling sulphur dioxide sorption on materials produced from fly ashes

R. Plukienė a, A. Plukis a, V. Remeikis a, and D. Ridikas b a Institute of Physics, Savanorių 231, LT Vilnius, Lithuania

Temos studijavimo tikslai

Ekonometrinių modelių pritaikymas OMXV indekso pokyčių prognozavimui

Skaitinis tekėjimo greičio ir sienelės temperatūros kitimo modeliavimas horizontaliame plokščiame kanale esant termogravitacijos jėgų poveikiui

20 SOCIALINIS DRAUDIMAS SVARBI VALDŽIOS FUNKCIJA

METODINĖS REKOMENDACIJOS, SKIRTOS MATEMATIKOS MODULIŲ PROGRAMOMS 9-10 KL. ĮGYVENDINTI

Muzika ir akustika. 15 tema. studio. studio. Garsas, per kurį atsiskleidžia muzika

Method of marks for propositional linear temporal logic

LIETUVOS TSR AUKŠTŲJŲ MOKYKLŲ MOKSLO DARBAI PEDAGOGIKA IR PSICHOLOGIJA X, 1969 M. STAKVILEVICIUS

8 NAMŲ ŪKIŲ SPRENDIMAI VARTOTI, TAUPYTI IR DIRBTI: LABIAU FORMALI ANALIZĖ

A general biochemical kinetics data fitting algorithm for quasi-steady-state detection

Chapter 4 Divide-and-Conquer

VILNIUS UNIVERSITY MAŽVYDAS MACKEVIČIUS COMPUTER MODELING OF CHEMICAL SYNTHESIS AT HIGH TEMPERATURES

VILNIAUS UNIVERSITETAS. Dmitrij Celov LAIKO EILUČIŲ AGREGAVIMAS, DEAGREGAVIMAS IR TOLIMA PRIKLAUSOMYBĖ.

Optimal Agreement in a Scale-Free Network Environment

VIEŠŲJŲ PASLAUGŲ PERKöLIMO IŠ TRADICINöS Į ELEKTRONINĘ TERPĘ BRANDOS LYGIO VERTINIMAS

Geografinė informacinė sistema (GIS) galimybės mokymui (si) ir kūrybai. Dr. Jurgita Rimkuvienė

Transcription:

VGTU Matematinio modeliavimo katedra VGTU SC Lygiagrečiųjų skaičiavimų laboratorija Paskaitų kursas. 2-oji dalis.

Turinys 1 Algoritmų sudarymo principai ir metodai

Variantų perrinkimas Tai bendras daugelio uždavinių sprendimo algortimų sudarymo principas, kai sprendinį galima rasti patikrinus baigtinį variantų skaičių. Šis metodas ypač išpopuliarėjo, kai atsirado kompiuteriai. Sudarant konkretų algoritmą, iškyla 2 uždaviniai: 1 Kaip gauti visus įmanomus variantus? 2 Kaip sumažinti tikrinamų variantų skaičių, nes tiesioginis (pilnas) visų variantų patikrinimas gali būti praktiškai neįvykdomas net su greičiausiais superkompiuteriais? Šių uždavinių sprendimui naudojami įvairiausi metodai: 1 specialūs kombinatorikos algoritmai, rekursija,... 2 šakų ir rėžių, dinaminio programavimo metodai, euristikos. Atvirkštinis pavyzdys: informacijos kodavimas ir jos dešifravimas. Informacija turi būti užkoduota taip, kad jos dešifravimui nebūtų galima sudaryti algoritmo su mažu variantų skaičiumi.

Rekursijos metodas Rekursija yra plačiai naudojama apibrėžiant matematinius objektus, sudarant bei realizuojant įvairiausius algoritmus. Rekursijos schema Objektas, priklausantis nuo parametro, yra apibrėžiamas naudojant tą patį objektą ar objektus, tik su kitomis parametro reikšmėmis. Nurodoma rekursijos pabaiga ir nustatomos pradinės sąlygos. Šių sąlygų skaičius sutampa su rekursijos gyliu. Pavyzdys. Fibonačio skaičiai (it. Leonardo Fibonaci). Aptinkami įvairiuose informatikos algoritmuose. Jie apibrėžiami tokiu būdu: { fn 1 + f n 2, jei n > 1, f n = f 0 = 1, f 1 = 1.

Rekursinis Fibonačio skaičių radimo algoritmas Kai objektas (uždavinys) apibrėžiamas rekursijos pagalba, lengvai gaunamas objekto radimo (uždavinio sprendimo) rekursinis algortimas. int Fib (n) begin (1) if ( n < 2 ) return (1); else (2) return end if end Fib ( Fib(n-1) + Fib(n-2) Rekursinio algoritmo vykdymo eiga, kai n = 4 ir n = 20: ) ; Daug kartų skaičiuojame tas pačias reikšmes!

Rekursinio Fibonačio skaičių algoritmo sudėtingumas Bazine algoritmo operacija laikykime sudėtį ir ignoruokime papildomas sąnaudas, atsirandančias realizuojant rekursijos kreipinius (praktijoje vis dėlto šios sąnaudos pasirodo gana didelės). Gauname tokią rekurentinę lygtį ir pradines sąlygas: T(n) = T(n 1) + T(n 2) + 1, T(0) = 1, T(1) = 1. Atlikę skaičiavimus, randame funkciją T(n): ( 1 + 5 T(n) = c 2 ) n + (2 c) ( 1 5 2 ) n ( 1 + 5 ) n 1 c. 2 Taigi rekursinis Fibonačio algoritmas yra eksponentinio sudėtingumo. Padidėjus vienetu duomenų skaičiui n, algoritmo vykdymo eiga pailgėja (1 + 5)/2 = 1, 618 kartų.

Rekursinio Fibonačio skaičių radimo algoritmo skaičiavimo eksperimentas Šią teorinę išvadą patvirtina ir atlikto skaičiavimo eksperimento rezultatai: n skaičiavimo laikas T n ρ n = T n T n 1 40 2,88 1,610 41 4,68 1,625 42 7,57 1,617 43 12,25 1,618 Atlikta analizė rodo, kad dideliems n, rekurisnis algoritmas praktiškai nenaudotinas (T(100) 317000 metų). Kaip dar galima rasti Fibonačio skaičius?

Iteracinis Fibonačio skaičių radimo algoritmas Fibonačio skaičius galime rasti ir iteraciniu algoritmu: FibIter (n) begin (1) f2 = 1; f1 = 1; Fib = 1; (2) for ( i = 2; i <= n ; i++ ) do (3) Fib = f2 + f1; (4) f1 = f2; (5) f2 = Fib; end do (6) return (Fib); end FibIter Iteracinio algoritmo sudėtingumas: T(n) = n 1. Šis pavyzdys rodo, kad rekursija ne visada naudotina net ir tada, kai sprendžiame uždavinius, apibrėžtus rekursijos būdu. Reikia stengtis sudaryti nerekursinį algoritmą!

Kada reikalinga rekursija? Naudojant rekursiją, patogu kontroliuoti užduočių atlikimo eiliškumą, kai to reikalauja sprendžiamas uždavinys. Pavyzdžiui, dvejetainio medžio viršūnių aplankymo algoritmai: prefix, infix ir postfix. Prefix (node* tree) begin (1) if ( tree!= NULL ) (2) print(tree->data); (3) Prefix (tree->left); (4) Prefix (tree->right); end if end Prefix Infix (node* tree) begin (1) if ( tree!= NULL ) (2) Infix (tree->left); (3) print(tree->data); (4) Infix (tree->right); end if end Infix Postfix (node* tree) begin (1) if ( tree!= NULL ) (2) Postfix (tree->left); (3) Postfix (tree->right); (4) print(tree->data); end if end Postfix Pavyzdys. Tarkime, aritmetinė išraiška (a b c)(d e + f ) saugoma dvejetainiame medyje. Tada, naudodami Prefix, Infix ir Postfix algoritmus, gauname tokias šios išraiškos formas: a) prefix: a bc + def, b) infix: a b c d e + f, c) postfix: abc de f +.

Variantų perrinkimas grįžtant atgal Rekursija yra labai naudinga sprendžiant uždavinius variantų perrinkimu su grįžimu atgal (angl. backtrack). Pavyzdžiui, 1) Kaip pereiti per labirintą? 2) Žirgo maršrutas šachmatų lentoje? Sudarysime rekursinį algortimų šabloną (angl. template) tokių uždavinių sprendimui.

Variantų perrinkimo šablonas grįžtant atgal Sprendžiant konkretų uždavinį turime apibrėžti duomenų struktūrą pozicija, kurioje saugosime informaciją apie uždavinio sprendimo eigą (pvz., praeitą maršrutą labirinte arba šachmatų lentoje). Sprendinio paieška tęsiama iš P taško (pvz., P - lentos langelis). Turime apibrėžti funkciją S=BandymųAibė(P, pozicija), kuri generuoja visus naujus ėjimus, kuriuos galima atlikti iš taško P. Leistinų ėjimų aibę S apibrėžia uždavinio sąlygos ir duomenų struktūroje pozicija saugoma informacija apie jau aplankytas paieškos vietas. Cikle pasirenkame vieną po kito ėjimus iš S, kiekvienam gauname naują tašką U, kurį įtraukiame į pozicija, ir gautai naujai pozicijai rekursyviai kviečiame pagrindinę algoritmo funkciją (variantų perrinkimo šabloną). Jei padarę kažkurį ėjimą gauname, kad naujos pozicijos S yra tuščia arba netiko nei vienas iš naujos S ėjimų (pranešime apie tai grąžindami reikšmę 0), tai turime grįžti atgal, atstatyti seną poziciją (SenaPozicija(U, pozicija)) ir tikrinti kitą leistiną ėjimą. Kai surandame sprendinį RadomeSprendinį (pozicija) == taip, grąžiname reikšmę 1, taip panešdami šią funkciją iškvietusiai funkcijai, kad sprendinys rastas ir ji irgi gali nutraukti savo darbą grąžindama 1.

Rekursinis algortimų šablonas int Tikrink (int n, Point P, Inf pozicija) begin (1) if ( RadomeSprendinį (pozicija) == taip ) then (2) Spausdink (pozicija); (3) return(1); (4) else (5) S = BandymųAibė(P, pozicija) (6) while ( S ) do (7) U = NaujasBandymas(S); (8) NaujaPozicija(U, pozicija); (9) if ( Tikrink (n+1, U, pozicija) == 1 ) return (1); (10) else (11) SenaPozicija(U, pozicija); end if end do (12) return (0); end if end Tikrink

Daugelio uždavinių efektyvius sprendimo algoritmus sudarome tokiu metodu: 1 Uždavinį skaidome į kelis mažesnius uždavinius. 2 Randame šių uždavinių sprendinius. 3 Iš jų sudarome viso uždavinio sprendinį. Dalinius uždavinius vėl galime spręsti tokiu pačiu metodu. Taip skaidome tol, kol gautieji uždaviniai yra lengvai išsprendžiami. Taip gauname rekursinį skaldyk ir valdyk metodo (angl. divide and conquer) algoritmą. Sprendžiant konkretų uždavinį reikia apibrėžti, kaip realizuojami šie trys žingsniai. Tai galima daryti įvairiai, todėl dažnai tam pačiam uždaviniui skaldyk ir valdyk metodu galime sudaryti kelis skirtingus sprendimo algoritmus.

Rekursinių skaldyk ir valdyk algortimų šablonas Sprendžiame uždavinį, kurį apibūdina duomenų struktūrą A. SprendTipas SkaldykIrValdyk (Inf A) begin (1) if ( A > ε ) then (2) (A 1, A 2,..., A M ) = Skaldyk (A); (3) for all ( A j, j=1, 2,, M ) do (4) S j = SkaldykIrValdyk (A j ); end do (5) S = Valdyk (S 1, S 2,..., S M ); else (6) S = Sprendinys(A) end if (7) return (S); end SkaldykIrValdyk

Rekursinių skaldyk ir valdyk algortimų sudėtingumas Tarkime, kad n dydžio uždavinį dalijame į a mažesnių uždavinių, kurių dydis yra n/b, o atskirų sprendinių sujungimo sąnaudos yra d(n). Kai uždavinys yra mažas, t. y. n = 1, jį išsprenžiame kokiu nors paprastu algoritmu, o veiksmų skaičių žymėsime c. Tokio algoritmo sudėtingumo funkcija tenkina uždavinį: c, jei n = 1, T(n) = at(n/b) + d(n), jei n > 1. Kai n = b m, jo sprendinį jau apskaičiavome: T(n) = ca m + m 1 j=0 aj d(b m j ). Jei, a = 2, b = 2, d = gn, tai skaldyk ir valdyk algoritmo sudėtingumo funkcijat(n) = O(n log n).

Pavyzdys. Dvieju gretimų taškų radimas. Turime n = 2 m taškų aibę P(n) = {P j = (x j, y j ), j = 1, 2,..., n}. Atstumą tarp dviejų taškų P i ir P j apibrėžiame lygybe d(p i, P j ) = ( (x i x j ) 2 + (y i y j ) 2) 1/2. Reikia rasti tokius du taškus P q ir P r, tarp kurių atstumas yra mažiausias d(p q, P r ) = min d(p i, P j ). 1 i,j n Koks yra pilno taškų porų perrinkimo algoritmo sudėtingumas? Iš viso galime sudaryti n(n 1) 2 skirtingas taškų poras, todėl tokio algoritmo sudėtingumas yra O(n 2 ).

Skaldyk ir valdyk metodu sudarykime šio uždavinio sprendimo algortimą. Sunumeruokime taškus koordinatės x didėjimo tvarka: x 1 x 2... x n. Padalinkime visus taškus į dvi vienodo dydžio aibes: (n ) { P L = Pj, j = 1, 2,..., n }, 2 2 (n ) { P R = Pj, j = n 2 2 + 1, 2,..., n}. Tada teisingas vienas iš šių teiginių: 1 Abu taškai P q, P r priklauso aibei P L ( n 2 ). 2 Abu taškai P q, P r priklauso aibei P R ( n 2 ). 3 Taškas P q priklauso aibei P L ( n 2 ), o taškas Pr priklauso aibei P R ( n 2 ). Taigi, galime taikyti rekursinių skaldyk ir valdyk algortimų šabloną.

float GretimiTaškai (Set P, int n) begin (1) if ( n > 2 ) (2) p L = GretimiTaškai (P L, n 2 ); (3) p R = GretimiTaškai (P R, n 2 ); (4) p T = min(p L, p R ); (5) p = Pasienis (P L, P R, p T ); else (6) p = d (P 1, P 2 ); end if (7) return (p); end GretimiTaškai

Dabar pateiksime procedūros Pasienis realizaciją. Užtenka nagrinėti tik taškus, priklausančius pasienio juostai: P B (n) = {P j : x n/2+1 p T < x j < x n/2 + p T, j = s, s + 1,..., f }. float Pasienis (Set P L, Set P R, float p T ) begin (1) for (i=s; i <= n/2; i++) do (2) for (j=n/2+1; x i x j < p T && j <= f; j++) do (3) p = d (P i, P j ); (4) p T = min(p, p T ); end do end do (5) return (p T ); end Pasienis

(angl. branch and bound method) Perrinkant variantus, skaidant ir sprendžiant mažesnius po-uždavinius, labai svarbu kuo anksčiau išskirti tuos variantus (po-uždavinius), kuriems uždavinio sprendinys tikrai nepriklauso, ir šių variantų (po-uždavinių) toliau nenagrinėti. yra bendras metodas, nurodantis kaip konstruoti tokius sprendimo algoritmus globaliosios optimizacijos uždaviniams. Nagrinėsime funkcijos f (X) minimizavimo uždaroje ir baigtinėje srityje D uždavinį: f (X 0 ) = min X D f (X). Jį žymėsime P(f, D). D vadinama leistinųjų sprendinių aibe (paieškos aibe) ir gali būti įvairiausių prigimčių.

Šakų ir rėžių metodo pagrindiniai žingsniai Šakų ir rėžių metode yra 2 pagrindiniai žingsniai, kurie turi būti apibrėžti sudarant konkretų tam tikro uždavinio sprendimo algoritmą. 1. Skaidymo (angl. branching) žingsnis. Leistinųjų sprendinių aibę skaidome į baigtinį skaičių mažesnių aibių: m D = D i. i=1 Tada funkcijos f (X) minimumo paieškos algoritmą patogu vaizduoti medžio duomenų struktūroje. Medžio šaknyje užrašome uždavinį P(f, D), šaknies m vaikai apibrėžia uždavinius P(f, D i ), t. y. funkciją f (X) minimizuojame srityse D i. Toks skaidymo procesas tęsiamas, kol nesunkiai apskaičiuojame gautojo uždavinio sprendinį.

2. Rėžių apskaičiavimo (angl. bounding) žingsnis. Algoritme turime apibrėžti, kaip efektyviai apskaičiuoti funkcijos f (X) minimumo srityje D i apatinį LB(f, D i ) ir viršutinį UB(f, D i ) rėžius: LB(f, D i ) min X D i f (X) UB(f, D i ). Tada, žinodami UB(f, D i ), galime apskaičiuoti minimalios reikšmės f (X 0 ) viršutinį rėžį UB(f, D) visoje aibėje D: UB(f, D) = min 1 i m UB(f, D i). Žinodami šiuos rėžius, dažnai galime gerokai sumažinti nagrinėjamų sričių skaičių. Jeigu srityje D i apatinis f (X) reikšmių rėžis LB(f, D i ) yra didesnis už UB(f, D): LB(f, D i ) > UB(f, D), tai tokios srities toliau nebetiriame, nes joje tikrai nėra optimalaus sprendinio.

Šakų ir rėžių metodo algortimo šablonas Sudarykime šakų ir rėžių metodo algortimo šabloną. Tegu visos užduotys saugomos sąraše L. O geriausias šiuo metu žinomas sprendinys saugomas struktūroje S. S galėtų būti ir sąrašas, jei reikia išsaugoti visus gaunamus galimus sprendinius. Naują užduotį išimame iš sąrašo L, naudodami parinkimo taisyklę (angl. selection rule). Dažniausiai naudojamas taisykles aptarsime vėliau.

begin BranchAndBound () m (1) Išskaidome D = i=1 D i, apskaičiuojame rėžius LB(D i ), UB(D i ), užduotis P(f, D i ) įtraukiame į sąrašą L = {P(f, D i ), 1 i m}, S =, apskaičiuojame UB(D) = min 1 i m UB(D i ). (2) while (L ) do (3) Naudodami ( parinkimo ) taisyklę išimame užduotį P(f, D i ) L (4) if LB(Di ) < UB(D) then m (5) Išskaidome aibę D i = j=1 D ij (6) for all (D ij, j = 1, m) do (7) Apskaičiuojame ( rėžius UB(D ij ) ir ) LB(D ij ) (8) UB(D) = min UB(D), UB(D ij ) //Galimai patiksliname rėžį (9) ( ) if LB(D ij ) < UB(D) then (10) if (P(f, D ij ) yra lapas ) then //Nebeskaidoma sritis (11) S = Sprendinys(D ij, S) //Ar D ij turi geresnį sprendinį (12) else // negu turimas S? (13) L := L P(f, D ij ) //Įtraukiame į sąrašą end if end if end do end if end do end BranchAndBound

Dažniausiai naudojamos parinkimo taisyklės 1. Naujausia užduotis. Tiriame užduotį, kurią vėliausiai sugeneravome. Naudodami tokią strategiją, greitai judame į variantų medžio gilumą ir minimizuojame saugomų užduočių skaičių (angl. depth-first search). Sąrašą L realizuojame naudodami dėklo (angl. stack) duomenų struktūrą. 2. Perspektyviausia užduotis. Tiriame užduotį P(f, D i ), kurios sprendinių apatinis įvertis LB(f, D i ) yra mažiausias (angl. best-first search). Tikimės, kad, skaidydami šią užduotį, greičiau rasime gerus sprendinio artinius arba pavyks iš esmės sumažinti viršutinį sprendinio įvertį UB(f, D). Tada smarkiai sumažės ir nagrinėjamų variantų skaičius. Sąrašą L realizuojame naudodami piramidės (angl. heap) duomenų struktūrą.

Dažniausiai naudojamos parinkimo taisyklės 3. Mažiausio lygio užduotis. Tiriame užduotį P(f, D i ), kurios lygis medyje yra mažiausias (angl. breath-first search). Naudodami šią strategiją, tolygiai nagrinėjame visą leistinųjų sprendinių aibę, t. y. tikimės išvengti detalaus nereikalingų lokaliųjų minimumų nagrinėjimo. Sąrašą L realizuojame naudodami eilės (angl. queue) duomenų struktūrą.

Pavyzdys. Globalus Lipšico funkcijos minimumas. Rasime vienmatės funkcijos f (x) globalų minimumą uždarame intervale [a, b]: f (x 0 ) = min x [a,b] f (x). Tarsime, kad f yra Lipšico funkcija, t. y. egzistuoja konstanta L, leidžianti įvertinti funkcijos reikšmių skirtumus: f (x) f (y) L x y, x, y [a, b]. Visos tolydžiai diferencijuojamos funkcijos yra ir Lipšico funkcijos, konstantą L randame imdami funkcijos išvestinės reikšmių modulio viršutinį rėžį: f (x) L, x [a, b]. Visai nebūtina rasti tikslųjį rėžį L, bet kuo mažesnė L reikšmė, tuo efektyvesnis šakų ir rėžių algoritmas. Pvz., y = sin x, L =?

Funkcijos minimumo radimo šakų ir rėžių algoritmas Pagal šakų ir rėžių metodą turime apibrėžti skaidymo žingsnį ir rėžių apskaičiavimo taisykles. 1. Skaidymo žingsnis. Uždavinio P(f, [a i, b i ]) intervalą skaidome į du naujus lygius intervalus: [a i, b i ] = [a i, c i ] [c i, b i ], c i = a i+b i 2. Taip gauname du naujus mažesnius uždavinius P(f, [a i, c i ]) ir P(f, [c i, b i ]). Jei b i a i 2 < ε, kur ε reikalaujamas tikslumas, tai intervalas toliau nebeskaidomas, o gaunamas uždavinio P(f, [a i, b i ]) sprendinys s i tikslumu ε: f (s i ) = min(f (a i ), f (c i ), f (b i )) ir palyginamas su šiuo metu turimu sprendiniu s: f (s) = min(f (s i ), f (s)).

Funkcijos minimumo radimo šakų ir rėžių algoritmas 2.1 Viršutinio įverčio skaičiavimo taisyklė. Uždavinio P(f, [a i, b i ]) sprendinio x 0i viršutinį rėžį UB(f, [a i, b i ]) galima gauti taip: f (x 0i ) = min f (x) min(f (a i), f (c i ), f (b i )) = UB(f, [a i, b i ]). x [a i,b i ] Galima imti ir daugiau intervalo [a i, b i ] vidinių taškų. 2.2 Apatinio įverčio skaičiavimo taisyklė. Uždavinio P(f, [a i, b i ]) sprendinio x 0i apatinį rėžį LB(f, [a i, b i ]) randame, taikydami Lipšico funkcijų apibrėžimą: f (x 0i ) f (c i ) L x 0i c i L b i a i 2. f (x 0i ) f (c i ) L b i a i 2 = LB(f, [a i, b i ]).

Lošimų teorijos algoritmai Daugelį žaidimų galime aprašyti tokia bendra schema: 1. Lošėjai paeiliui atlieka leistinus žaidimo ėjimus. Visą žaidimo eigą aprašome naudodami medžio duomenų struktūrą. Medžio viršūnėje saugome pradinę žaidimo poziciją. Viršūnės vaikai apibrėžia pozicijas, kurias gauname atlikę pirmąjį ėjimą ir t. t. Medžio lapuose saugome baigiamąsias žaidimo pozicijas. 2. Remdamiesi žaidimo taisyklėmis, galime įvertinti visas pabaigos pozicijas tam tikru svoriu. Pavyzdžiui, šachmatuose visas pozicijas, kuriose laimi baltosios figūros, įvertiname 1, juodųjų figūrų laimėtas pozicijas vertiname (-1), o pozicijas, kai žaidimas baigėsi lygiosiomis, įvertiname 0. 3. Lošėjai siekia priešingų tikslų: vienas nori, kad galutinės žaidimo pozicijos svoris būtų didžiausias, o antrasis stengiasi pasiekti mažiausio svorio baigiamąją poziciją.

Variantų perrinkimo algortimas su grįžimu atgal Apskaičiuojame optimalų rezultatą, kurį lošėjas gali pasiekti iš duotosios pozicijos A. Parametras tikslas (lygus MAX arba MIN) apibrėžia lošėjo strategiją. float Lošimas (pozicija A, int tikslas) begin (1) if ( A == pabaigospozicija ) then (2) return Vertė(A); (3) else (4) if ( tikslas == MAX ) then (5) v = - ; (6) for all ( B Vaikai(A) ) do (7) v = max ( v, Lošimas (B, MIN) ); end do (8) else (9) v = ; (10) for all ( B Vaikai(A) ) do (11) v = min ( v, Lošimas (B, MAX) ); end do end if (12) return v; end if end Lošimas

Pavyzdys: lošimo uždavinio sprendimas su variantų perrinkimo algoritmu su grįžimu atgal Pradėkite nuo viršaus ir gaukite visų viršūnių svorius.

taikymas lošimų uždaviniams Nagrinėjamų variantų skaičių galime sumažinti taikydami šakų ir rėžių metodą. Pritaikę jį lošimų algoritmams, gauname taip vadinama α β metodą. Šio metodo idėja: vertindami viršūnės svorį, jį lyginame ir su viršūnės tėvo naujausiu įverčiu. Tarkime, kad viršūnės v tikslas yra MAX, o jos tėvo viršūnės w (jos strategija MIN) įvertis lygus α. Jeigu, tikrindami v vaikus, radome variantą, kurio svoris β α, tai nutraukiame tolesnę viršūnės v vaikų analizę, nes v pomedyje negali egzistuoti viršūnės w optimali žaidimo strategija. Taigi lošėjas, patekęs į w poziciją, niekada nesirinks ėjimo, vedančio į viršūnę v. Panašiai, jei viršūnės v tikslas yra MIN, tai jos vaikų analizę nutraukiame, jei radome variantą, kurio svoris β α.

pav. : Lošimo uždavinio sprendimas α β metodu. Pilka spalva pažymėtos tos medžio šakos ir viršūnės, kurių nereikia tikrinti

α β algoritmas float αβ (pozicija A, int tikslas, double a) begin (1) if ( A == pabaigospozicija ) then (2) return Vertė(A); else (3) B = KitasVaikas(A); (4) if ( tikslas == MAX ) then (5) v = - ; (6) while (v < a) && (B ) do (7) v = max (v, αβ (B, MIN, v) ); (8) B = KitasVaikas(A); end do else (9) v = ; (10) while (v > a) && (B ) do (11) v = min (v, αβ (B, MAX, v) ); (12) B = KitasVaikas(A); end do end if (13) return v; end if end αβ

Viso variantų perrinkimo algoritmai dažnai neefektyvūs dėl labai didelio nagrinėjamų variantų skaičiaus. Analizuodami daugelį tokių algoritmų matome, kad skaičiuojant daug kartų sprendžiame tas pačias užduotis. Šio trūkumo neturi dinaminio programavimo metodas, kurį pasiūlė Belmanas (R. Bellman).

Dinaminio programavimo metodo sąlygos taikytinas tada, kai tenkinamos tokios sąlygos: 1 Algoritmo vykdymo metu generuojamos užduočių aibės esmingai persidengia, todėl daug kartų sprendžiame tas pačias užduotis. Dinaminio programavimo metode įsimename jau spręstų užduočių sprendinius ir sprendžiame tik naujus uždavinius. 2 Uždavinys tenkina Belmano sąlygą, kad optimalus sprendinys yra sudarytas iš atskirų mažesnių užduočių optimalių sprendinių. Šią sąlygą užrašome rekurentinės lygybės forma, ji smarkiai sumažina nagrinėjamų variantų skaičių.

Dinaminio programavimo metodo eiga Skaldyk ir valdyk algoritme užduotys generuojamos iš viršaus į apačią, t. y. pradinis uždavinys skaidomas į kelias mažesnes užduotis, kurios toliau dalijamos į mažesnes. Dinaminio programavimo metode uždavinį pradedame spręsti nuo mažiausių ir lengvai išsprendžiamų užduočių, jų rezultatus išsaugome (jei reikia) ir naudojame spręsdami didesnes užduotis. Taip surandame viso uždavinio sprendinį. Realizuodami dinaminio programavimo metodą nagrinėjame tik tuos variantus, kurių gali prireikti optimaliai strategijai sudaryti. Taip sataupome laiką, bet atsiranda papildomos atminties sąnaudos. Tokios strategijos pranašumus jau matėme nagrinėdami kai kuriuos rekursinius algoritmus, pvz., Fibonačio skaičius.

Dinaminio programavimo metodo taikymo pavyzdys Pateiksime dar vieną panašų pavyzdį, kai ieškome, kiek yra skirtingų būdų išrinkti k daiktų iš n daiktų aibės. Atsakymą apibrėžia derinių kombinatorinė formulė C k n = n! k!(n k)!, tačiau ji netinka dideliems n, nes faktorialas - labai greitai didėjanti funkcija. Pvz., 13! = 6.227.020.800 > 2 32 = 4.294.967.296, t.y. naudojant unsigned integer 32-bitų duomenų tipą negalime išreikšti n!, kai n 13. Tačiau šio duomenų tipo kintamajame galima išsaugoti C k n iki n = 34: C 17 34 = 2.333.606.220.

Rekursyvus C k n skaičiavimo algoritmas Cn k apskaičiavimui galime naudoti rekursinę lygybę: 1, k = 0, Cn k = Cn 1 k 1 + C n 1 k, 0 < k < n, 1, k = n, kurios teisingumą patikriname atlikę elementarius veiksmus. int BinKoef (int n, int k) begin (1) if ( k == 0 n == k ) then (2) return (1); (3) else (4) return ( BinKoef(n-1, k-1) + BinKoef(n-1, k) ); end if end BinKoef

Įvertinsime tokio algoritmo sudėtingumo funkciją T(n). Tegul, skaičiuodami binominį koeficientą Cn k, atliekame P(n, k) aritmetinių veiksmų. Tada T(n) = max 0 k n P(n, k). Iš pateiktojo algoritmo gauname tokius sąryšius: 1, k = 0, P(n, k) = P(n 1, k) + P(n 1, k 1), 0 < k < n, 1, k = n, todėl P(n, k) = C k n. Jos reikšmė didžiausia, kai k = n/2. Taigi rekursinio algoritmo sudėtingumo funkcija T(n) = C n/2 n = n! ( (n/2)! ) 2.

Pasinaudoję Stirlingo formule, gauname, kad n! = ( n ) n ( ) ( n ) n/2 ( ) 2πn 1+O(1/n), (n/2)! = πn 1+O(1/n), e 2e todėl teisingas asimptotinis įvertis T(n) = Θ(2 n / n). Matome, kad algoritmo veiksmų skaičius didėja eksponentiniu greičiu, taigi rekursyvus algoritmas yra paprastas, bet labai neefektyvus. Lentelėje pateikti skaičiavimo eksperimento rezultatai: T n yra binominio koeficiento Cn n/2 skaičiavimo laikas, ρ n = Tn T n 1. n T n ρ n 32 18,5 2,015 33 35,5 1,919 34 71,3 2,008 35 138 1,935

Dabar pateiksime algoritmą, kurį gauname dinaminio programavimo metodu. Ir šis algoritmas naudoja rekursinę formulę: C k n = C k 1 n 1 + C k n 1, kuri ir yra binominio koeficiento Belmano sąlyga. Skaičiuoti pradedame nuo mažiausio koeficiento C0 0 ir didiname parametro n reikšmę. Pagalbinių koeficientų reikšmes saugome matricoje H, turinčioje (n + 1) eilutę ir (k + 1) stulpelį.

Dinaminio programavimo binominių koeficientų algoritmas int BinKoef2 (int n, int k) begin (1) for ( i=0; i<= n; i++ ) do (2) for ( j=0; j<= min(i, k); j++ ) do (3) if ( j == 0 j == i ) then (4) H(i,j) = 1; (5) else (6) H(i,j) = H(i-1,j-1) + H(i-1,j); end if end do end do (7) return ( H(i,k) ); end BinKoef2

Dinaminio programavimo algoritmo sudėtingumas Naujuoju algoritmu binominį koeficientą apskaičiuojame, atlikę (n k)(k + 1) + (k+2)(k+1) 2 veiksmų. Šis skaičius didžiausias, kai k = n 2 (prisiminkite lygybę Cn k = Cn n k ). Taigi dinaminio programavimo algoritmo sudėtingumo funkcija yra kvadratinė T(n) = 3n 2 /8 + O(n). Kokios yra dinaminio programavimo algoritmo atminties sąnaudos? Ar galima jas sumažinti?

Euristiniai algoritmai Daugeliui uždavinių variantų perrinkimo algoritmų sudėtingumas aprašomas nepolinomine (pvz., eksponentine) funkcija. Todėl dažnai visus variantus perrinkti neįmanoma net ir su šiuolaikiniais superkompiuteriais. Kai nėra žinomas pakankamai greitas algoritmas, randantis tikslųjį (optimalųjį) uždavinio sprendinį, naudojami algoritmai, gaunami atsisakius sprendinio tikslumo reikalavimo. Algoritmas vadinamas euristiniu arba tiesiog euristika (angl. heuristic), jei jis pakankamai greitai randa priimtiną, bet nebūtinai tikslųjį (optimalųjį) uždavinio sprendinį. Euristikos dažniausiai būna polinominio sudėtingumo. Tai pasiekiama patikrinant ne visus, o tik perspektyviuosius (euristikos apibrėžimo prasme) variantus.

Taip sudarytas algoritmas laikomas euristiniu, net jei jis praktiškai grąžina tiksliuosius sprendinius, bet nėra formalaus įrodymo, kad taip bus visada (t.y. bet kokiems uždavinio duomenims). Pavyzdžiui, sprendžiant paieškos ar optimizacijos uždavinius, populiarūs algoritmai gaunami naudojant godžiąją (angl. greedy) strategiją. Daugeliui uždavinių gaunami pagal šią strategiją taip vadinami godieji algoritmai yra tik euristikos, t.y. bendruoju atveju negarantuoja tikslaus (optimalaus) sprendinio radimo. Tačiau egzistuoja svarbus taikomieji uždaviniai, kurių sprendimui sukurti godieji algoritmai yra tikslieji algoritmai, t.y. jie randa tiksliuosius atitinkamų uždavinių sprendinius ir tai yra formaliai įrodyta.

Godžiųjų algoritmų sudarymo bendroji schema Uždavinio sprendinio paiešką išskaidome į n žingsnių. Kiekvienu žingsniu renkamės iš nedidelio baigtinio skaičiaus variantų m. Godieji algoritmai (angl. greedy) gaunami renkantis lokaliai geriausią variantą duotojo žingsnio metu (t.y. tą iš m, kuris šiuo žingsniu atneša didžiausią pelną). Aišku, kad tokia lokali pasirinkimo strategija nebūtinai yra optimali viso uždavinio sprendimo atžvilgiu. Bet jos realizavimo sąnaudos yra labai mažos: lokalaus pasirinkimo sudėtingumas O(m), o viso godžiojo algoritmo sudėtingumas tik O(nm) veiksmų.

Diskretusis kuprinės užpildymo uždavinys (angl. 0 1 knapsack problem) Tarkime, kad turime n daiktų, kurių tūriai yra v 1, v 2,..., v n, o kaina p 1, p 2,..., p n. Reikia rasti tokį daiktų rinkinį, kuris tilptų į V tūrio kuprinę, o daiktų vertė būtų didžiausia. Sprendžiame optimizavimo uždavinį: max (x 1p 1 + x 2 p 2 +... + x n p n ), (x 1,...,x n) D D = {x 1 v 1 + x 2 v 2 +... + x n v n V, x j {0, 1}}. Tiesioginio pilno perrinkimo algoritmo (angl. brute-force search) sudėtingumas - O(2 n ).

Diskretusis kuprinės uždavinys. Godieji algoritmai. Pirmiausia pagal bendrąją godžiųjų algoritmų sudarymo schemą išskaidome sprendinio paiešką į n žingsnių: kiekviename žingsnyje dedame į kuprinę po vieną daiktą (jis ten ir lieka iki algoritmo pabaigos). Tada i-ame žingsnyje turime rinktis iš tų likusių n i daiktų, kurie telpa į dar neužpildytą kuprinės tūrį. Lokaliai geriausio varianto (t.y. daikto) pasirinkimą galima apibrėžti 3 būdais: 1 pagal mažiausią tūrį - v j, 2 pagal didžiausią kainą - p j, 3 pagal didžiausią santykinę vertę - p j v j. Visi 3 būdai duoda leistinus sprendinius, tačiau nei vienas negarantuoja tikslaus (optimalaus) sprendinio. Kuris būdas duos geresnį sprendinį priklauso nuo uždavinio duomenų.

Panagrinėkime pavyzdį (kuprinės tūris V = 100): Godieji sprendiniai pagal Optimalus p i i v i p i kainą tūrį s. vertę sprendinys v i 1 100 40 0.4 1 0 0 0 2 50 35 0.7 0 0 1 1 3 45 18 0.4 0 1 0 1 4 20 4 0.2 0 1 1 0 5 10 10 1.0 0 1 1 0 6 5 2 0.4 0 1 1 1 sprendinio tūris 100 80 85 100 sprendinio vertė 40 34 51 55 Taigi diskrečiajam kuprinės užpildymo uždaviniui sudaryti godieji algoritmai yra tik euristikos.

Sudarykite godaus algoritmo pseudo-kodą ir raskite jo sudėtingumą. Kaip kitaip galima rasti optimalų uždavinio sprendinį? Tegu A(n, V ) yra maksimali vertė daiktų, išrinktų iš n, tokių, kad jų bendras tūris neviršija V. Tada A(n, V ) gali būti rastas pagal rekursinį sąryšį: 0, jei n = 0, 0, jei V = 0, A(n, V ) = A(n 1, V ), jei v n > V, max {A(n 1, V ), p n + A(n 1, V v n )}, jei v n V. Sudarykite dinaminio programavimo metodo algoritmą ir įvertinkite jo sudėtingumą.

Tolydusis (angl. fractional) kuprinės uždavinys Užduoties sąlyga tokia pati, kaip diskrečiajame uždavinyje, tik dabar daiktai yra dalūs ir galime imti jų dalį, t.y. 0 x i 1, i = 1, 2,..., n. Pavyzdžiui, tai gali būti aukso plytelės (diskretusis užd.) ir aukso smėlis (tolydusis), supakuotas ir birusis cukrus. Tada naudojame tokį godųjį algoritmą: surūšiuojame daiktus pagal jų santykines vertes ir kiekviename žingsnyje imame į kuprinę patį vertingiausią likusį daiktą (visą arba dalį, kiek telpa). Nagrinėkime daiktų rinkinį, pateiktą ankstesniame pavyzdyje. Tada į kuprinę nuosekliai įdedame visą 5-ą daiktą (jo tūris 10, o vertė 10), visą 2-ą daiktą (jo tūris 50, vertė 35) ir 40 tūrio vienetų 1-ojo daikto (tūris 40, vertė 40 0.4). Taigi toks krovinys užpildo visą kuprinę, o jo vertė 61.

Godžiųjų algoritmų optimalumas Kada godžiuoju algoritmu visada randame optimalųjį (tikslųjį) uždavinio sprendinį? Turi būti patenkintos dvi sąlygos: 1. (angl. optimal substructure property). Optimalų sprendinį galime apskaičiuoti išskaidę uždavinį į mažesnių (tokių pačių) užduočių seką ir suradę optimalius jų sprendinius. Tai yra dinaminio programavimo metodo Belmano sąlyga. Ji yra būtina, bet jos nepakanka, kaip matėme diskrečiojo kuprinės uždavinio atveju, kai ši sąlyga patenkinta, bet godieji algoritmai yra tik euristikos. Godžiajame algoritme visada renkamės tik lokaliai vertingiausią sprendinį, o dinaminio programavimo metode įvertiname tokio pasirinkimo pasekmes visiems tolesniems variantams. 2. (angl. greedy-choice property). Atliekant lokaliai geriausią (godųjį) pasirinkimą kiekviename žingsnyje išlieka galimybė gauti viso uždavinio optimalųjį sprendinį.

Teorema. Godžiuoju algoritmu randame optimalųjį tolydaus kuprinės užpildymo uždavinio sprendinį. Įrodymas. Jei į kuprinę telpa tik vertingiausias daiktas ar jo dalis, tai godžiojo algoritmo optimalumas yra akivaizdus. Nagrinėkime atvejį, kai v 1 < V. Tada godžiuoju algoritmu pirmajame žingsnyje pasirinkome visą kiekį santykinai vertingiausio daikto - v 1. Tarkime, kad egzistuoja optimalus rinkinys, kuriame šio produkto yra mažiau: w 1 < v 1. Pažymėkime optimalaus rinkinio vertę P O. Tada, išėmę iš optimaliai užpildytos kuprinės (v 1 w 1 ) mažiausiai vertingo k-ojo produkto (k 1) ir įdėję tokį patį kiekį pirmojo produkto, gausime naują rinkinį, kurio vertė lygi

a) P O + (v 1 w 1 )(s 1 s k ) > P O, jei s 1 > s k (s i = p i v i ), t.y. didesnė negu optimalaus rinkinio! Gavome prieštaravimą! b) P O, jei s 1 = s k, t.y. gavome kitą optimalų rinkinį (jų gali būti ne vienas, kai dalies produktų santykinės vertės sutampa), kuriame yra w 1 + (v 1 w 1 ) = v 1 pirmojo produkto. Taigi godžiosios strategijos taikymas pirmajame žingsnyje (v 1 įdėjimas) leidžia rasti optimalų rinkinį. Po pirmojo žingsnio vėl gavome kuprinės užpildymo vertingiausiais produktais uždavinį, tik sumažėjo kuprinės tūris (V v 1 ) ir liko trumpesnis daiktų sąrašas. Remdamiesi matematinės indukcijos metodu, tvirtiname, kad godžiuoju algoritmu randame optimalų sprendinį.