Uppräkningsalgoritm - Enumeration algorithm

Inom datavetenskap är en uppräkningsalgoritm en algoritm som räknar upp svaren på ett beräkningsproblem . Formellt gäller en sådan algoritm för problem som tar en input och producerar en lista med lösningar, liknande funktionsproblem . För varje ingång måste uppräkningsalgoritmen producera listan över alla lösningar utan dubbletter och sedan stoppa. Utförandet av en uppräkning algoritm mäts i termer av den tid som krävs för att producera de lösningar, antingen i termer av den totala tiden som krävs för att producera alla lösningar, eller i termer av den maximala fördröjningen mellan två på varandra följande lösningar och i form av en förbehandling tid , räknas som tiden innan den första lösningen matades ut. Denna komplexitet kan uttryckas som ingångens storlek, storleken på varje enskild utgång eller den totala storleken på uppsättningen av alla utgångar, på samma sätt som vad som görs med utgångskänsliga algoritmer .

Formella definitioner

Ett uppräkningsproblem definieras som en relation över strängar i ett godtyckligt alfabet :

En algoritm löser om algoritmen för varje ingång producerar (möjligen oändlig) sekvens så att den inte har någon duplikat och om och bara om . Algoritmen ska stanna om sekvensen är ändlig.

Vanliga komplexitetsklasser

Uppräkningsproblem har studerats i samband med beräkningskomplexitetsteori , och flera komplexitetsklasser har införts för sådana problem.

En mycket allmän sådan klass är EnumP , klassen av problem för vilken riktigheten av en möjlig utgång kan kontrolleras i polynomtid i in- och utgången. Formellt måste det för ett sådant problem finnas en algoritm A som tar som inmatning av problemingången x , kandidatutgången y och löser beslutsproblemet om y är en korrekt utgång för ingången x , i polynomtid i x och y . Till exempel innehåller denna klass alla problem som motsvarar att räkna upp vittnen till ett problem i klassen NP .

Andra klasser som har definierats inkluderar följande. När det gäller problem som också finns i EnumP ordnas dessa problem från minst till mest specifika

  • Output polynomial , klassen av problem vars fullständiga output kan beräknas på polynomial tid.
  • Inkrementell polynomtid , den klass av problem där, för alla i , den jag kan produceras: e utgångskomposanten i polynomisk tid i inmatningsstorleken och i antalet jag .
  • Polynomfördröjning , klassen av problem där fördröjningen mellan två på varandra följande utgångar är polynom i ingången (och oberoende av utgången).
  • Starkt polynomfördröjning , klassen av problem där förseningen före varje utgång är polynomisk i storleken på denna specifika utgång (och oberoende av ingången eller från de andra utgångarna). Förbehandlingen antas i allmänhet vara polynom.
  • Konstant fördröjning , klassen problem där fördröjningen före varje utgång är konstant, dvs oberoende av in- och utgången. Förbehandlingsfasen antas i allmänhet vara polynom i ingången.

Vanliga tekniker

  • Backtracking : Det enklaste sättet att räkna upp alla lösningar är genom att systematiskt utforska utrymmet för möjliga resultat ( partitionera det vid varje successivt steg). Att utföra detta kan dock inte ge goda garantier för förseningen, dvs en backtracking-algoritm kan spendera lång tid på att utforska delar av rymden med möjliga resultat som inte ger upphov till en fullständig lösning.
  • Ficklampasökning : Denna teknik förbättrar backtracking genom att utforska utrymmet för alla möjliga lösningar men lösa i varje steg problemet om den aktuella partilösningen kan utvidgas till en partiell lösning. Om svaret är nej kan algoritmen omedelbart gå tillbaka och undvika att slösa tid, vilket gör det lättare att visa garantier för fördröjningen mellan två kompletta lösningar. I synnerhet gäller denna teknik väl för självreducerande problem.
  • Stängning under uppsatta operationer : Om vi ​​vill räkna upp den ojämna sammansättningen av två uppsättningar kan vi lösa problemet genom att räkna upp den första uppsättningen och sedan den andra uppsättningen. Om unionen inte är enskilt men uppsättningarna kan räknas upp i sorterad ordning kan uppräkningen utföras parallellt på båda uppsättningarna samtidigt som dubbletter i farten elimineras. Om facket inte är enskilt och båda uppsättningarna inte sorteras kan dubbletter elimineras på bekostnad av en högre minnesanvändning, t.ex. genom att använda en hash-tabell . På samma sätt kan den kartesiska produkten av två uppsättningar räknas upp effektivt genom att räkna upp en uppsättning och sammanfoga varje resultat med alla resultat som erhållits när man räknar upp det andra steget.

Exempel på uppräkningsproblem

Anslutning till beräkningsbarhetsteori

Begreppet uppräkningsalgoritmer används också inom beräkningsbarhetsteorin för att definiera vissa höga komplexitetsklasser såsom RE , klassen för alla rekursivt uppräkbara problem. Detta är den klass av uppsättningar för vilka det finns en uppräkningsalgoritm som kommer att producera alla element i uppsättningen: algoritmen kan springa för evigt om uppsättningen är oändlig, men varje lösning måste produceras av algoritmen efter en begränsad tid.

Referenser

  1. ^ Strozecki, Yann; Mary, Arnaud (2017-12-11). "Effektiv uppräkning av lösningar som produceras genom stängningsoperationer". arXiv : 1509.05623 [ cs.CC ].
  2. ^ "" Algorithmic and Computational Complexity Issues of MONET - Cuvillier Verlag " . Cuvillier.de . Hämtad 23.05.2019 .
  3. ^ Bagan, Guillaume; Durand, Arnaud; Grandjean, Etienne (2007). Duparc, Jacques; Henzinger, Thomas A. (red.). "Om cykliska konjunktiva frågor och konstant fördröjningsuppräkning". Datavetenskapslogik . Föreläsningsanteckningar inom datavetenskap. Springer Berlin Heidelberg. 4646 : 208–222. doi : 10.1007 / 978-3-540-74915-8_18 . ISBN 9783540749158.
  4. ^ Marquis, s .; Darwiche, A. (2002). "En kunskapskompileringskarta". Journal of Artificial Intelligence Research . 17 : 229–264. arXiv : 1106.1819 . doi : 10.1613 / jair.989 .