Bagaimana cara membuat DFA dari ekspresi reguler tanpa menggunakan NFA?

12

Tujuannya adalah membuat DFA dari ekspresi reguler dan menggunakan "Exp reguler> NFA> Konversi DFA" bukan opsi. Bagaimana seharusnya orang melakukan itu?

Saya mengajukan pertanyaan ini kepada profesor kami tetapi dia mengatakan kepada kami bahwa kami dapat menggunakan intuisi dan dengan baik hati menolak untuk memberikan penjelasan. Jadi saya ingin bertanya kepada Anda.

"Exp reguler> NFA> Konversi DFA" bukan opsi karena konversi seperti itu membutuhkan banyak waktu untuk mengonversi ekspresi reguler yang agak rumit. Misalnya, untuk regex tertentu "regex> NFA> DFA" membutuhkan waktu 1 jam untuk manusia. Saya perlu mengonversi regex ke DFA dalam waktu kurang dari 30 menit.

Raphael
sumber
2
Anda perlu memberikan lebih banyak konteks. Algoritma (informal) apa yang saat ini Anda gunakan untuk menerjemahkan ekspresi reguler? Mungkin bermanfaat untuk menjelaskan proses Anda dengan contoh seperti a(a|ab|ac)*a+. Anda bisa langsung menerjemahkannya ke NDFA yang Anda kurangi menjadi DFA, atau Anda bisa menormalkannya menjadi sesuatu yang segera dipetakan ke DFA.
amon
Apakah Anda harus melakukannya pada contoh spesifik dengan cara apa pun, atau apakah Anda harus memberikan prosedur umum. Untuk diterapkan oleh komputer?
babou

Jawaban:

18

Karena Anda ingin "mengubah regex menjadi DFA dalam waktu kurang dari 30 menit", saya kira Anda bekerja dengan tangan pada contoh yang relatif kecil.

Dalam hal ini Anda dapat menggunakan algoritma Brzozowski , yang menghitung secara langsung otomat Nerode dari suatu bahasa (yang diketahui sama dengan otomat deterministik minimalnya). Ini didasarkan pada perhitungan langsung dari derivatif dan juga berfungsi untuk ekspresi reguler yang diperpanjang yang memungkinkan persimpangan dan komplementasi. Kelemahan dari algoritma ini adalah bahwa ia perlu memeriksa ekuivalensi ekspresi yang dihitung sepanjang jalan, proses yang mahal. Tetapi dalam praktiknya, dan untuk contoh kecil, ini sangat efisien.[1]

Quotients kiri . Biarkan menjadi bahasa dan biarkan menjadi kata. Kemudian Bahasa disebut quotient kiri (atau kiri turunan ) dari .LAu

u1L={vAuvL}
u1LL

Otomat Nerode . The Nerode otomat dari adalah deterministik otomat di mana , dan fungsi transisi didefinisikan, untuk setiap , dengan rumus Waspadai definisi yang agak abstrak ini. Setiap status adalah hasil bagi kiri dari per kata, dan karenanya adalah bahasa . Keadaan awal adalah bahasa , dan himpunan menyatakan akhir adalah himpunan semua quotients kiriLA(L)=(Q,A,,L,F)Q={u1LuA}F={u1LuL}aA

(u1L)a=a1(u1L)=(ua)1L
ALALL oleh firman .L

Algoritma Brzozowski . Biarkan menjadi huruf. Seseorang dapat menghitung quotients kiri menggunakan rumus berikut: 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

Contoh . Untuk , kami mendapatkan berturut-turut: yang memberikan otomat minimal berikut. 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
Otomat minimal

[1] J. Brzozowski, Derivatif Ekspresi Reguler, J.ACM 11 (4), 481–494, 1964.

Edit . (5 April 2015) Saya baru saja menemukan bahwa pertanyaan serupa: Algoritma apa yang ada untuk konstruksi DFA yang mengenali bahasa yang dijelaskan oleh regex yang diberikan? diminta pada cstheory. Jawabannya sebagian membahas masalah kompleksitas.

J.-E. Pin
sumber
Bisakah Anda mengatakan lebih banyak tentang kompleksitas algoritma ini?
babou
@ baou Mengubah RE menjadi DFA adalah PSPACE-hard, jadi pasti eksponensial.
jmite
Ini mungkin harus masuk ke jawabannya. OP dimulai dengan "konstruksi standar melalui NFA terlalu lambat" dan bagian dari jawabannya tampaknya "sial, sebenarnya tidak ada solusi cepat". Masih membahas apakah ini di sini lebih baik daripada konstruksi standar. (cc @jmite)
Raphael
@iteite Ya saya mengharapkan itu. Alasan pertanyaan saya adalah mengapa cara membangun DFA ini harus dianggap lebih mudah. (catatan: sistem membutuhkan waktu sehari penuh untuk memberi tahu saya tentang jawaban @ jmite).
babou
2

J.-E. Pin memberikan jawaban yang lebih baik dalam hal formalitas dan kelengkapan, tetapi saya pikir ada sesuatu yang bisa dikatakan untuk "intuisi" yang disindir profesor Anda.

Dalam sebagian besar kasus ini, hal yang paling mudah untuk dilakukan adalah melihat ekspresi reguler, memahami bahasa apa yang diterimanya, kemudian gunakan kreativitas / kepintaran Anda untuk membangun DFA yang menerima bahasa itu.

Tidak ada cara langsung untuk melakukan ini, selain algoritma yang diberikan orang lain, tetapi berikut adalah beberapa panduan yang mungkin terbukti bermanfaat.

  1. Tanyakan kepada diri sendiri, dapatkah saya menulis sebuah program yang menerima RE ini hanya menggunakan variabel boolean atau variabel integer yang sangat kecil? Kemudian tulis program itu, dan konversikan menjadi DFA di mana ada keadaan untuk setiap kombinasi nilai.

  2. Cari bagian dari ekspresi reguler yang Anda tahu dapat Anda terima secara deterministik, di mana Anda tahu "Jika saya melihat ini, maka saya harus mencocokkan bagian RE ini." Tidak akan selalu ada banyak ini, tetapi mengidentifikasi bagian-bagian ini dapat menunjukkan bagian-bagian yang akan mudah untuk membuat DFA, sehingga Anda dapat menghabiskan lebih banyak waktu pada bagian-bagian yang benar-benar membutuhkan non-determinisme.

  3. Konstruksi subset untuk NFA-> DFA sebenarnya tidak rumit dari suatu algoritma. Jadi jika ini adalah tugas, bukan pertanyaan ujian, mungkin lebih cepat untuk hanya membuat kode implementasi, dan biarkan program Anda mengonversi NFA ke DFA. Jika Anda menggunakan kode Anda sendiri, seharusnya tidak ada masalah plagarisme.

Ingat bahwa apa pun yang Anda lakukan, teknik apa pun akan meledak secara eksponensial dalam kasus terburuk (kecuali jika Anda menemukan algoritma polinomial untuk ini, dalam hal ini, selamat, Anda telah membuktikan dan Anda sekarang menjadi jutawan .)P=NP=PSPACE

Cobalah untuk "melihat ke depan," memotong sudut ketika Anda dapat menggunakan intuisi Anda di tempat-tempat ketika algoritma akan membutuhkan banyak langkah tetapi hasilnya jelas.

Ya ampun
sumber
-2

Meskipun ini bukan cara yang benar tetapi itu berfungsi sebagian besar waktu.

Langkah Pertama : Temukan string terkecil yang dapat diterima oleh Ekspresi Reguler. Langkah Kedua : Gambarkan status yang diperlukan dengan transaksi mesin penerima string minimum. Langkah Ketiga : Untuk semua negara bagian, tarik transaksi alfabet yang tersisa.

Sebagai Contoh: Ekspresi Reguler (0 +1) * 1 "String yang diakhiri dengan 1" Langkah 1: String Terkecil: 1 Langkah 2: dua status Q0 dan Q1. memiliki transaksi 1 dari Q0 ke Q1. dan Q1 adalah negara penerima. Langkah 3: untuk Q0 Negara Q0 1 transaksi adalah ke Q1. Sekarang lakukan 0 transaksi di Q0 itu sendiri. Untuk Negara Q1 Q1 1 transaksi akan tetap di Q1. Dan 0 transaksi akan masuk Q0.

Naveen CS
sumber