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.
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.Jawaban:
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 .L A∗ u
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 kiriL A(L)=(Q,A,⋅,L,F) Q={u−1L∣u∈A∗} F={u−1L∣u∈L} a∈A
Algoritma Brzozowski . Biarkan menjadi huruf. Seseorang dapat menghitung quotients kiri menggunakan rumus berikut:a,b
Contoh . Untuk , kami mendapatkan berturut-turut: yang memberikan otomat minimal berikut.L=(a(ab)∗)∗∪(ba)∗
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.
sumber
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.
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.
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.
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.
sumber
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.
sumber