วิธีการตรวจสอบว่าห้องที่ใช้ voxel 3D ถูกปิดผนึกอย่างมีประสิทธิภาพ


10

ฉันเคยมีปัญหาบางอย่างกับการพิจารณาว่าห้องขนาดใหญ่ถูกผนึกในห้อง 3D แบบ voxel หรือไม่ ฉันอยู่ในจุดที่ฉันพยายามอย่างหนักที่สุดในการแก้ปัญหาโดยไม่ขอความช่วยเหลือ แต่ไม่พยายามให้มากพอฉันจึงขอความช่วยเหลือ

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

ตอนนี้นี่เป็นวิธีที่ฉันทำ:

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

หากพื้นที่ไม่ได้ปิดผนึกให้เรียกใช้การวนซ้ำอีกครั้งด้วยการเปลี่ยนแปลงบางอย่าง:

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

นี่คือรหัสที่ฉันใช้: http://pastebin.com/NimyKncC

ปัญหา:

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

ฉันสงสัยว่าใครที่มีประสบการณ์เกี่ยวกับการเพิ่มประสิทธิภาพสามารถให้มือฉันหรืออย่างน้อยก็ชี้ให้ฉันไปในทิศทางที่ถูกต้อง ขอบคุณมัด


การตรวจสอบเฉพาะเมื่อสิ่งที่เปลี่ยนแปลงจะเป็นการเริ่มต้น ตรวจสอบทุก ๆ สามวินาทีดูเหมือนว่า overkill เพราะคุณรู้ว่าเมื่อ voxels เปลี่ยนไปซึ่งอาจทำให้ผนึก หาก voxel ที่ประกอบเป็นห้องที่ปิดสนิทเปลี่ยนไปคุณสามารถทำเครื่องหมายห้องนั้นว่าจะทำการตรวจสอบซ้ำมิฉะนั้นไม่ต้องกังวล
MichaelHouse

เนื่องจากอาจมีการเปลี่ยนแปลงของ voxels หลายร้อยรายการในกรอบเวลา 3 วินาทีนั้นฉันคิดว่ามันจะมีประสิทธิภาพมากกว่าที่จะทำมันเป็นระยะ ๆ แทนที่จะตรวจสอบว่ามีบางสิ่งเปลี่ยนไปในบริเวณใกล้เคียง ฉันจะทดลองกับสิ่งนั้น
NigelMan1010

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

คำตอบ:


3

ทางออกที่ดีที่สุดจะขึ้นอยู่กับหลายปัจจัยเช่นขนาดห้องที่คาดหวัง

  1. ตรวจสอบสิ่งนี้เท่านั้นเมื่อมีอะไรเปลี่ยนแปลง

วิธีที่ 1:

คุณสามารถใช้ A * เพื่อค้นหาเส้นทางจากช่องระบายอากาศไปยังกระเบื้องเหนือช่องระบายอากาศ / ช่องระบายอากาศของตัวเองหรือไปยังช่องว่างที่เรียกว่า vaccum หากพบเส้นทางห้องจะถูกปิดผนึก สิ่งนี้ไม่แตกต่างจากแนวทางปัจจุบันของคุณ แต่ควรเร็วขึ้น เมื่อพบแล้วให้ "เติมน้ำท่วม" เพื่อตั้งค่ากระเบื้องเป็นสูญญากาศ

วิธีที่ 2:

บางทีโครงสร้างด้านนอกของคุณเรียบเรียงน้อยลง - เนื่องจากมีพื้นผิวที่เป็นห้องคุณไม่จำเป็นต้องเคลื่อนที่ทั้ง 6 ทิศทางดังนั้นคุณควรเดินทางไปตามพื้นผิวทำเครื่องหมายกระเบื้องทุกอันที่คุณเดินทาง


0

เมื่อคุณค้นหาแบบเรียกซ้ำคุณแน่ใจหรือไม่ว่าคุณไม่ได้ตรวจสอบ voxel เดียวกันหลาย ๆ ครั้ง? ฉันไม่สามารถบอกได้จากวิธีที่คุณอธิบายอัลกอริทึมของคุณ แต่คุณควรมีการตั้งค่าสถานะบางอย่างเพื่อระบุว่าคุณได้ขยาย voxel ซ้ำแล้วซ้ำอีกดังนั้นคุณจะไม่ทำมากกว่าหนึ่งครั้ง

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

แก้ไข:

ฉันดูรหัสของคุณ ดูเหมือนว่าคุณกำลังใช้ LinkedList เพื่อระบุว่ามีการตรวจสอบ voxel แล้วเช่นเดียวกับในย่อหน้าแรกของฉัน คุณอาจได้ผลลัพธ์ที่ดีกว่าหากคุณใช้สิ่งอื่นนอกเหนือจาก LinkedList สำหรับสิ่งนี้ ลองใช้ HashSet หรืออะไรสักอย่าง? สิ่งนี้จะลดความซับซ้อนของวิธีการตรวจสอบของคุณจาก O (n) ถึง O (1)


ใช่ฉันเพิ่มลงใน LinkedList ชื่อ "ตรวจสอบ" แล้วตรวจสอบว่ารายการนั้นมีตำแหน่งก่อนตรวจสอบหรือไม่ ฉันคิดว่าการตรวจสอบว่ามีการเปลี่ยนแปลงอะไรที่จะต้องใช้ CPU เป็นอย่างมากเนื่องจาก voxels นับร้อยสามารถเปลี่ยนแปลงได้ภายในระยะเวลา 3 วินาทีนั้น ฉันจะดูว่าแฮชเซทเปรียบเทียบกับลิสต์ที่เชื่อมโยงในสถานการณ์นี้อย่างไรขอบคุณ
NigelMan1010
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.