ตัวอย่างของไฟไนต์สเตทจักร [ปิด]


25

ฉันกำลังมองหาตัวอย่างที่ดีของเครื่องจักรสถานะ จำกัด ; ภาษาไม่สำคัญเป็นอย่างยิ่ง แต่เป็นตัวอย่างที่ดี

การใช้งานโค้ดมีประโยชน์ (หลอกรหัสทั่วไป) แต่ก็มีประโยชน์มากในการรวบรวมการใช้งานต่างๆของ FSM

ตัวอย่างไม่จำเป็นต้องใช้คอมพิวเตอร์ตัวอย่างเช่นเครือข่ายรถไฟของ Mike Dunlavey นั้นมีประโยชน์มาก


12
นิพจน์ทั่วไปเป็นเครื่องจักรสถานะ จำกัด
chrisaycock

5
ฉันไม่เข้าใจว่าทำไมคำถามนี้จึงถูกทำเครื่องหมายว่า 'ไม่สร้างสรรค์' เมื่อพิจารณาเป็นเวลาเกือบ 2 ปีแล้วนับตั้งแต่ฉันนำเสนอคำตอบครั้งแรกว่ามันถูกปิดฉันขอยืนยันว่าจริงๆแล้วมันสร้างสรรค์มากและเป็นหัวข้อ
น้ำ

2
@ aqua - มันเป็นปัญหาของกองซ้อนจริงๆโปรแกรมเมอร์มันเป็นหน้าที่ที่จะต้องตอบคำถามคำถามที่เฉพาะเจาะจงมาก ๆ ซึ่งมีหนึ่งคำตอบ อย่างไรก็ตามคำถามเช่นนี้ซึ่งมีค่าจะไม่ถือว่าเป็น "สร้างสรรค์" (คำจำกัดความที่แย่มากของคำใน IMNSHO.) ตามคำจำกัดความของไซต์สแต็กโดยทั่วไป ตรงไปตรงมาเพื่อให้โปรแกรมเมอร์มีประโยชน์อย่างแท้จริงควรปรับใช้ความกระตือรือร้นน้อยลงในกฎนี้โดยเฉพาะ แต่ฉันแก่แล้วเหนื่อยล้าและมีส่วนร่วมเป็นอย่างอื่นเพื่อวางความพยายามที่จำเป็นลงใน
ocodo

1
ปัญหาที่แท้จริงอย่างมีประสิทธิภาพคือไซต์สแต็กเป็นหนึ่งในแหล่งข้อมูลคุณภาพสูงเพียงไม่กี่แห่งที่รู้จักกันดีและทำงานร่วมกันได้ดีและมีรูปแบบที่ดีและสามารถอ่านได้ ดูเหมือนว่าการลดลงในกองซ้อนนี้ชี้ไปที่ความต้องการรูปแบบไซต์ที่ใช้สำหรับ "คำถาม" เพื่อการศึกษา (อาจจะไม่ใช้คำ E)
ocodo

3
ฉันยังคงขอร้องให้ผู้คนเปิดคำถามนี้อีกครั้งเพราะตัวอย่างอีกมากจะดีมาก ความจริงที่น่าเศร้าก็คือถ้ายังไม่มีคำตอบใหม่ ๆ คำถามจะยังคงเปิดอยู่
ocodo

คำตอบ:


28

Safe (เรียกใช้เหตุการณ์)

  • สถานะ : สถานะ "ล็อค" หลายสถานะหนึ่งสถานะ "ปลดล็อค"
  • การเปลี่ยน : ชุดค่าผสม / คีย์ที่ถูกต้องจะย้ายคุณจากสถานะการล็อคเริ่มต้นไปยังสถานะการล็อคที่ใกล้กว่าเพื่อปลดล็อคจนกว่าคุณจะได้รับการปลดล็อคในที่สุด รวมกันไม่ถูกต้อง / คีย์ที่ดินคุณย้อนกลับไปในสถานะล็อคครั้งแรก (บางครั้งเรียกว่าไม่ได้ใช้งาน

ไฟจราจร (เรียกเวลา | เซ็นเซอร์ [เหตุการณ์] ถูกเรียก)

  • รัฐ : สีแดงสีเหลืองสีเขียว (ตัวอย่างง่ายที่สุด)
  • การเปลี่ยน : หลังจากตัวจับเวลาเปลี่ยนสีแดงเป็นสีเขียวสีเขียวเป็นสีเหลืองและสีเหลืองเป็นสีแดง อาจถูกกระตุ้นด้วยการตรวจจับรถยนต์ในสถานะต่างๆ (ซับซ้อนมากขึ้น)

ตู้หยอดเหรียญ (เหตุการณ์ถูกเรียก, รูปแบบที่ปลอดภัย )

  • รัฐ : IDLE, 5_CENTS, 10_CENTS, 15_CENTS, 20_CENTS, 25_CENTS, ฯลฯ , VEND, CHANGE
  • ช่วงการเปลี่ยนภาพ : การเปลี่ยนแปลงสถานะเมื่อแทรกเหรียญตั๋วเงินการเปลี่ยนเป็น VEND ตามจำนวนการซื้อที่ถูกต้อง (หรือมากกว่า) จากนั้นเปลี่ยนเป็น CHANGE หรือ IDLE (ขึ้นอยู่กับว่าเครื่องหยอดเหรียญของคุณมีจริยธรรมอย่างไร)

+1 และมากกว่าถ้าฉันทำได้ ทุกอย่างดูดียกเว้นอันสุดท้าย ควรเป็น IDLE, VEND และ CHANGE ค่าเป็นเงื่อนไขและควรแสดงว่าเป็นการเปลี่ยนระหว่าง IDLE กับตัวเอง นอกจากนี้คุณยังต้องการให้รัฐแสดงว่ามีการเลือกรายการ
Evan Plaice

@EvanPlaice: จะไม่เลือกรายการเพียงเหตุการณ์ที่ทำให้เกิดการเปลี่ยนแปลงจาก IDLE เป็น VEND ใช่ไหม นอกเสียจากว่าคุณจะจินตนาการถึงวิธีการยืนยันการเลือกก่อนจำหน่าย
Misko

มีโอกาสไดอะแกรมสำหรับสองสิ่งนี้หรือไม่?
ocodo

นี่เป็นตัวอย่างเดียวกับที่ระบุในหน้าFSM Wikipediaซึ่งรวมถึงลิฟท์: "ตัวอย่างง่ายๆคือเครื่องหยอดเหรียญซึ่งจ่ายผลิตภัณฑ์เมื่อมีการสะสมเหรียญที่เหมาะสมลิฟต์จะกำหนดลิฟต์ตามลำดับการหยุด โดยผู้ขับขี่สัญญาณไฟจราจรซึ่งเปลี่ยนลำดับเมื่อรถยนต์กำลังรอและล็อคการรวมซึ่งจำเป็นต้องป้อนหมายเลขผสมในลำดับที่เหมาะสม "
icc97

1
@ icc97 ตัวอย่าง FSM นั้นมีมากมายและพบได้ทั่วไปในชีวิตประจำวัน อนึ่งการโพสต์การแลกเปลี่ยนสแต็คก่อนวันรวมของข้อมูลตัวอย่างเช่นในหน้าวิกิพีเดีย :)
น้ำ

14

ตัวอย่างโปรโตคอลเกตเวย์เกตเวย์

BGP เป็นโปรโตคอลที่สนับสนุนการตัดสินใจในการกำหนดเส้นทางหลักบนอินเทอร์เน็ต มันเก็บรักษาตารางเพื่อพิจารณาการเข้าถึงของโฮสต์จากโหนดที่กำหนดและทำให้อินเทอร์เน็ตมีการกระจายอำนาจอย่างแท้จริง

ในเครือข่ายแต่ละBGPโหนดเพียร์และการใช้เครื่องสถานะ จำกัด กับหนึ่งในหกรัฐไม่ได้ใช้งาน , การเชื่อมต่อ , การใช้งาน , OpenSent , OpenConfirmและก่อตั้งขึ้น การเชื่อมต่อเพียร์แต่ละรายการในเครือข่ายรักษาสถานะเหล่านี้อย่างใดอย่างหนึ่ง

โปรโตคอล BGP กำหนดข้อความที่ส่งไปยังเพื่อนเพื่อเปลี่ยนสถานะของพวกเขา

BPG statechart

BGP สถานะชาร์ต

ว่าง

ครั้งแรกที่รัฐไม่ได้ใช้งาน ในสถานะนี้ BGP จะเริ่มต้นทรัพยากรและปฏิเสธการพยายามเชื่อมต่อขาเข้าและเริ่มต้นการเชื่อมต่อกับเพื่อน

เชื่อมต่อ

เป็นรัฐที่สองเชื่อมต่อ ในสถานะนี้เราเตอร์จะรอให้การเชื่อมต่อเสร็จสมบูรณ์และเปลี่ยนเป็นสถานะOpenSentหากสำเร็จ หากไม่สำเร็จจะรีเซ็ตตัวจับเวลา ConnectRetry และการเปลี่ยนเป็นสถานะใช้งานเมื่อหมดอายุ

คล่องแคล่ว

ในสถานะใช้งานเราเตอร์จะรีเซ็ตตัวจับเวลา ConnectRetry เป็นศูนย์และกลับสู่สถานะเชื่อมต่อ

OpenSent

ในสถานะOpenSentเราเตอร์จะส่งข้อความ Open และรอหนึ่งค่าตอบแทน ข้อความ Keepalive มีการแลกเปลี่ยนและเมื่อได้รับที่ประสบความสำเร็จเราเตอร์จะอยู่ในสถานะที่จัดตั้งขึ้น

ที่จัดตั้งขึ้น

ในการก่อตั้งรัฐเราเตอร์สามารถส่ง / รับ: Keepalive; อัปเดต; และข้อความแจ้งเตือนไปยัง / จากเพียร์

เพิ่มเติมข้อมูลเกี่ยวกับ BGP อยู่ในวิกิพีเดีย


@tcrosley - มาจากวิกิพีเดียดังนั้นจึงไม่สมควรได้รับเครดิต
ocodo

1
ตกลง +1 สำหรับรวมไดอะแกรม :)
tcrosley

ผมพยายามที่จะแก้ไขป้ายชื่อของแผนภูมิเพื่อ BGP แต่มันจะไม่ให้ฉัน - ตัวอักษรไม่เพียงพอ :)
ไมค์ Dunlavey

ต้องมีวิธีที่ดีกว่าในการวาดสิ่งนี้
งาน

1
@ งาน - การตอบกลับช้าไปหน่อยขอโทษ แต่ตอนนี้ฉันคิดว่านี่เป็นตัวอย่างที่ลึกลับเกินไปตู้เซฟหยอดเหรียญ ฯลฯ เป็นวิธีที่มีประโยชน์มากกว่าที่ฉันคิด
ocodo

7

มันมีประโยชน์สำหรับการสร้างแบบจำลองทุกสิ่ง ตัวอย่างเช่นรอบการเลือกตั้งสามารถสร้างแบบจำลองกับรัฐตามแนวของ (รัฐบาลปกติ) - การเลือกตั้งที่เรียกว่า -> (การรณรงค์ในช่วงต้น) - รัฐสภายุบ -> (การรณรงค์หนัก) - การเลือกตั้ง -> (การนับคะแนนเสียง ) จากนั้นทั้งสอง (นับคะแนนเสียง) - ไม่มีเสียงข้างมาก -> (การเจรจาสัมพันธมิตร) - บรรลุข้อตกลง -> (รัฐบาลปกติ) หรือ (นับคะแนนเสียง) - เสียงข้างมาก -> (รัฐบาลปกติ) ฉันใช้งานชุดรูปแบบนี้ในเกมที่มีเกมย่อยทางการเมือง

พวกมันถูกใช้ในด้านอื่น ๆ ของเกมเช่นกัน AI มักจะเป็นของรัฐ การเปลี่ยนระหว่างเมนูและระดับและการเปลี่ยนเมื่อความตายหรือระดับที่เสร็จสมบูรณ์มักเป็นแบบอย่างที่ดีโดย FSM


++ เป็นตัวอย่างที่ดี
Mike Dunlavey

1
+1 ตัวอย่างที่ดีของ DFM (Machine Finite State Machine) เนื่องจากเส้นทาง
Evan Plaice

4

ตัวแยกวิเคราะห์ CSV ใช้ในปลั๊กอินjquery-csv

มันเป็นตัวแยกวิเคราะห์ไวยากรณ์พื้นฐาน Chomsky Type III

tokenizer ของ regex ใช้ในการประเมินข้อมูลแบบ char-by-char เมื่อพบตัวควบคุมถ่านรหัสจะถูกส่งไปยังคำสั่งสลับเพื่อการประเมินผลเพิ่มเติมตามสถานะเริ่มต้น อักขระที่ไม่ได้ควบคุมจะถูกจัดกลุ่มและคัดลอก en masse เพื่อลดจำนวนการดำเนินการคัดลอกสตริงที่จำเป็น

tokenizer:

var tokenizer = /("|,|\n|\r|[^",\r\n]+)/;

การจับคู่ชุดแรกคืออักขระควบคุม: ตัวคั่นค่า (") ตัวคั่นค่า (,) และตัวคั่นรายการ (การขึ้นบรรทัดใหม่ทั้งหมด) การจับคู่ครั้งสุดท้ายจัดการการจัดกลุ่มถ่านที่ไม่ได้ควบคุม

มีกฎ 10 ข้อที่ parser ต้องเป็นไปตาม:

  • กฎ # 1 - หนึ่งรายการต่อบรรทัดแต่ละบรรทัดลงท้ายด้วยขึ้นบรรทัดใหม่
  • กฎ # 2 - การขึ้นบรรทัดใหม่ที่ท้ายไฟล์ถูกตัดออก
  • กฎ # 3 - แถวแรกมีข้อมูลส่วนหัว
  • กฎ # 4 - ช่องว่างถือเป็นข้อมูลและรายการไม่ควรมีเครื่องหมายจุลภาคต่อท้าย
  • กฎ # 5 - เส้นอาจหรือไม่ถูกคั่นด้วยเครื่องหมายคำพูดคู่
  • กฎ # 6 - ฟิลด์ที่มีตัวแบ่งบรรทัดอัญประกาศคู่และเครื่องหมายจุลภาคควรอยู่ในเครื่องหมายคำพูดคู่
  • กฎ # 7 - หากใช้เครื่องหมายอัญประกาศคู่เพื่อใส่เขตข้อมูลดังนั้นเครื่องหมายอัญประกาศคู่ที่ปรากฏภายในเขตข้อมูลจะต้องถูกหลีกเลี่ยงโดยนำหน้าด้วยเครื่องหมายคำพูดคู่อื่น
  • การแก้ไข # 1 - ฟิลด์ที่ไม่มีเครื่องหมายอัญประกาศอาจหรืออาจ
  • แก้ไข # 2 - ฟิลด์ที่ยกมาอาจหรือไม่
  • การแก้ไข # 3 - ฟิลด์สุดท้ายในรายการอาจมีค่า Null หรือไม่ก็ได้

หมายเหตุ: ด้านบน 7 กฎจะได้มาโดยตรงจากIETF RFC 4180 มีการเพิ่ม 3 รายการล่าสุดเพื่อครอบคลุมกรณีขอบที่แนะนำโดยแอปสเปรดชีตที่ทันสมัย ​​(เช่น Excel, Google Spreadsheet) ที่ไม่ได้กำหนดขอบเขต (เช่นอัญประกาศ) ค่าทั้งหมดเป็นค่าเริ่มต้น ฉันลองบริจาคการเปลี่ยนแปลงกลับไปที่ RFC แต่ยังไม่ได้ยินการตอบกลับคำถามของฉัน

เพียงพอกับลมขึ้นนี่คือแผนภาพ:

เครื่องแยกวิเคราะห์สถานะ จำกัด CSV

สหรัฐอเมริกา:

  1. สถานะเริ่มต้นสำหรับรายการและ / หรือค่า
  2. พบคำพูดเปิด
  3. พบคำพูดที่สอง
  4. พบค่าที่ไม่ยกมา

การเปลี่ยน:

  • ตรวจสอบทั้งค่าที่ยกมา (1), ค่าที่ไม่ยกมา (3), ค่า Null (0), รายการ Null (0), และรายการใหม่ (0)
  • ข ตรวจสอบถ่านคำพูดที่สอง (2)
  • ค ตรวจสอบใบเสนอราคาที่หลบหนี (1), จุดสิ้นสุดของค่า (0), และจุดสิ้นสุดของรายการ (0)
  • d ตรวจสอบจุดสิ้นสุดของค่า (0) และจุดสิ้นสุดของรายการ (0)

หมายเหตุ: จริง ๆ แล้วมันไม่มีสถานะ ควรมีบรรทัดจาก 'c' -> 'b' ที่มีสถานะ '1' เนื่องจากตัวคั่นตัวที่สองที่ใช้ค่า Escape หมายความว่าตัวคั่นตัวแรกยังคงเปิดอยู่ ในความเป็นจริงมันอาจจะดีกว่าที่จะแสดงว่ามันเป็นช่วงการเปลี่ยนภาพอื่น การสร้างสิ่งเหล่านี้เป็นศิลปะไม่มีวิธีที่ถูกต้องเพียงอย่างเดียว

หมายเหตุ: นอกจากนี้ยังขาดสถานะออก แต่ในข้อมูลที่ถูกต้องตัวแยกวิเคราะห์จะสิ้นสุดในช่วงการเปลี่ยนภาพ 'a' และไม่มีสถานะใดที่เป็นไปได้เนื่องจากไม่มีสิ่งใดที่จะแยกวิเคราะห์

ความแตกต่างระหว่างรัฐและช่วงการเปลี่ยนภาพ:

รัฐมีขอบเขต จำกัด ซึ่งหมายความว่าสามารถอนุมานได้ว่าหมายถึงสิ่งเดียวเท่านั้น

ช่วงการเปลี่ยนภาพหมายถึงการไหลระหว่างรัฐดังนั้นมันอาจหมายถึงหลายสิ่งหลายอย่าง

โดยพื้นฐานแล้วความสัมพันธ์ของการเปลี่ยนสถานะ -> คือ 1 -> * (เช่นหนึ่งต่อหลายรายการ) รัฐจะกำหนดว่า 'มันคืออะไร' และการเปลี่ยนผ่านจะกำหนด 'วิธีจัดการ'

หมายเหตุ: ไม่ต้องกังวลหากแอปพลิเคชันของสถานะ / ช่วงการเปลี่ยนภาพไม่รู้สึกเป็นธรรมชาติ แต่ก็ไม่ง่าย มันครอบคลุมบางส่วนที่สอดคล้องกับใครบางคนที่ฉลาดกว่าฉันก่อนที่ฉันจะได้แนวคิดในการติด

รหัสหลอก:

csv = // csv input string

// init all state & data
state = 0
value = ""
entry = []
output = []

endOfValue() {
  entry.push(value)
  value = ""
}

endOfEntry() {
  endOfValue()
  output.push(entry)
  entry = []
}

tokenizer = /("|,|\n|\r|[^",\r\n]+)/gm

// using the match extension of string.replace. string.exec can also be used in a similar manner
csv.replace(tokenizer, function (match) {
  switch(state) {
    case 0:
      if(opening delimiter)
        state = 1
        break
      if(new-line)
        endOfEntry()
        state = 0
        break
      if(un-delimited data)
        value += match
        state = 3
        break
    case 1:
      if(second delimiter encountered)
        state = 2
        break
      if(non-control char data)
        value += match
        state = 1
        break
    case 2:
      if(escaped delimiter)
        state = 1
        break
      if(separator)
        endOfValue()
        state = 0
        break
      if(newline)
        endOfEntry()
        state = 0
        break
    case 3:
      if(separator)
        endOfValue()
        state = 0
        break
      if(newline)
        endOfEntry()
        state = 0
        break
  }
}

หมายเหตุ: นี่คือส่วนสำคัญในทางปฏิบัติมีมากขึ้นที่จะต้องพิจารณา ตัวอย่างเช่นการตรวจสอบข้อผิดพลาดค่า Null, บรรทัดว่างต่อท้าย (เช่นที่ถูกต้อง) ฯลฯ

ในกรณีนี้สถานะเป็นเงื่อนไขของสิ่งต่าง ๆ เมื่อบล็อกการจับคู่ regex สิ้นสุดการวนซ้ำ การเปลี่ยนแปลงถูกแสดงเป็นคำสั่ง case

ในฐานะมนุษย์เรามีแนวโน้มที่จะทำให้การปฏิบัติงานระดับต่ำเป็นนามธรรมที่สูงขึ้นได้ง่ายขึ้น แต่การทำงานกับ FSM กำลังทำงานกับการดำเนินงานระดับต่ำ ในขณะที่รัฐและช่วงการเปลี่ยนภาพนั้นง่ายมากที่จะทำงานกับบุคคลมันเป็นเรื่องยากที่จะเห็นภาพรวมทั้งหมดในครั้งเดียว ฉันพบว่ามันง่ายที่สุดในการติดตามแต่ละเส้นทางของการดำเนินการซ้ำไปซ้ำมาจนกว่าฉันจะรู้ได้ว่าการเปลี่ยนภาพนั้นเล่นออกมาได้อย่างไร มันเป็นราชาแห่งการเรียนรู้คณิตศาสตร์ขั้นพื้นฐานคุณจะไม่สามารถประเมินโค้ดจากระดับที่สูงขึ้นจนกว่ารายละเอียดระดับต่ำจะเริ่มเป็นอัตโนมัติ

นอกเหนือจาก: หากคุณดูการใช้งานจริงมีรายละเอียดมากมายที่หายไป ก่อนอื่นเส้นทางที่เป็นไปไม่ได้ทั้งหมดจะส่งข้อยกเว้นเฉพาะ มันเป็นไปไม่ได้ที่จะตีพวกเขา แต่ถ้ามีอะไรผิดพลาดพวกเขาจะก่อให้เกิดข้อยกเว้นอย่างแน่นอนในนักวิ่งทดสอบ ประการที่สองกฎ parser สำหรับสิ่งที่ได้รับอนุญาตในสตริงข้อมูล CSV "ถูกกฎหมาย" จะค่อนข้างหลวมดังนั้นรหัสที่จำเป็นในการจัดการกับกรณีขอบจำนวนมาก นี่เป็นกระบวนการที่ใช้ในการเยาะเย้ย FSM ก่อนการแก้ไขบั๊กส่วนขยายและการปรับแต่งทั้งหมด

เช่นเดียวกับการออกแบบส่วนใหญ่มันไม่ได้เป็นตัวแทนที่แท้จริงของการใช้งาน แต่มันสรุปส่วนที่สำคัญ ในทางปฏิบัติจริง ๆ แล้วมีฟังก์ชันแยกวิเคราะห์ที่แตกต่างกัน 3 ฟังก์ชันที่ได้รับจากการออกแบบนี้: ตัวแยกบรรทัดเฉพาะ csv, ตัวแยกวิเคราะห์บรรทัดเดียวและตัวแยกวิเคราะห์หลายบรรทัดที่สมบูรณ์ พวกเขาทั้งหมดทำงานในลักษณะที่คล้ายกันพวกเขาต่างกันในวิธีที่พวกเขาจัดการกับอักขระขึ้นบรรทัดใหม่


1
โว้ว! ผลงานที่ดีมาก
ocodo

@Slomojo ขอบคุณฉันมีความสุขที่จะแบ่งปัน ฉันไม่ได้ไปโรงเรียนเพื่อ CS ดังนั้นฉันต้องเรียนรู้สิ่งนี้ด้วยตัวเอง มันยากมากที่จะหาแอปพลิเคชันในโลกแห่งความเป็นจริงซึ่งครอบคลุมหัวข้อ CS ระดับสูงเช่นออนไลน์ ในที่สุดฉันก็วางแผนที่จะทำอัลกอริธึม parser อย่างละเอียดเพื่อที่จะเป็นประโยชน์กับคนอื่นเช่นฉันในอนาคต เป็นการเริ่มต้นที่ดี
Evan Plaice

ฉันสอนตัวเองด้วย แต่ฉันเริ่มเมื่อ 30 ปีที่แล้วดังนั้นตอนนี้ฉันก็ได้ครอบคลุมหลักสูตร CS แล้ว :) ฉันโพสต์คำถามนี้สำหรับคนที่ชอบคุณและฉัน ฉันคิดว่ามันง่ายกว่ามากที่จะเรียนรู้ทฤษฎีระดับต่ำมากตั้งแต่นั้นมาเพราะมีสิ่งที่ทำให้ไขว้เขวน้อยลงและมีโอกาสมากขึ้นที่จะทำงานใกล้ชิดกับโลหะแม้ว่าจะไม่มีอินเทอร์เน็ตจริงๆและเราทุกคนอาศัยอยู่ในถ้ำ
ocodo

3

Simple FSM ใน Java

int i=0;

while (i<5) {
 switch(i) {
   case 0:
     System.out.println("State 0");
     i=1;
     break;
   case 1:
     System.out.println("State 1");
     i=6;
     break;
   default:
     System.out.println("Error - should not get here");
     break;      
  }

} 

ไปแล้ว ตกลงมันไม่ได้ยอดเยี่ยม แต่มันแสดงให้เห็นความคิด

คุณมักจะพบ FSM ในผลิตภัณฑ์โทรคมนาคมเพราะพวกเขานำเสนอวิธีแก้ปัญหาอย่างง่ายสำหรับสถานการณ์ที่ซับซ้อน


3
พวกเขายังเป็นส่วนสำคัญของการสร้างคอมไพเลอร์ในการวิเคราะห์คำศัพท์
jmq

@jmquigley คุณสามารถเพิ่มคำตอบได้ไหม?
ocodo

1
ฉันได้เพิ่มคำตอบแยกต่างหากโดยมีลิงก์สำหรับคุณสองสามข้อ
jmq

3

ฉันพบว่าการคิดถึง / การสร้างแบบจำลองลิฟต์ (ลิฟท์) เป็นตัวอย่างที่ดีของเครื่องจักรสถานะ จำกัด มันต้องการวิธีการแนะนำเล็กน้อย แต่ให้สถานการณ์ที่ไม่สำคัญในการนำมาใช้

ยกตัวอย่างเช่นรัฐอยู่ที่ชั้นล่างที่ชั้นหนึ่ง ฯลฯ และย้ายพื้นดินไปที่ชั้นหนึ่งหรือย้ายที่สามไปที่ชั้นล่าง แต่ปัจจุบันระหว่างชั้น 3 และ 2 และอื่น ๆ

ผลกระทบของปุ่มในกรงลิฟท์และที่ชั้นให้อินพุตปัจจัยที่ขึ้นอยู่กับทั้งสองปุ่มที่ถูกกดพร้อมกับสถานะปัจจุบัน

แต่ละชั้นยกเว้นด้านบนและด้านล่างจะมีสองปุ่ม: อันหนึ่งเพื่อขอให้ลิฟท์ขึ้นไปอีกอันหนึ่งลงไป


2

ตกลงนี่เป็นตัวอย่าง สมมติว่าคุณต้องการแยกจำนวนเต็ม มันจะเป็นแบบdd*ที่dเป็นเลขจำนวนเต็ม

state0:
    if (!isdigit(*p)) goto error;
    p++;
    goto state1;
state1:
    if (!isdigit(*p)) goto success;
    p++;
    goto state1;

แน่นอนว่า @Gary กล่าวว่าคุณสามารถปลอมแปลงgotos เหล่านั้นโดยใช้คำสั่ง switch และตัวแปรสถานะ ขอให้สังเกตว่าสามารถจัดโครงสร้างให้รหัสนี้ซึ่ง isomorphic เพื่อการแสดงออกปกติเดิม:

if (isdigit(*p)){
    p++;
    while(isdigit(*p)){
        p++;
    }
    // success
}
else {
    // error
}

แน่นอนคุณสามารถทำได้ด้วยตารางการค้นหา

เครื่องจักรสถานะ จำกัด สามารถทำได้หลายวิธีและหลายสิ่งสามารถอธิบายได้เป็นอินสแตนซ์ของเครื่องจักรสถานะ จำกัด มันไม่ได้เป็น "เรื่อง" มากนักสำหรับการคิดเกี่ยวกับสิ่งต่าง ๆ

ตัวอย่างเครือข่ายทางรถไฟ

ตัวอย่างหนึ่งของ FSM คือเครือข่ายทางรถไฟ

มีจำนวน จำกัด ของสวิตช์ที่รถไฟสามารถเข้าสู่หนึ่งในสองทาง

มีจำนวน จำกัด ของแทร็กที่เชื่อมต่อสวิตช์เหล่านี้

เมื่อใดก็ตามที่รถไฟอยู่บนแทร็กหนึ่งสามารถส่งไปยังแทร็กอื่นได้โดยข้ามสวิตช์โดยอิงจากข้อมูลอินพุตหนึ่งบิต


(ฉันได้แก้ไขคำตอบของคุณแล้วฉันหวังว่าคุณจะอนุมัติ)
ocodo

@Slomojo: ไม่เป็นไร ดูดี.
Mike Dunlavey

2

เครื่องจักรสถานะ จำกัด ในทับทิม:

module Dec_Acts
 def do_next
    @now = @next
    case @now
    when :invite
      choose_round_partner
      @next = :wait
    when :listen
      @next = :respond
    when :respond
      evaluate_invites
      @next = :update_in
    when :wait
      @next = :update_out
    when :update_in, :update_out
      update_edges
      clear_invites
      @next = :exchange
    when :exchange
      update_colors
      clear_invites
      @next = :choose
    when :choose
      reset_variables
      choose_role
    when :done
      @next = :done
    end
  end
end

นั่นเป็นพฤติกรรมของการคำนวณโหนดเดียวในระบบกระจายการตั้งค่ารูปแบบการสื่อสารที่เชื่อมโยง มากหรือน้อย. ในรูปแบบกราฟฟิคดูเหมือนว่านี้:

ป้อนคำอธิบายรูปภาพที่นี่


+1 น่าสนใจ DGMM หมายถึงอะไร
Evan Plaice

@EvanPlaice มันกระจายอัลกอริทึมปกคลุมขั้นต่ำน้ำหนักถ่วงน้ำหนักสูงสุดกระจายขั้นตอนวิธี (DGMM) ... คำย่อที่ย่อเล็กน้อยไม่ถามฉันว่า G มาจากไหน
ocodo

@slomojo "G" มีไว้สำหรับ "Generalized" อัลกอริธึมเรียงลำดับซึ่งสิ่งนี้ได้รับมาใช้เทคนิคที่เรียกว่าการจับคู่สูงสุดทั่วไป
philosodad

@philosodad ฉันถือว่ามาก แต่ฉันไม่ชอบการโพสต์ข้อสมมติฐาน
ocodo

1

ลองดูลิงค์นี้สำหรับตัวอย่างง่ายๆของการวิเคราะห์คำ (FSM):

http://ironbark.bendigo.latrobe.edu.au/subjects/SS/clect/clect03.html

นอกจากนี้คุณยังสามารถดูตัวอย่าง "หนังสือมังกร" (ไม่ใช่การอ่านแบบเบา ๆ )

http://en.wikipedia.org/wiki/Compilers:_Principles,_Techniques,_and_Tools


0

ในทางปฏิบัติเครื่องรัฐมักใช้สำหรับ:

  • วัตถุประสงค์ในการออกแบบ (การสร้างแบบจำลองการกระทำที่แตกต่างในโปรแกรม)
  • parsers ภาษาธรรมชาติ (ไวยากรณ์)
  • การแยกสตริง

ตัวอย่างหนึ่งคือเครื่องสถานะที่สแกนสตริงเพื่อดูว่ามีไวยากรณ์ที่ถูกต้องหรือไม่ เช่นรหัสไปรษณีย์ของดัตช์ได้รับการจัดรูปแบบเป็น "1234 AB" ส่วนแรกอาจประกอบด้วยตัวเลขตัวอักษรตัวที่สองเท่านั้น สามารถเขียน State Machine ที่ติดตามว่าอยู่ในสถานะ NUMBER หรือในสถานะ LETTER และหากพบการป้อนข้อมูลผิดให้ปฏิเสธ

เครื่องรัฐตัวรับนี้มีสองสถานะ: เป็นตัวเลขและอัลฟา เครื่องสถานะเริ่มต้นในสถานะตัวเลขและเริ่มอ่านตัวอักษรของสตริงที่จะตรวจสอบ หากพบอักขระที่ไม่ถูกต้องในระหว่างสถานะใด ๆ ฟังก์ชันจะส่งคืนด้วยค่าเท็จโดยปฏิเสธว่าอินพุตไม่ถูกต้อง

รหัสหลาม:

import string

STATE_NUMERIC = 1
STATE_ALPHA = 2

CHAR_SPACE = " "

def validate_zipcode(s):
cur_state = STATE_NUMERIC

for char in s:
    if cur_state == STATE_NUMERIC:
        if char == CHAR_SPACE:
            cur_state = STATE_ALPHA
        elif char not in string.digits:
            return False
    elif cur_state == STATE_ALPHA:
        if char not in string.letters:
            return False
return True

zipcodes = [
    "3900 AB",
    "45D6 9A",
]

for zipcode in zipcodes:
    print zipcode, validate_zipcode(zipcode)

ที่มา: (จำกัด ) เครื่องจักรของรัฐในทางปฏิบัติ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.