Niedeterminizm stanowi przeciwną koncepcję. Nawet gdybyśmy mieli pełną wiedzę na temat stanu Świata w danej chwili, to i tak nie bylibyśmy w stanie przewidzieć przyszłości. Co najwyżej moglibyśmy określić jakie są możliwe przyszłe dzieje.
W informatyce determinizm oznacza, że jeżeli będziemy wielokrotnie uruchamiać ten sam program czy mechanizm obliczeniowy, podając te same dane, to zawsze uzyskamy te same wyniki. Niedeterminizm zaś przeciwnie -- dla tych samych danych możemy uzyskać różne wyniki. Prostych programy komputerowe (bez randomizacji) zwykle działają w sposób deterministyczny. Niedeterminizm pojawia się np. w algorytmach randomizacyjnych czy programowaniu współbieżnym, czyli tam, gdzie jest jakieś źródło przypadkowości. Wówczas zwykle wymagamy, aby bez względu na przebieg obliczeń była zachowana jakaś wymagana przez nas własność. Niedeterminizm jest też używany przy specyfikowaniu systemów -- specyfikacja nie określa jednoznacznie jak powinien zachowywać się system, każde zachowanie zgodne ze specyfikacją jest dopuszczalne.
Automat niedeterministyczny jest więc automatem, którego działania nie da się w pełni przewidzieć. Będąc w tym samym stanie i wczytując ten sam znak może wykonać różne przejścia. Przestaje więc obowiązywać wymóg, że dla danego znaku, z każdego stanu wychodzi dokładnie jedno przejście odpowiadające wczytaniu tego znaku. Takich przejść może być dowolnie wiele, a nawet może ich nie być wcale (co to znaczy wyjaśni się za chwilę). Automat taki może również mieć wiele stanów początkowych -- każde uruchomienie automatu może rozpocząć się w dowolnym z tych stanów.
Może więc się zdarzyć, że ten sam automat raz zaakceptuje dane słowo, a raz nie. Czy więc takie słowo należy do języka akceptowanego przez automat, czy nie? Otóż, jeśli tylko automat może zaakceptować słowo, to powiemy, że należy ono do języka akceptowanego przez automat. Jest to dosyć nietypowa interpretacja niedeterminizmu. Nie odpowiada ona intuicyjnemu rozumieniu przypadku.
Na taki niedeterministyczny automat możemy spojrzeć jak na mechanizm o dwoistej budowie: jedna jego część to automat skończony określający jakie przejścia są możliwe, druga część, to tzw. wyrocznia, która w przypadku wielu możliwych do wykonania przejść wybiera przejście, które prowadzi do zaakceptowania słowa. (Zapachniało metafizyką? Chwila cierpliwości, zaraz wszystko będzie ściśle zdefiniowane.) Jedno z zagadnień, którymi się zajmiemy, to czy taka wyrocznia zmienia siłę obliczeniową automatów, czyli czy dla tych samych języków potrafimy zbudować automaty deterministyczne i nie, czy też są jakieś różnice? Jak się okaże, w przypadku automatów skończonych nie ma żadnej różnicy, a wyrocznię i niedeterminizm można zastąpić większą liczbą stanów.
Działanie automatu niedeterministycznego możemy symulować w następujący sposób. Spójrzmy na diagram automatu jak na planszę, po której będziemy przesuwać pionki -- stany to pola, na których będziemy stawiać pionki, a przesuwać będziemy je zgodnie z przejściami.
Kilka własności funkcji , które przydadzą nam się w dalszej części wykładu:
Dowód przebiega przez indukcję ze względu na |y|.
Dowód przebiega przez indukcję ze względu na |x|.
W trakcie symulacji działania automatu niedeterministycznego istotny jest zbiór pól, na których w danym momencie znajdują się pionki. Nasza konstrukcja będzie polegała na zbudowaniu automatu deterministycznego, którego stanami będą zbiory stanów automatu niedeterministycznego (mogące się pojawić w czasie symulacji), jego stanem początkowym będzie zbiór stanów początkowych automatu niedeterministycznego, a akceptujące będą te stany, które zawierają choć jeden stan akceptujący automatu niedeterministycznego.
Konstruując automat deterministyczny liczba stanów może wzrosnąć nawet wykładniczo. Jednak nie zawsze tak musi być, gdyż nie zawsze wszystkie możliwe zbiory stanów automatu niedeterministycznego mogą się pojawić w czasie symulacji. Zobaczmy kilka przykładów.
Konstruowany automat deterministyczny, równoważny automatowi niedeterministycznemu, jest nazywany automatem potęgowym -- gdyż jego zbiór stanów to zbiór potęgowy zbioru stanów automatu niedeterministycznego. Formalnie, jego konstrukcja przebiega następująco.
Korzystając z lematu, dowód, że jest natychmiastowy:
W tak skonstruowanym automacie potęgowym możemy, bez zmiany akceptowanego przez niego języka, usunąć wszystkie stany nieosiągalne.
Podobnie, jak automaty deterministyczne stanowią szczególny
przypadek automatów niedeterministycznych, tak
automaty niedeterministyczne stanowią szczególny przypadek
automatów z -przejściami --
są to automaty z
-przejściami, w których nie ma
-przejść.
Okazuje się, że automaty z -przejściami mają
taką samą siłę wyrazu co automaty niedeterministyczne.
Czasami jednak
-przejścia pozwalają uprościć budowę
automatu.
Rozszerzenie funkcji przejścia
definiujemy następująco:
Pokażemy teraz, że automaty z -przejściami i automaty niedeterministyczne mają taką samą siłę wyrazu. (Tym samym, automaty z
-przejściami mają taką samą siłę wyrazu co automaty deterministyczne.) Powiedzieliśmy już wcześniej, że automaty niedeterministyczne są szczególnym przypadkiem automatów z
-przejściami. Musimy pokazać, że
-przejścia nie zwiększają siły wyrazu i że zawsze można je wyeliminować, zamieniając automat z
-przejściami w automat niedeterministyczny.
Niech
będzie automatem
skończonym z
-przejściami.
Równoważny mu niedeterministyczny automat skończony M'
ma postać
,
gdzie S'=D(S),
(dla
).
W informatyce niedeterminizm oznacza, że uruchamiając kilka razy ten sam program czy inny mechanizm obliczeniowy, dla tych samych danych możemy uzyskać różne wyniki.