มีหลายวิธีในการทำการแปลงจากออโตมาตา จำกัด เป็นนิพจน์ปกติ ที่นี่ฉันจะอธิบายหนึ่งที่มักจะสอนในโรงเรียนซึ่งเป็นภาพมาก ฉันเชื่อว่ามันถูกใช้มากที่สุดในการปฏิบัติ อย่างไรก็ตามการเขียนอัลกอริทึมไม่ใช่ความคิดที่ดี
วิธีการกำจัดสถานะ
อัลกอริทึมนี้เกี่ยวกับการจัดการกราฟของหุ่นยนต์และดังนั้นจึงไม่เหมาะสำหรับอัลกอริทึมเนื่องจากมันต้องการกราฟแบบดั้งเดิมเช่น ... การลบรัฐ ฉันจะอธิบายมันโดยใช้พื้นฐานระดับสูง
ความคิดหลัก
แนวคิดคือการพิจารณานิพจน์ทั่วไปบนขอบจากนั้นลบสถานะสื่อกลางในขณะที่ทำให้ป้ายชื่อขอบคงที่
รูปแบบหลักสามารถเห็นได้ในรูปต่อไปนี้ เป็นครั้งแรกที่มีป้ายระหว่างที่มีการแสดงออกปกติและเราต้องการที่จะเอาคิวe , f , g , h , i qp,q,re,f,g,h,iq
เมื่อนำออกแล้วเราจะเขียนด้วยกัน (ในขณะที่รักษาขอบอื่น ๆ ระหว่างและแต่สิ่งนี้ไม่ปรากฏบนนี้):p re,f,g,h,ipr
ตัวอย่าง
ใช้ตัวอย่างเดียวกันกับคำตอบของราฟาเอล :
เราลบอย่างต่อเนื่อง:q2
แล้ว :q3
แล้วเรายังคงต้องใช้ดาวบนแสดงออกจากเพื่อq_1ในกรณีนี้สถานะสุดท้ายก็เริ่มต้นด้วยดังนั้นเราแค่ต้องเพิ่มดาว:q 1q1q1
(ab+(b+aa)(ba)∗(a+bb))∗
ขั้นตอนวิธี
L[i,j]
เป็น regexp ของภาษาจากที่เพื่อq_jก่อนอื่นเราจะลบหลายขอบทั้งหมด:q jqiqj
for i = 1 to n:
for j = 1 to n:
if i == j then:
L[i,j] := ε
else:
L[i,j] := ∅
for a in Σ:
if trans(i, a, j):
L[i,j] := L[i,j] + a
ตอนนี้การกำจัดของรัฐ สมมติว่าเราต้องการลบสถานะ :qk
remove(k):
for i = 1 to n:
for j = 1 to n:
L[i,i] += L[i,k] . star(L[k,k]) . L[k,i]
L[j,j] += L[j,k] . star(L[k,k]) . L[k,j]
L[i,j] += L[i,k] . star(L[k,k]) . L[k,j]
L[j,i] += L[j,k] . star(L[k,k]) . L[k,i]
โปรดทราบว่าทั้งสองด้วยดินสอกระดาษและด้วยวิธีที่คุณควรลดความซับซ้อนของการแสดงออกเช่นstar(ε)=ε
, e.ε=e
, ∅+e=e
, ∅.e=∅
(ด้วยมือคุณเพียงแค่ไม่ได้เขียนขอบเมื่อมันไม่หรือแม้กระทั่งสำหรับห่วงตนเองและคุณไม่สนใจเมื่อมี ไม่มีการเปลี่ยนแปลงระหว่างและหรือและ )ε∅εq k q j q kqiqkqjqk
ตอนนี้วิธีการใช้งานremove(k)
? คุณไม่ควรลบสถานะสุดท้ายหรือเริ่มต้นเบา ๆ มิฉะนั้นคุณจะพลาดบางส่วนของภาษา
for i = 1 to n:
if not(final(i)) and not(initial(i)):
remove(i)
หากคุณมีสถานะสุดท้ายเพียงรัฐและสถานะเริ่มต้นหนึ่งสถานะดังนั้นนิพจน์สุดท้ายคือ:q sqfqs
e := star(L[s,s]) . L[s,f] . star(L[f,s] . star(L[s,s]) . L[s,f] + L[f,f])
หากคุณมีสถานะขั้นสุดท้ายหลายสถานะ (หรือแม้กระทั่งสถานะเริ่มต้น) ดังนั้นจึงไม่มีวิธีที่ง่ายในการผสานสถานะเหล่านี้นอกเหนือจากการใช้วิธีการปิด transitive โดยทั่วไปแล้วนี่ไม่ใช่ปัญหาด้วยมือ แต่มันก็น่าอึดอัดใจเมื่อเขียนอัลกอริทึม วิธีแก้ปัญหาที่ง่ายกว่ามากคือการแจกแจงคู่ทั้งหมดและเรียกใช้อัลกอริทึมบนกราฟ (แล้วลบรัฐ) เพื่อรับนิพจน์ทั้งหมดสมมติว่าเป็นสถานะเริ่มต้นเท่านั้นและเป็นขั้นสุดท้ายเท่านั้น ของรัฐแล้วทำสหภาพทุกF}e s , f s f e s , f(s,f)es,fsfes,f
สิ่งนี้และความจริงที่ว่านี่เป็นการแก้ไขภาษาแบบไดนามิกมากกว่าวิธีแรกทำให้เกิดข้อผิดพลาดได้ง่ายขึ้นเมื่อตั้งโปรแกรม ฉันแนะนำให้ใช้วิธีอื่น
จุดด้อย
มีหลายกรณีในอัลกอริทึมนี้ตัวอย่างเช่นสำหรับการเลือกโหนดที่เราควรลบจำนวนสุดท้ายของสถานะในตอนท้ายข้อเท็จจริงที่ว่าสถานะสุดท้ายสามารถเริ่มต้นได้เช่นกัน
โปรดทราบว่าขณะนี้อัลกอริทึมถูกเขียนขึ้นแล้วนี่เป็นวิธีการปิด transitive บริบทการใช้งานจะแตกต่างกันเท่านั้น ฉันไม่แนะนำให้ใช้อัลกอริทึม แต่การใช้วิธีทำด้วยมือเป็นความคิดที่ดี