Jak utworzyć DFA z wyrażenia regularnego bez użycia NFA?


12

Celem jest utworzenie DFA z wyrażenia regularnego, a użycie opcji „Regular exp> NFA> Konwersja DFA” nie jest opcją. Jak należy to zrobić?

Zadałem to pytanie naszemu profesorowi, ale powiedział mi, że możemy korzystać z intuicji i uprzejmie odmówił podania jakichkolwiek wyjaśnień. Więc chciałem cię zapytać.

Opcja „Regular exp> NFA> Konwersja DFA” nie jest opcją, ponieważ taka konwersja zajmuje dużo czasu, aby przekonwertować dość złożone wyrażenie regularne. Na przykład dla pewnego wyrażenia regularnego „wyrażenie regularne> NFA> DFA” zajmuje człowiekowi 1 godzinę. Muszę przekonwertować wyrażenie regularne na DFA w mniej niż 30 minut.


2
Musisz podać więcej kontekstu. Jakiego (nieformalnego) algorytmu używasz obecnie do tłumaczenia wyrażeń regularnych? Pomocne może być wyjaśnienie procesu na przykładzie takim jak a(a|ab|ac)*a+. Możesz albo bezpośrednio przetłumaczyć to na NDFA, które redukujesz do DFA, albo możesz znormalizować to do czegoś, co mapuje natychmiast do DFA.
amon

Czy musisz to robić na konkretnych przykładach za pomocą dowolnych środków, czy też musisz podać ogólną procedurę. Do zastosowania przez komputer?
babou

Odpowiedzi:


18

Ponieważ chcesz „przekonwertować wyrażenie regularne na DFA w mniej niż 30 minut”, przypuszczam, że pracujesz ręcznie na stosunkowo małych przykładach.

W tym przypadku można zastosować algorytm Brzozowskiego , który bezpośrednio oblicza automat Nerode języka (o którym wiadomo, że jest równy minimalnemu automatowi deterministycznemu). Opiera się na bezpośrednim obliczeniu pochodnych, a także działa na rozszerzone wyrażenia regularne, umożliwiające przecięcie i uzupełnienie. Wadą tego algorytmu jest to, że wymaga sprawdzenia równoważności wyrażeń obliczanych po drodze, kosztownego procesu. Ale w praktyce i dla małych przykładów jest bardzo wydajny.[1]

Lewe ilorazy . Niech będzie językiem A * i niech u być słowo. Następnie u - 1 L = { v * | u , v L } Język u - 1 l nazywa się lewy iloraz (lub po pochodnej ) z L .LAu

u1L={vAuvL}
u1LL

Automat Nerode . Automat Nerode z jest deterministyczny automat ( L ) = ( P , , , L , F ) , gdzie P = { u - 1 l | u * } , M = { u - 1 l | u L } i funkcja przejścia jest zdefiniowana dla każdego a LA(L)=(Q,A,,L,F)Q={u1LuA}F={u1LuL} według wzoru ( u - 1 L ) a = a - 1 ( u - 1 L ) = ( u a ) - 1 L Strzeż się tej raczej abstrakcyjnej definicji. Każdy stan A jest lewym ilorazem L słowa, a zatem jest językiem A . Początkowy stan jest język L i zbiorem stanów końcowych jest zbiorem wszystkich pozostawionych ilorazów L przez słowo L .aA

(u1L)a=a1(u1L)=(ua)1L
ALALLL

a,b

a11=0a1b={1if a=b0if aba1(L1L2)=a1L1u1L2,a1(L1L2)=a1L1u1L2,a1(L1L2)=a1L1u1L2,a1L=(a1L)L
a1(L1L2)={(a1L1)L2si 1L1,(a1L1)L2a1L2si 1L1

L=(a(ab))(ba)

11L=L=L1a1L1=(ab)(a(ab))=L2b1L1=a(ba)=L3a1L2=b(ab)(a(ab))(ab)(a(ab))=bL2L2=L4b1L2=a1L3=(ba)=L5b1L3=a1L4=a1(bL2L2)=a1L2=L4b1L4=b1(bL2L2)=L2b1L2=L2a1L5=b1L5=a(ba)=L3
Minimalny automat

[1]

Edit . (5 kwietnia 2015 r.) Właśnie odkryłem, że podobne pytanie: jakie algorytmy istnieją do budowy DFA, który rozpoznaje język opisany przez dane wyrażenie regularne? został zapytany na cstheory. Odpowiedź częściowo rozwiązuje problemy ze złożonością.


Czy możesz powiedzieć więcej o złożoności tego algorytmu?
babou

@babou Przekształcenie RE w DFA jest trudne dla PSPACE, więc jest zdecydowanie wykładnicze.
jmite

To prawdopodobnie powinno znaleźć się w odpowiedzi. OP zaczyna się od „standardowych konstrukcji przez NFA są zbyt wolne”, a część odpowiedzi wydaje się brzmieć „pech, nie ma tak naprawdę szybkiego rozwiązania”. Pozostaje do omówienia, czy tutaj jest to lepsze niż standardowa konstrukcja. (cc @jmite)
Raphael

@jmite Tak, spodziewałem się tego. Powodem mojego pytania jest to, dlaczego ten sposób budowania DFA należy uznać za łatwiejszy. (uwaga: system poświęcił cały dzień na powiadomienie mnie o odpowiedzi @ jmite).
babou

2

J.-E. Pin zapewnia lepszą odpowiedź pod względem formalności i kompletności, ale myślę, że można powiedzieć coś o „intuicji”, na którą wskazuje twój profesor.

W większości tych przypadków najłatwiej jest spojrzeć na wyrażenie regularne, zrozumieć, jaki język akceptuje, a następnie wykorzystać swoją kreatywność / spryt, aby zbudować DFA akceptujący ten język.

Nie ma prostego sposobu, aby to zrobić, oprócz algorytmów podanych przez innych, ale oto kilka wskazówek, które mogą się okazać przydatne.

  1. Zadaj sobie pytanie, czy mógłbym napisać program, który akceptuje to RE, używając tylko zmiennych boolowskich lub bardzo małych liczb całkowitych? Następnie napisz ten program i przekonwertuj go na DFA, w którym istnieje stan dla każdej kombinacji wartości.

  2. Poszukaj części wyrażenia regularnego, które możesz zaakceptować deterministycznie, gdzie wiesz, że „Jeśli to widzę, to muszę dopasować tę część RE”. Nie zawsze będzie ich mnóstwo, ale identyfikacja tych części może pokazać części, które będą łatwe do stworzenia DFA, dzięki czemu możesz spędzić więcej czasu na częściach, które naprawdę wymagają niedeterminizmu.

  3. Konstrukcja podzbioru dla NFA-> DFA nie jest tak skomplikowana jak algorytm. Więc jeśli jest to zadanie, a nie pytanie egzaminacyjne, może być szybsze kodowanie implementacji i pozwolenie Twojemu programowi na konwersję NFA na DFA. Jeśli użyłeś własnego kodu, nie powinno być żadnych problemów z plagaryzmem.

P=NP=PSPACE

Spróbuj „patrzeć przed siebie”, skracając rogi, gdy możesz używać intuicji w miejscach, w których algorytm wymagałby wielu kroków, ale jego wynik jest jasny.


-2

Chociaż nie jest to właściwy sposób, ale działa przez większość czasu.

Pierwszy krok : znajdź najmniejszy ciąg znaków, który może zostać zaakceptowany przez wyrażenie regularne. Drugi krok : narysuj niezbędne stany za pomocą transakcji minimalnego ciągu akceptującego ciąg. Trzeci krok : dla wszystkich stanów narysuj pozostałe transakcje alfabetyczne.

Na przykład: Wyrażenie regularne (0 + 1) * 1 ”Łańcuch kończący się na 1” Krok 1: Najmniejszy ciąg: 1 Krok 2: dwa stany Q0 i Q1. z transakcją 1 od Q0 do Q1. a Q1 to stan akceptujący. Krok 3: dla stanu Q0 transakcja Q0 1 odbywa się do pierwszego kwartału. Teraz dokonaj transakcji 0 w samym Q0. Dla stanu w pierwszym kwartale transakcja w pierwszym kwartale pozostanie w pierwszym kwartale. I 0 transakcji pójdzie w Q0.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.