Suurin osajoukon ongelma - Maximum subarray problem

Image
Visualisointi siitä, miten aliryhmät muuttuvat otoksen alku- ja loppukohtien perusteella. Jokainen mahdollinen viereinen aliryhmä on piste värillisellä viivalla. Pisteen y-koordinaatti edustaa otoksen summaa. Sen x-koordinaatti edustaa näytteen loppua ja vasemmanpuoleisin piste värillisellä viivalla edustaa näytteen alkua. Tässä tapauksessa taulukko, josta näytteet otetaan, on [2, 3, -1, -20, 5, 10].

In Computer Science , The enimmäismäärä Alijärjestelyn ongelma on tehtävänä on löytää vierekkäisiä alaryhmän, jolla on suurin summa, tietyssä yksiulotteisen taulukon A [1 ... n] numeroita. Muodollisesti tehtävä on löytää indeksejä ja joissa siten, että summa

on mahdollisimman suuri. (Jotkut ongelman muotoilut mahdollistavat myös tyhjän aliryhmän huomioimisen; sopimuksen mukaan tyhjän aliryhmän kaikkien arvojen summa on nolla.) Syöttömatriisin A jokainen numero voi olla positiivinen, negatiivinen tai nolla.

Esimerkiksi arvotaulukolle [−2, 1, −3, 4, -1, 2, 1, −5, 4] vierekkäinen alirivi, jolla on suurin summa, on [4, -1, 2, 1] , summa 6.

Jotkut tämän ongelman ominaisuudet ovat:

  1. Jos taulukko sisältää kaikki ei-negatiiviset luvut, ongelma on triviaali; suurin alirivi on koko ryhmä.
  2. Jos taulukko sisältää kaikki ei-positiiviset luvut, ratkaisu on mikä tahansa koon 1 aliryhmä, joka sisältää taulukon maksimiarvon (tai tyhjä aliryhmä, jos se on sallittu).
  3. Useilla eri aliryhmillä voi olla sama enimmäissumma.

Tämä ongelma voidaan ratkaista käyttämällä useita erilaisia ​​algoritmisia tekniikoita, kuten raakaa voimaa, jakamista ja valloitusta, dynaamista ohjelmointia ja lyhentämistä lyhyimmille poluille.

Historia

Ulf Grenander ehdotti vuonna 1977 enimmäisaliryhmäongelmaa yksinkertaistettuna mallina digitaalisten kuvien kuvioiden maksimaalisen todennäköisyyden arvioimiseksi.

Grenander halusi löytää suorakulmaisen alirivin, jossa oli suurin summa, kaksiulotteisesta reaalilukutaulukosta. Raa'an voiman algoritmi kaksiulotteiselle ongelmalle suoritetaan O ( n 6 ): ssa; koska tämä oli kohtuuttoman hidasta, Grenander ehdotti yksiulotteista ongelmaa saadakseen käsityksen sen rakenteesta. Grenander johti algoritmin, joka ratkaisee yksiulotteisen ongelman O ( n 2 ): ssa, mikä parantaa O ( n 3 ): n raa'an voiman käyttöaikaa . Kun Michael Shamos kuuli ongelmasta, hän kehitti yön aikana sille O ( n log n ) jakamis- ja valloitusalgoritmin . Pian tämän jälkeen Shamos kuvasi yksiulotteista ongelmaa ja sen historiaa Carnegie Mellonin yliopiston seminaarissa, johon osallistui Jay Kadane , joka suunnitteli minuutissa O ( n ) -aikaisen algoritmin, joka on mahdollisimman nopea. Vuonna 1982 David Gries sai saman O ( n ) -ajan algoritmin soveltamalla Dijkstran "standardistrategiaa"; Vuonna 1989 Richard Bird johdatti sen puhtaasti algebrallisella manipuloinnilla raa'an voiman algoritmilla käyttäen Bird-Meertensin formalismia .

Grenanderin kaksiulotteinen yleistys voidaan ratkaista O ( n 3 ) -ajalla joko käyttämällä Kadanen algoritmia aliohjelmana tai jakamalla ja valloita -lähestymistavan avulla. Tamaki & Tokuyama (1998) ja Takaoka (2002) ovat ehdottaneet hieman nopeampia etäisyysmatriisin kertolaskuun perustuvia algoritmeja . On olemassa joitakin todisteita siitä, ettei ole olemassa merkittävästi nopeampaa algoritmia; algoritmi, joka ratkaisee kaksiulotteisen enimmäisaliryhmän ongelman O ( n 3 ε ) -ajalla, missä tahansa ε> 0, tarkoittaisi yhtä nopeaa algoritmia kaikkien parien lyhyimpien polkujen ongelmaan.

Sovellukset

Suurimmat osajoukko -ongelmat syntyvät monilla aloilla, kuten genomisen sekvenssin analyysi ja tietokoneen visio .

Genomisessa sekvenssianalyysissä käytetään enimmäisaliryhmäalgoritmeja proteiinisekvenssien tärkeiden biologisten segmenttien tunnistamiseksi. Näihin ongelmiin kuuluvat konservoidut segmentit, GC-rikkaat alueet, tandem-toistot, matalan kompleksisuuden suodatin, DNA: ta sitovat domeenit ja korkean varauksen alueet.

Vuonna konenäkö , maksimi-alijärjestelylle algoritmeja käytetään bittikarttakuvien havaita kirkkain alue kuvassa.

Kadanen algoritmi

Tyhjät alaryhmät hyväksyttiin

Kadanen alkuperäinen algoritmi ratkaisee ongelmaversion, kun tyhjät alisarjat hyväksytään. Se skannaa annetun taulukon vasemmalta oikealle. Kolmannessa vaiheessa se laskee alirivin, jonka suurin summa päättyy kohtaan ; tämä summa pysyy muuttujana . Lisäksi se laskee alirivin, jolla on suurin summa kaikkialla , muuttujana ja helposti saavutettavissa kaikkien tähän mennessä nähtyjen arvojen maksimina , vrt. algoritmin rivi 7. current_sumbest_sumcurrent_sum

Koska silmukka muuttumaton , että th vaiheessa, vanha arvo omistaa suurimman kaikkien summan . Siksi se on maksimi koko summasta . Jälkimmäisen enimmäismäärän laajentamiseksi kattamaan myös tapaus , riittää, kun otetaan huomioon myös tyhjä aliryhmä . Tämä tehdään rivillä 6 määrittämällä uudeksi arvoksi arvo , joka sen jälkeen pitää maksimissaan koko summan . current_sumcurrent_sumcurrent_sumcurrent_sum

Näin ollen ongelma voidaan ratkaista seuraavalla koodilla, joka ilmaistaan ​​täällä Pythonissa :

def max_subarray(numbers):
    """Find the largest sum of any contiguous subarray."""
    best_sum = 0  # or: float('-inf')
    current_sum = 0
    for x in numbers:
        current_sum = max(0, current_sum + x)
        best_sum = max(best_sum, current_sum)
    return best_sum

Tämä algoritmin versio palauttaa arvon 0, jos syöte ei sisällä positiivisia elementtejä (myös silloin, kun syöte on tyhjä).

Tyhjiä alaryhmiä ei sallita

Ongelman muunnelmassa, joka ei salli tyhjiä alaryhmiä, best_sumse on alustettava negatiiviseen äärettömyyteen ja myös for -silmukassa current_sumon päivitettävä muodossa max(x, current_sum + x). Siinä tapauksessa, jos syöte ei sisällä positiivista elementtiä, palautettu arvo on suurimman elementin arvo (eli arvo, joka on lähinnä 0) tai negatiivinen ääretön, jos syöte oli tyhjä.

Parhaan aliryhmän sijainnin laskeminen

Algoritmia voidaan muokata myös seuratakseen enimmäisaliryhmän alku- ja loppuindeksejä:

def max_subarray(numbers):
    """Find a contiguous subarray with the largest sum."""
    best_sum = 0  # or: float('-inf')
    best_start = best_end = 0  # or: None
    current_sum = 0
    for current_end, x in enumerate(numbers):
        if current_sum <= 0:
            # Start a new sequence at the current element
            current_start = current_end
            current_sum = x
        else:
            # Extend the existing sequence with the current element
            current_sum += x

        if current_sum > best_sum:
            best_sum = current_sum
            best_start = current_start
            best_end = current_end + 1  # the +1 is to make 'best_end' exclusive

    return best_sum, best_start, best_end

Pythonissa taulukot indeksoidaan 0: sta alkaen ja lopetusindeksi jätetään yleensä pois, jotta matriisin [-11, 22, 33, -44] alimatriisi [22, 33] alkaa indeksistä 1 ja päättyy indeksiin 3.

Monimutkaisuus

Koska tämä algoritmi käyttää optimaalisia alarakenteita (jokaisen sijainnin enimmäispääte lasketaan yksinkertaisella tavalla asiaan liittyvästä mutta pienemmästä ja päällekkäisestä alitehtävästä: suurin alirivi päättyy edelliseen paikkaan), tätä algoritmia voidaan pitää yksinkertaisena/ triviaali esimerkki dynaamisesta ohjelmoinnista .

Kadanen algoritmin suoritusaikainen monimutkaisuus on .

Yleistykset

Samankaltaisia ​​ongelmia voi esiintyä korkeamman ulottuvuuden matriiseille, mutta niiden ratkaisut ovat monimutkaisempia; katso esim. Takaoka (2002) . Brodal & Jørgensen (2007) esittivät kuinka löytää k suurimman alirivisumman yksiulotteisesta taulukosta optimaalisella aikarajalla .

Suurin summa k -hajautetut aliryhmät voidaan myös laskea optimaalisella aikarajalla .

Katso myös

Huomautuksia

Viitteet

  • Backurs, Arturs; Dikkala, Nishanth; Tzamos, Christos (2016), "Tight Hardness Results for Maximum Weight Rectangles", Proc. 43. kansainvälinen kollokviumi automaateista, kielistä ja ohjelmoinnista : 81: 1–81: 13, doi : 10.4230/LIPIcs.ICALP.2016.81 , S2CID  12720136
  • Bae, Sung Eun (2007), Sequential and Parallel Algorithms for the Generalized Maximum Subarray Problem (PDF) (väitöskirja), University of Canterbury, S2CID  2681670 , arkistoitu alkuperäisestä (PDF) 26.10.2017.
  • Bengtsson, Fredrik; Chen, Jingsen (2007), Enimmäispistemääräsegmenttien optimaalinen laskenta (PDF) (Tutkimusraportti), Luulajan teknillinen yliopisto
  • Bentley, Jon (1984), "Programming Pearls: Algorithm Design Techniques", Communications of the ACM , 27 (9): 865–873, doi : 10.1145/358234.381162 , S2CID  207565329
  • Bentley, Jon (toukokuu 1989), Programming Pearls (2.? Toim.), Reading, MA: Addison Wesley, ISBN 0-201-10331-1
  • Bird, Richard S. (1989), "Algebraic Identities for Program Calculation" (PDF) , The Computer Journal , 32 (2): 122–126, doi : 10.1093/comjnl/32.2.122
  • Brodal, Gerth Stølting; Jørgensen, Allan Grønlund (2007), "Lineaarinen aika-algoritmi k- maksimiarvojen ongelmaan", Tietotekniikan matemaattiset perusteet, Tietotekniikan luento, 4708 , Springer-Verlag, s. 442–453, doi : 10.1007/978 -3-540-74456-6_40.
  • Gries, David (1982), "Huomautus silmukkainvarianttien ja silmukoiden kehittämisen standardistrategiasta" (PDF) , Tietokoneohjelmoinnin tiede , 2 (3): 207–241, doi : 10.1016/0167-6423 (83) 90015 -1 , HDL : 1813/6370
  • Takaoka, Tadao (2002), "Tehokkaita algoritmeja alimatriisin enimmäisongelmalle etäisyysmatriisin kertomalla", Electronic Notes in Theoretical Computer Science , 61 : 191–200, doi : 10.1016/S1571-0661 (04) 00313-5.
  • Tamaki, Hisao; Tokuyama, Takeshi (1998), "Algorithms for the Maximum Subarray Problem based on Matrix Multiplication" , Proceedings of the 9. Symposium on Discrete Algorithms (SODA) : 446–452 , haettu 17. marraskuuta 2018

Ulkoiset linkit