Powstrzymanie problemu twierdzi, że niemożliwe jest napisanie programu, który może określić, czy kolejne przystanków programowych dla wszystkich możliwych programów wejściowych .
Mogę jednak z pewnością napisać program, który może obliczyć czas działania programu takiego jak:
for(i=0; i<N; i++)
{ x = 1; }
i zwróć czasową złożoność , bez uruchamiania go.
W przypadku wszystkich innych programów wejściowych zwracałby flagę wskazującą, że nie był w stanie określić złożoności czasowej.
Moje pytanie brzmi:
Jakie warunki musi spełnić, abyśmy mogli algorytmicznie określić złożoność czasową danego programu?
* Jeśli istnieje kanoniczne odniesienie lub artykuł przeglądowy, doceniłbym link do niego w komentarzach.
Odpowiedzi:
Zasadniczo nie można określić złożoności, nawet w przypadku zatrzymania programów: niech będzie dowolną maszyną Turinga i niech będzie programem (który zawsze zwraca 0):p TT. pT.
Oczywiste jest, że ogólnie nie można czy jest czasem liniowym, czy kwadratowym.pT.
Przeprowadzono jednak wiele pracy nad skutecznym obliczeniem złożoności programu. Szczególnie podoba mi się teoria niejawnej złożoności, która ma na celu tworzenie języków, które za pomocą specjalnych konstrukcji lub dyscyplin typów pozwalają pisać tylko programy, które zamieszkują określoną, ściśle określoną klasę złożoności. Według tego, co uważam za cud, języki te są często kompletne dla tej klasy!
Jeden szczególnie ładny przykład został opisany w tym artykule przez J.-Y. Marion, który opisuje drobny język imperatyw, z dyscypliny typu inspirowane z technik informacyjno-przepływowych i analiza zabezpieczeń, który umożliwia charakterystykę algorytmów w P .
źródło
Pytanie, które stawiasz i konkretna sztuczka liczenia, którą opisujesz, jest klasyczna w analizie programu. Istnieje teoretyczny problem analizy złożoności, a jego praktyczny przejaw polega na automatycznym szacowaniu wydajności fragmentu kodu. Taka zautomatyzowana analiza ma kilka aplikacji, od wykrywania błędów wydajności po szacowanie kosztów niektórych obliczeń w chmurze.
Cody wskazał, że problem jest ogólnie nierozstrzygalny. Ten problem jest trudniejszy niż udowodnienie zakończenia, ponieważ uzyskanie złożoności wiąże się z tym, że program również się kończy. Istnieją dwa podejścia do takiego problemu. Jeden pochodzi z analizy programu. Pomysł dodania licznika i oszacowania jego wartości istnieje od lat 70. XX wieku. To kodowanie zmniejsza problem określania czasu działania do obliczania niezmiennika.
Drugim podejściem jest zaprojektowanie języka programowania, który dopuszcza tylko programy o określonej ograniczonej złożoności. Jest to obszar niejawnej złożoności obliczeniowej.
Poniżej podano odniesienia do obu obszarów.
źródło