เติมรูปหลายเหลี่ยมเป็นเส้นตรงด้วยสี่เหลี่ยม [ซ้ำกัน]

เมื่อกำหนดรูปหลายเหลี่ยมซึ่งสร้างขึ้นจากสี่เหลี่ยมทั้งหมด และกำหนดโดยอาร์เรย์ของจุด โดยที่ขอบจะอยู่ในแนวเดียวกับแกนเสมอ:

รูปหลายเหลี่ยมที่สร้างขึ้นทั้งหมดจากสี่เหลี่ยมที่ตัดกัน

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

แก้ไข: ต่อไปนี้เป็นโค้ด การประมวลผล ง่ายๆ เพื่อสร้างรูปร่างนี้ (ก็ใกล้เคียงกัน)

float[] xpts = {0,    50,  50,  100, 100, 150, 150, 250, 250, 300, 300, 325, 325, 300, 300, 250, 250, 210, 210, 250, 250, 125, 125, 25, 25,   50,  50,  0 };
float[] ypts = {100, 100,  80,   80, 10,   10,  80, 80,  75,  75, 80,   80,  200, 200, 300, 300, 275, 275, 260, 260, 200, 200, 270, 270, 165, 165, 125, 125};


void setup( )
{
  size( 350, 350 );
}

void draw( )
{

stroke( 0 );
strokeWeight( 1.5 );

float px = xpts[0];
float py = ypts[0];
for (int i=1; i < xpts.length; i++)
{
  float nx = xpts[i];
  float ny = ypts[i];
  line( px, py, nx, ny );


  px = xpts[i];
  py = ypts[i];
}
float nx = xpts[0];
float ny = ypts[0];

line( px, py, nx, ny );
}

person jedierikb    schedule 03.05.2011    source แหล่งที่มา
comment
ขอบอยู่ในแนวแกนเสมอหรือไม่? คุณสามารถใช้เส้นสแกนเพื่อค้นหาพื้นที่ที่ใหญ่ที่สุดได้อย่างง่ายดายหากเป็นเช่นนั้น   -  person Flexo    schedule 04.05.2011
comment
ใช่ ขอบจะอยู่ในแนวแกนเสมอ (ฉันจะอัปเดตโพสต์) คุณช่วยให้รายละเอียดเพิ่มเติมเกี่ยวกับวิธีการสแกนไลน์ได้ไหม ขอบคุณ.   -  person jedierikb    schedule 04.05.2011
comment
@finnw - ฉันคิดว่านี่แตกต่างจากคำถามนั้นเพียงพอ - ที่นี่อินพุตคือรายการขอบ   -  person Flexo    schedule 04.05.2011


คำตอบ (2)


สร้าง KD-Tree โดยใช้ขอบที่มีอยู่เป็นระนาบตัวแยก และละเว้นขอบเขตที่อยู่นอกรูปหลายเหลี่ยมโดยสิ้นเชิงในระหว่างการเรียกซ้ำ โหนดใบจะประกอบกันเป็นการสลายตัวเป็นรูปสี่เหลี่ยมผืนผ้า

การได้รับการสลายตัวที่ดีเป็นเพียงเรื่องของตัวแยกที่จะเลือกในแต่ละขั้นตอนของการเรียกซ้ำ คุณอาจต้องการใช้การศึกษาพฤติกรรมแบบง่ายๆ ที่ลดพื้นที่ที่เหลือลงครึ่งหนึ่งในแต่ละขั้นตอน หากคุณต้องการ คุณสามารถลองใช้ตัวแยกสัญญาณที่แตกต่างกันสองสามตัวได้!

นี่คือรหัสเทียมบางส่วน:

function makeRects(Rect r, Polygon p)

  if p is empty
    if r is inside your original polygon
      add r to results

  else
    choose good splitter s

    makeRects(left part of r relative to s, left part of p relative to s)
    makeRects(right part of r relative to s, right part of p relative to s)

ตัวแยกสำหรับการแบ่งแยกตัวอย่าง OPs

person ltjax    schedule 06.05.2011
comment
คุณช่วยยกตัวอย่างได้ไหม? ฉันไม่ชัดเจนนักว่าลูก ๆ ของแต่ละแยกถูกกำหนดอย่างไร - person Null Set; 06.05.2011
comment
เสร็จสิ้น - หวังว่าจะช่วยได้ ลูกของแต่ละการแยกเป็นเพียงสเปซย่อยที่เหลือ เช่น. สองซีกของระนาบการแยกตัดกับสเปซย่อยที่เกี่ยวข้องกับโหนดพาเรนต์ - person ltjax; 08.05.2011
comment
รหัสเทียมบางรหัส (อาจมีระดับที่สูงมาก) จะเป็นประโยชน์ในการทำความเข้าใจวิธีนำข้อเสนอแนะของคุณไปใช้ ขอบคุณมาก - person jedierikb; 20.05.2011
comment
เพิ่มรหัสหลอกตามที่คุณร้องขอ มันทำให้มีอิสระมาก.. ตัวอย่างเช่น คุณไม่จำเป็นต้องทดสอบอย่างชัดเจนว่า r อยู่ภายในรูปหลายเหลี่ยมดั้งเดิมหรือไม่เพื่อแยกการเรียกซ้ำ: โดยปกติแล้วคุณสามารถได้รับสิ่งนั้นจากระนาบตัวแยกที่สูงกว่าหนึ่งระดับ! - person ltjax; 20.05.2011
comment
ฉันเข้าใจแล้ว ขอบคุณ แต่ไม่ได้เป็นส่วนหนึ่งของ p เมื่อเทียบกับการดำเนินการที่ค่อนข้างแพงใช่หรือไม่ ฉันเข้าใจว่าค่า p จะถูกตัดน้อยลง แต่มันก็ยังมีการตรวจสอบจุดอีกมากใช่ไหม? - person jedierikb; 20.05.2011
comment
มันควรจะเป็นเส้นตรงหากคุณนำไปใช้อย่างไร้เดียงสา แต่ถึงอย่างนั้นมันก็ควรจะค่อนข้างรวดเร็ว ดังนั้นฉันก็ไม่ต้องกังวลกับมันมากเกินไป - person ltjax; 20.05.2011

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

person Mecki    schedule 04.05.2011
comment
เล็กที่สุดเปลี่ยนเป็นเล็ก ขอบคุณ! - person jedierikb; 06.05.2011
comment
คุณช่วยร่างข้อพิสูจน์ได้ไหมว่าทำไมถึงเป็น NP - person citykid; 19.06.2014
comment
@citykid ตอนนี้คำถามบอกว่าเล็กมันไม่ใช่ปัญหา NP อีกต่อไป แต่เดิมทีมันอ่านว่าเล็กที่สุด แสดงการทดสอบทางคณิตศาสตร์เพื่อยืนยันว่าโซลูชันมีขนาดเล็กที่สุดและทำงานในเวลาพหุนาม ฉันไม่รู้เลย ดังนั้นการตรวจสอบวิธีแก้ปัญหาที่เล็กที่สุดก็เป็นปัญหา NP อยู่แล้ว ดังนั้นการค้นหาวิธีแก้ปัญหาที่เล็กที่สุดก็คือ NP เช่นกัน คล้ายกับปัญหาของพนักงานขายที่กำลังเดินทางหรือปัญหาเรื่องกระเป๋าเป้สะพายหลัง การหาวิธีแก้ปัญหาที่ดีในเวลาอันสั้นเป็นไปได้ แต่การหาวิธีแก้ปัญหาที่สมบูรณ์แบบนั้นคือ NP - person Mecki; 20.06.2014
comment
ทำได้ดีมาก เห็นด้วย มันค่อนข้างเป็นกระเป๋าเป้สะพายหลัง - person citykid; 21.06.2014
comment
สวัสดี ขอบคุณสำหรับคำถามนี้ ฉันสร้างกราฟเรคติซและลดขนาดด้วยอัลกอริธึมฮอปคอร์กและคาร์ป คุณยังอาจลัดขั้นตอนนี้ได้โดยลากเส้นตัดเพื่อแปลงรูปหลายเหลี่ยม (orthogon) ให้เป็นชุดสี่เหลี่ยมผืนผ้าเท่านั้น ผลที่ได้คือคุณจะได้สี่เหลี่ยมมากกว่าจำนวนสี่เหลี่ยมที่น้อยที่สุด แต่ก็มักจะไม่ใช่ปัญหาใหญ่ ถ้าคุณปฏิบัติต่อออร์โธกอนขนาดเล็กหลายพันตัวในแอปแปลก ๆ ก็อาจเป็นได้ ปัญหาสำหรับฉันตอนนี้คือ เมื่อวาดสี่เหลี่ยมแล้ว ฉันไม่สามารถเติมสี่เหลี่ยมได้ ฉันพยายามทำความเข้าใจอัลกอริธึมที่เสนอ ตัวอย่างที่ไหนสักแห่ง? ขอบคุณ. - person Jean-Yves DANIEL; 06.04.2021