Problem maksimalnog podniza

S Vikipedije, slobodne enciklopedije

U informatici, problem maksimalnog podniza je zadatak pronalaženja neprekidnog podniza, unutar jednodimenzionalnog niza brojeva (mora da sadrži bar jedan pozitivan broj) koji ima najveću sumu. Na primer, za niz brojeva −2, 1, −3, 4, −1, 2, 1, −5, 4, neprekidni podniz sa najvećom sumom je 4, −1, 2, 1, čija suma iznosi 6.

Problem je prvi postavio Ulf Grenander na Braun univerzitetu 1977. godine, kao uprošćeni model za maksimalnu verovatnoću procene šablona u digitalizovanim slikama. Algoritam linearne složenosti pronađen je ubrzo od strane Džej Kadana na Karnegi Melon Univerzitetu.

Kadanov algoritam[uredi | uredi izvor]

Kadanov algoritam se sastoji od pretraživanja vrednosti niza, izračunavajući na svakoj poziciji maksimum podniza zaključno sa tom pozicijom u nizu. Ova suma je ili prazna (u čijem slučaju je vrednost sume 0) ili sadrži jedan element više u odnosu na kraj maksimalnog podniza prethodne pozicije. Ovaj problem može biti rešen sledećim kodom predstavljenim u Pajtonu.

def max_subarray(A):
    max_ending_here = max_so_far = 0
    for x in A:
        max_ending_here = max(0, max_ending_here + x)
        max_so_far = max(max_so_far, max_ending_here)
    return max_so_far

Varijanta problema koja ne dozvoljava nulte dužine podniza kao povratne vrednosti u slučaju da se ceo niz sastoji od negativnih brojeva, može se rešiti sledećim delom koda predstavljenim u programskom jeziku C++.

int sequence(std::vector<int>& numbers)
{
        // Initialize variables here
        int max_so_far  = numbers[0], max_ending_here = numbers[0];

        // OPTIONAL: These variables can be added in to track the position of the subarray
        // size_t begin = 0;
        // size_t begin_temp = 0;
        // size_t end = 0;

        // Find sequence by looping through
        for(size_t i = 1; i < numbers.size(); i++)
        {
                // calculate max_ending_here
                if(max_ending_here < 0)
                {
                        max_ending_here = numbers[i];
                        
                        // begin_temp = i;
                }
                else
                {
                        max_ending_here += numbers[i];
                }

                // calculate max_so_far
                if(max_ending_here >= max_so_far )
                {
                        max_so_far  = max_ending_here;
                        
                        // begin = begin_temp;
                        // end = i;
                }
        }
        return max_so_far ;
}

Algoritam se takođe može lako modifikovati tako da prati početne i krajnje indekse maksimalnog podniza.

Zbog načina na koji ovaj algoritam koristi optimalnu podstrukturu (kraj maksimalnog podniza na svakoj poziciji je izračunat na jednostavan način uz pomoć povezanog ali manjeg potproblema) ovaj algoritam se može predstaviti kao jednostavan primer dinamičkog programiranja.

Složenost Kadanovog algoritma je .

Podeli pa vladaj[uredi | uredi izvor]

Podeli pa vladaj predstavlja algoritam u kojem se veći problem raščlanjuje na više manjih, koji su jednostavniji za sagledavanje i pojedinačno rešavanje. Ovi potproblemi se mogu rešavati paralelno (istovremeno rešavanje dva ili više potproblema) ili jedan za drugim.

Njegova složenost je .

Generalizacija[uredi | uredi izvor]

Slični problemi mogu se postaviti i na višedimenzionalnim nizovima ali je njihovo rešenje komplikovanije. Na primer, Takaoka (2002. godine), Brodal i Jorgensen (2007. godine) pokazali su kako da pronađemo najveću sumu k podnizova jednodimenzionalnog niza optimalne vremenske složenosti .

Literatura[uredi | uredi izvor]

Spoljašnje veze[uredi | uredi izvor]