Szukam dobrych przykładów skończonych maszyn stanów; język nie jest szczególnie ważny, tylko dobre przykłady.
Implementacje kodu są przydatne (pseudo-kod uogólniony), ale bardzo przydatne jest również gromadzenie różnych zastosowań FSM.
Przykłady niekoniecznie muszą być oparte na komputerze, na przykład przykład sieci kolejowej Mike'a Dunlavey'a jest bardzo przydatny.
finite-state-machine
ocodo
źródło
źródło
Odpowiedzi:
Sejf (wywołane zdarzenie)
Sygnalizacja świetlna (wyzwolony czas | czujnik [zdarzenie] wyzwolony)
Automat (aktywacja zdarzenia, odmiana sejfu )
źródło
Przykład protokołu bramki granicznej
BGP to protokół, który wspiera kluczowe decyzje dotyczące routingu w Internecie. Utrzymuje tabelę, aby określić dostępność hostów z danego węzła, i sprawiła, że Internet był naprawdę zdecentralizowany.
W sieci każdy węzeł BGP jest równorzędny i używa skończonej maszyny stanów, z jednym z sześciu stanów: Bezczynności , Połącz , Aktywny , OpenSent , OpenConfirm i Ustalony . Każde połączenie równorzędne w sieci utrzymuje jeden z tych stanów.
Protokół BGP określa komunikaty wysyłane do peerów w celu zmiany ich stanu.
Wykres statystyk BPG.
Bezczynny
Pierwszy stan Bezczynny . W tym stanie BGP inicjuje zasoby, odrzuca próby połączenia przychodzącego i inicjuje połączenie z peerem.
Połączyć
Drugi stan Połącz . W tym stanie router czeka na zakończenie połączenia i jeśli zakończy się powodzeniem, przejdzie w stan OpenSent . Jeśli się to nie powiedzie, resetuje licznik ConnectRetry i po wygaśnięciu przechodzi w stan Aktywny .
Aktywny
W stanie Aktywnym router resetuje licznik ConnectRetry na zero i powraca do stanu Połącz .
OpenSent
W stanie OpenSent router wysyła wiadomość Open i czeka na jedną w zamian. Komunikaty podtrzymujące są wymieniane, a po pomyślnym odebraniu router jest przełączany w stan Ustanowiony .
Ustanowiony
W stanie Ustanowiony router może wysyłać / odbierać: Keepalive; Aktualizacja; oraz wiadomości z powiadomieniem do / od swojego partnera.
Więcej informacji o BGP znajduje się na wikipedii
źródło
Są przydatne do modelowania wszelkiego rodzaju rzeczy. Na przykład cykl wyborczy można modelować z państwami na wzór (normalnego rządu) - wyborów zwanych -> (wczesna kampania) - Parlament rozwiązany -> (ciężka kampania) - wybory -> (liczenie głosów ). Następnie albo (liczenie głosów) - brak większości -> (negocjacje koalicyjne) - osiągnięto porozumienie -> (normalny rząd) lub (liczenie głosów) - większość -> (normalny rząd). Zaimplementowałem wariant tego schematu w grze z podgrą polityczną.
Są one również wykorzystywane w innych aspektach gier: AI często zależy od stanu; przejścia między menu i poziomami oraz przejścia po śmierci lub ukończeniu poziomu są często dobrze modelowane przez FSM.
źródło
Parser CSV używany we wtyczce jquery-csv
Jest to podstawowy parser gramatyki Chomsky'ego typu III .
Tokenizator wyrażeń regularnych służy do oceny danych według char-by-char. Po napotkaniu znaku sterującego kod jest przekazywany do instrukcji switch w celu dalszej oceny w oparciu o stan początkowy. Znaki niekontrolowane są grupowane i kopiowane masowo, aby zmniejszyć liczbę wymaganych operacji kopiowania ciągów.
Tokenizer:
Pierwszy zestaw dopasowań to znaki sterujące: separator wartości („) separator wartości (,) i separator wprowadzania (wszystkie odmiany znaku nowej linii). Ostatnie dopasowanie obsługuje grupowanie znaków niekontrolowanych.
Analizator składni musi spełniać 10 reguł:
Uwaga: 7 najlepszych reguł pochodzi bezpośrednio z IETF RFC 4180 . Ostatnie 3 zostały dodane, aby objąć przypadki krawędzi wprowadzone przez nowoczesne aplikacje arkuszy kalkulacyjnych (np. Excel, Arkusz kalkulacyjny Google), które domyślnie nie ograniczają (tj. Cytują) wszystkich wartości. Próbowałem przyczynić się do zmian w RFC, ale jeszcze nie usłyszałem odpowiedzi na moje zapytanie.
Wystarczy z podsumowaniem, oto schemat:
Stany:
Przejścia:
Uwaga: w rzeczywistości brakuje stanu. Powinien znajdować się wiersz od „c” -> „b” oznaczony stanem „1”, ponieważ drugi znak delimitera oznacza, że pierwszy separator jest nadal otwarty. W rzeczywistości prawdopodobnie lepiej byłoby przedstawić ją jako kolejne przejście. Ich tworzenie jest sztuką, nie ma jednego poprawnego sposobu.
Uwaga: Brakuje również stanu wyjścia, ale przy prawidłowych danych analizator zawsze kończy się na przejściu „a” i żaden ze stanów nie jest możliwy, ponieważ nie ma już nic do przeanalizowania.
Różnica między stanami a przejściami:
Stan jest skończony, co oznacza, że można go wywnioskować tylko z jednej rzeczy.
Przejście reprezentuje przepływ między stanami, więc może oznaczać wiele rzeczy.
Zasadniczo relacja stan-> przejście wynosi 1 -> * (tj. Jeden do wielu). Państwo definiuje „co to jest”, a przejście określa „jak sobie z tym poradzić”.
Uwaga: Nie martw się, jeśli zastosowanie stanów / przejść nie jest intuicyjne, nie jest intuicyjne. Zajęło mi trochę obszernej korespondencji z kimś znacznie mądrzejszym ode mnie, zanim w końcu udało mi się utrzymać koncepcję.
Pseudokod:
Uwaga: To jest sedno, w praktyce jest o wiele więcej do rozważenia. Na przykład sprawdzanie błędów, wartości zerowe, końcowa pusta linia (tj. Która jest poprawna) itp.
W tym przypadku stan jest warunkiem rzeczy, gdy blok dopasowania wyrażenia regularnego kończy iterację. Przejście jest reprezentowane jako instrukcje przypadku.
Jako ludzie mamy tendencję do uproszczenia operacji niskiego poziomu do wyższego poziomu, ale streszczenia pracy z FSM jest praca z operacji niskim poziomie. Podczas gdy poszczególne stany i przejścia są bardzo łatwe do indywidualnej pracy, z natury trudno jest zobrazować całość naraz. Odkryłem, że najłatwiej jest podążać w kółko poszczególnymi ścieżkami wykonania, dopóki nie mogłem zrozumieć, jak przebiegają przejścia. Jest królem nauki matematyki, nie będziesz w stanie oceniać kodu z wyższego poziomu, dopóki szczegóły niskiego poziomu nie staną się automatyczne.
Poza tym: jeśli spojrzysz na faktyczną implementację, brakuje wielu szczegółów. Po pierwsze, wszystkie niemożliwe ścieżki spowodują określone wyjątki. Uderzenie ich nie powinno być możliwe, ale jeśli coś się zepsuje, absolutnie wyzwolą wyjątki w teście. Po drugie, reguły parsera dotyczące dozwolonego ciągu „legalnego” łańcucha danych CSV są dość luźne, więc kod potrzebny do obsługi wielu konkretnych przypadków krawędzi. Niezależnie od tego był to proces wyśmiewania FSM przed wszystkimi poprawkami błędów, rozszerzeniami i dostrajaniem.
Jak w przypadku większości projektów, nie jest to dokładna reprezentacja implementacji, ale przedstawia najważniejsze części. W praktyce z tego projektu pochodzą 3 różne funkcje analizatora składni: rozdzielacz linii specyficzny dla csv, analizator jednowierszowy i kompletny analizator składający się z wielu linii. Wszystkie działają w podobny sposób, różnią się sposobem obsługi znaków nowej linii.
źródło
Prosty FSM w Javie
Proszę bardzo. OK, to nie jest genialne, ale pokazuje pomysł.
Często można znaleźć FSM w produktach telekomunikacyjnych, ponieważ oferują one proste rozwiązanie skomplikowanej sytuacji.
źródło
Odkryłem, że myślenie / modelowanie windy (windy) jest dobrym przykładem skończonej maszyny stanów. Nie wymaga wiele od wprowadzenia, ale zapewnia daleki od trywialnej sytuacji do wdrożenia.
Stany znajdują się na przykład na parterze, na pierwszym piętrze itp. I przenoszą ziemię na pierwsze piętro lub przenoszą trzecią na parter, ale obecnie między piętrem 3 a 2 i tak dalej.
Działanie przycisków w klatce windowej i na samych podłogach zapewnia dane wejściowe, których działanie zależy zarówno od naciśnięcia przycisku, jak i od bieżącego stanu.
Każde piętro, z wyjątkiem górnej i dolnej, będzie miało dwa przyciski: jeden z prośbą o windę, aby wejść w górę, a drugi o dół.
źródło
OK, oto przykład. Załóżmy, że chcesz przeanalizować liczbę całkowitą. Poszłoby mniej więcej tak,
dd*
gdzied
jest liczba całkowita.Oczywiście, jak powiedział @Gary, można je ukryć
goto
za pomocą instrukcji switch i zmiennej stanu. Zauważ, że można utworzyć strukturę tego kodu, który jest izomorficzny w stosunku do pierwotnego wyrażenia regularnego:Oczywiście możesz to również zrobić za pomocą tabeli odnośników.
Maszyny stanów skończonych można tworzyć na wiele sposobów, a wiele rzeczy można opisać jako instancje maszyn stanów skończonych. To nie tyle „koncepcja”, co koncepcja, do myślenia o rzeczach.
Przykład sieci kolejowej
Jednym z przykładów FSM jest sieć kolejowa.
Istnieje skończona liczba zwrotnic, w których pociąg może jechać na jeden z dwóch torów.
Istnieje ograniczona liczba ścieżek łączących te przełączniki.
W dowolnym momencie pociąg znajduje się na jednym torze, można go wysłać na inny tor, przekraczając przełącznik, w oparciu o pojedynczy bit informacji wejściowych.
źródło
Maszyna stanów skończonych w Rubim:
Takie jest zachowanie pojedynczego węzła obliczeniowego w systemie rozproszonym, ustanawiając schemat komunikacji oparty na łączu. Mniej więcej. W formie graficznej wygląda to tak:
źródło
Sprawdź ten link, aby uzyskać kilka prostych przykładów analizy leksykalnej (FSM):
http://ironbark.bendigo.latrobe.edu.au/subjects/SS/clect/clect03.html
Możesz także sprawdzić przykłady „książeczki smoków” (nie jest to lekka lektura)
http://en.wikipedia.org/wiki/Compilers:_Principles,_Techniques,_and_Tools
źródło
W praktyce maszyny stanowe są często używane do:
Jednym z przykładów może być automat stanów, który skanuje ciąg znaków, aby sprawdzić, czy ma właściwą składnię. Na przykład holenderskie kody pocztowe mają format „1234 AB”. Pierwsza część może zawierać tylko cyfry, druga tylko litery. Można napisać automat stanowy, który śledzi, czy jest w stanie NUMEROWY, czy w stanie LITEROWYM, a jeśli napotka nieprawidłowe wejście, odrzuć go.
Ta maszyna stanów akceptora ma dwa stany: numeryczny i alfa. Automat stanowy uruchamia się w stanie numerycznym i zaczyna odczytywać znaki ciągu do sprawdzenia. Jeśli napotkane zostaną nieprawidłowe znaki w którymkolwiek ze stanów, funkcja zwraca wartość False, odrzucając dane wejściowe jako nieprawidłowe.
Kod Python:
Źródło: (skończone) maszyny państwowe w praktyce
źródło