เป็นไปได้หรือไม่ที่จะแสดงการกลายพันธุ์ของวัตถุกราฟได้อย่างมีประสิทธิภาพกับสถานะที่เปลี่ยนแปลงไม่ได้?


12

ฉันกำลังฝึกใช้วัตถุที่ไม่เปลี่ยนรูปใน C ++ เป้าหมายส่วนตัวของฉันแสดงกราฟวัตถุทั่วไป (เป็นกอง) กับลำดับของกราฟที่ไม่เปลี่ยนรูป

การสร้างกราฟหลายรุ่นนั้นไม่ได้ยากขนาดนั้น ปัญหาคือประสิทธิภาพ การกำหนดเวอร์ชันแบบเดรัจฉานต้องการสำเนากราฟเต็มรูปแบบและไม่สามารถยอมรับได้

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

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

เป็นไปได้หรือไม่ที่จะแสดงการกลายพันธุ์ของกราฟวัตถุอย่างมีประสิทธิภาพด้วยสถานะไม่เปลี่ยนรูป?


1
เป็นเรื่องยากเพียงเพราะคุณวางขอบบนโหนด หากคุณเก็บขอบไว้ภายนอกในคอลเลกชันที่ไม่เปลี่ยนรูปแบบมันจะง่าย
dan_waterworth

@dan_waterworth หากฉันใช้รายการ adjacency ฉันต้องค้นหาขอบแต่ละครั้งในแต่ละครั้ง ดังนั้นฉันคิดว่ามันเป็นการแลกเปลี่ยนระหว่างการอ่านและการเขียน
Eonil

1
มันไม่จำเป็นต้องเป็นรายการ
dan_waterworth

@dan_waterworth คุณหมายถึงบางอย่างเช่น B-tree ใช่ไหม
Eonil

2
ต้นไม้กว้างเช่นต้นไม้ B มีแนวโน้มที่จะใช้เมื่อเวลาแฝงของสื่อจัดเก็บข้อมูลสูง ในกรณีนี้คุณอาจจะดีกว่าถ้ามีบางสิ่งที่แคบกว่า แต่ใช่แผนภูมิการค้นหาที่สมดุลบางประเภทจะเป็นแนวคิดที่ดี
dan_waterworth

คำตอบ:


11

สิ่งที่คุณกำลังมองหาเรียกว่าโครงสร้างข้อมูลถาวร ทรัพยากรที่ยอมรับสำหรับโครงสร้างข้อมูลแบบถาวรเป็นหนังสือของคริสโอคาสากิหมดจดหน้าที่โครงสร้างข้อมูล โครงสร้างข้อมูลถาวรได้รวบรวมความสนใจในครั้งล่าสุดเนื่องจากความนิยมใน Clojure และ Scala

อย่างไรก็ตามด้วยเหตุผลบางอย่างที่แปลกกราฟแบบถาวรดูเหมือนจะไม่ได้รับความสนใจเป็นส่วนใหญ่ เรามีรายการต้นไม้หลากหลายชนิดอาร์เรย์ลำดับความสำคัญคิวแผนที่ แต่ไม่มีกราฟ

ฉันพบเพียงหนึ่งกระดาษจริง ๆ : กราฟถาวรอย่างเต็มที่ - เลือกอันไหน?


4

หากคุณไม่พิจารณาการเชื่อมต่อระหว่างวัตถุที่จะเป็นส่วนหนึ่งของทรัพยากรเวอร์ชันของคุณ (และคุณอาจ - ซึ่งในกรณีต่อไปนี้อาจไม่ได้ช่วยอะไรมาก) คุณสามารถพิจารณาแยกวัตถุของคุณออกเป็นส่วนที่แสดงถึงส่วนการเชื่อมต่อ ของวัตถุและชิ้นส่วนที่แสดงถึงสถานะที่ไม่เปลี่ยนรูป

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

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

หากการเชื่อมต่อระหว่างวัตถุเป็นส่วนหนึ่งของสถานะเวอร์ชันของคุณแสดงว่าสิ่งที่กล่าวมาไม่ทำงาน แต่บางทีคุณสามารถขยายได้ดังนี้

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

ตรรกะเดียวกันที่อธิบายข้างต้นใช้สำหรับการอัปเดตเวอร์ชันภายในที่จับซึ่งช่วยให้สามารถอัปเดตที่แปลเป็นภาษาท้องถิ่นได้


3

มีวิธีแก้ไขปัญหานี้ที่เผยแพร่แล้วซึ่งมีความซับซ้อนของเวลาที่ถูกตัดจำหน่ายที่ดีมาก แต่หาได้ยากเมื่อคุณไม่รู้ว่าจะต้องค้นหาอะไร คุณสามารถหาบทสรุปเหล่านี้มีความสุขในเอกสารประกอบการบรรยาย (ส่วนการตรวจสอบ 2.2.3) หรืออ่านกระดาษเดิมทำโครงสร้างข้อมูลแบบต่อเนื่อง หากกราฟวัตถุของคุณมีการเชื่อมต่อที่ จำกัด (เช่นโครงสร้างที่มีลักษณะคล้ายต้นไม้) คุณสามารถเข้าถึงความซับซ้อน O (1) ที่ตัดจำหน่ายได้สำหรับทั้งการอ่านและการอัปเดตกราฟที่ไม่เปลี่ยนรูปซึ่งน่าประทับใจ

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

  • วัตถุที่คุณต้องการเปลี่ยนยังคงมีพื้นที่สำหรับการเปลี่ยนแปลง คุณสามารถจัดเก็บการเปลี่ยนแปลงได้โดยตรงในวัตถุ

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

    หากวัตถุอ้างอิงนั้นยังมีพื้นที่สำหรับการเปลี่ยนแปลงคุณสามารถจัดเก็บการเปลี่ยนแปลงในการอ้างอิงโดยตรงมิฉะนั้นมันจะเรียงซ้อนซ้ำ

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

เมื่อใช้สิ่งนี้ฉันพยายามซ่อนความซับซ้อนนี้ไว้ใน API เมื่ออ้างอิงบางอย่างในกราฟที่ไม่เปลี่ยนรูปจากภายนอกฉันใช้ stubs ที่สร้างขึ้นแทนการอ้างอิงโดยตรงดังนั้นผู้โทรไม่จำเป็นต้องส่งเวอร์ชันที่ต้องการด้วยตนเอง ทำให้การอ้างอิงมีราคาแพงกว่าตัวชี้โดยตรงเล็กน้อย แต่ฉันคิดว่ามันคุ้มค่ากับความสะดวกสบาย

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