อัลกอริทึมสำหรับ "รักษา" หลายรูปสี่เหลี่ยมให้เป็นรูปสี่เหลี่ยมผืนผ้าจำนวนน้อยลงหรือไม่?


14

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

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

ภาพด้านบนเป็นกรณีที่ง่ายมากและช่องว่างระหว่างสี่เหลี่ยมใช้สำหรับการสร้างภาพข้อมูลเท่านั้น - จริง ๆ แล้วพวกเขาจะได้รับการบรรจุแน่น

ชื่อวิธีหรืออัลกอริทึม (ยินดีที่จะ google) ที่สามารถช่วยฉันทำสิ่งนี้คืออะไร?


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

มีตารางพื้นฐานของสี่เหลี่ยม (เช่นกระดานหมากรุก) และแต่ละสี่เหลี่ยมจะแบ่งเขตแดนกับสี่เหลี่ยมพื้นฐานเหล่านั้น เช่นคุณสามารถใช้จำนวนเต็มเพื่ออธิบายด้านบน / ล่าง / ซ้าย / ขวาของทุกสี่เหลี่ยม ดังนั้นจึงไม่สามารถหมุนในมุมที่ไม่สามารถหารได้ 90 องศา นอกจากนี้ตาราง NxM ยังเต็มไปด้วยสี่เหลี่ยม - ไม่มีตำแหน่งกริดเปิด
xaxxon

ฉันแค่พยายามหลีกเลี่ยงกรณีที่ดูเหมือนตัวอย่างข้างต้น (จากมุมมองของสี) แต่มันประกอบด้วยสี่เหลี่ยม 1x1 ตันและฉันประมวลผลแต่ละภาพเมื่อฉันสามารถจัดการพื้นที่ในหลาย ๆ โทรน้อยลง
xaxxon

ฉันคาดเดาบางอย่างของ "เพิ่งเริ่มต้นที่ไหนสักแห่งและพยายามสี่เหลี่ยมที่ใหญ่กว่าและใหญ่กว่าในมิติเดียว (พูดในแนวตั้ง) จนกว่าคุณจะตีเส้นขอบสีแล้วขยายมิติอื่น (แนวนอน) จนกระทั่งคุณตีชายแดนแล้วลองแนวนอนก่อน . แล้วอาจจะลองเพียงสี่เหลี่ยม (การเจริญเติบโตในแนวทแยงมุม) แต่ไม่แน่ใจว่าถ้าเพียงแค่เลือกที่ใหญ่ที่สุดของด้านบน 3 ความเป็นไปได้เป็นวิธีการที่เหมาะสม..
xaxxon

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

คำตอบ:


15

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

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

ตัวอย่างการแปลงรูปสี่เหลี่ยมผืนผ้าเป็นเซลล์กริดและย้อนกลับ

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

อย่างมีประสิทธิภาพเราต้องการหาวิธีที่จะแยก polyomino นี้ออกเป็นรูปสี่เหลี่ยมผืนผ้า (น่าเสียดายที่วรรณกรรมส่วนใหญ่ที่ฉันสามารถหาพบได้คือเกี่ยวกับปัญหาตรงข้าม: การตัดรูปสี่เหลี่ยมลงในรูปหลายเหลี่ยม!

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

การสลายโพลีโอมิโนลงในการวิ่งในแนวนอนจากนั้นทำการรวมในแนวตั้ง

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

ตัวอย่างของเคสที่มีโซลูชัน 3 สี่เหลี่ยมผืนผ้าซึ่งวิธีการด้านบนค้นหา 4

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

ฉันได้ดูวิธีการที่เราเดินไปรอบ ๆ โพลีโอมิโนและตัดผ่านทุกครั้งที่เราพบมุมเว้า แต่วิธีนี้ดูผิดพลาดได้ง่ายกว่าสำหรับฉัน การได้ผลลัพธ์ที่ดีที่สุดนั้นต้องการการจัดลำดับความสำคัญการตัดที่รวมมุมเว้าสองมุมและรูปร่างที่มีโพรงต้องมีการจัดการเป็นพิเศษดังนั้นวิธีการสแกนแถวจะมีความได้เปรียบที่เรียบง่าย

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

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


ขอบคุณสำหรับคำตอบที่ยอดเยี่ยม! วิธีแก้ปัญหานั้นดูเร็วพอที่ฉันจะวิ่งไปตามทิศทางที่ต่างกันและเลือกอันที่ดีที่สุด - ซ้าย -> - ขวา, แนวนอน -> - ซ้ายและจากนั้นก็ตั้งฉากกัน
xaxxon

2
ปัญหาคือเราสามารถสร้างรูปร่างที่จะทำให้เข้าใจผิดอัลกอริทึมจากทุกทิศทางการกวาด สิ่งเหล่านั้นอาจไม่ปรากฏในการใช้งานจริง แต่ก็ยังบั๊กฉัน ฉันคิดว่ามันมีวิธีแก้ไขที่ง่าย ๆ ... สิ่งที่ชอบสังเกตในการวิ่งแต่ละครั้งไม่ว่าจะมีมุมมุมเว้าเหนือกลาง จากนั้นหากการวิ่งครั้งต่อไปสิ้นสุดลง ณ จุดนั้นเราจะย้อนกลับไปตามการวิ่งข้างต้นโดยแยกพวกมันออกในแนวตั้ง ฉันยังไม่ได้แยกรายละเอียดแบบเต็มแม้ว่า
DMGregory

1
นอกจากนี้ฉันไม่แน่ใจว่าทำไมขั้นตอนการเติมน้ำท่วมเป็นสิ่งจำเป็น เมื่อไปจากตำแหน่งโพสิทีโนไปยังสี่เหลี่ยมผอมยาวคุณสามารถเดินแถวเต็มหรือคอลัมน์ของตาราง (ไม่ว่าคุณจะไปทางไหน) เพื่อสร้างสี่เหลี่ยม 1xN เหล่านั้น ไม่จำเป็นต้องรู้โพลีโนใช่ไหม?
xaxxon

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