ค้นหาแบบที่ใกล้ที่สุดที่ดีที่สุดสำหรับวงกลม


12

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

ประสิทธิภาพสำหรับฉันไม่ใช่สิ่งสำคัญสำหรับแอปพลิเคชันนี้

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


1
วงกลมสีดำมีความสำคัญอะไร? คุณสามารถวางวงกลมสีน้ำเงินเหนือมันได้ไหม?
Ewan

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

3
เกี่ยวข้อง: Circle Packing
Robert Harvey

2
วงกลมทั้งหมดจะสัมผัสกับวงกลมอื่น ๆ ในสถานที่อย่างน้อยหนึ่งแห่งเสมอหรือไม่
Robert Harvey

3
ที่เกี่ยวข้อง: stackoverflow.com/questions/10666116และstackoverflow.com/questions/5509151 อาจมีความเกี่ยวข้อง: stackoverflow.com/a/19375601
Robert Harvey

คำตอบ:


4

นี่ไม่ใช่วิธีการแก้ปัญหาทั่วไปเนื่องจากมีหลายสถานการณ์เพราะจะไม่ให้ตำแหน่งของวงกลมสีน้ำเงินที่มีระยะทางสั้นที่สุดไปยังจุดสีขาว ตัวอย่างเช่นหากคุณมีลูกบอลสีแดง 100 กลุ่มรวมกันและจุดสีขาวอยู่ไกลจากกลุ่มลูกบอลสีแดงกลุ่มนี้ไม่มีลูกบอลสีแดงใด ๆ ที่จะมีอิทธิพลใด ๆ ในตำแหน่งของวงกลมสีน้ำเงินที่สามารถอยู่กึ่งกลางจุดสีขาว . มันจะไม่แสดงรายละเอียดการคำนวณทั้งหมด อย่างไรก็ตามสำหรับเซตย่อยของการกำหนดค่าที่การแก้ปัญหา (วงกลมสีฟ้า) แทนเจนต์กับวงกลมสีแดงสองวงดังต่อไปนี้ควรใช้งานได้:
1) ให้ R เป็นรัศมีของวงกลมสีน้ำเงิน
2) ทำการวนรอบวงกลมสีแดงทุกคู่ใช่ ฉันรู้ว่านี่คือ O (n2)
3) สำหรับวงกลมแต่ละคู่ i, j มีจุดศูนย์กลางที่ (xi, yi) และ (xj, yj) ด้วยรัศมี ri และ rj ตามลำดับคำนวณระยะห่างระหว่างคู่ของวงกลม

d_ij^2=(xi-xj)^2+(yi-yj)^2  

4) ใส่วงกลมทุกคู่ที่

dij^2<R^2

ลงในรายการ

5) สำรวจรายการโดยหาวิธีแก้ปัญหา 2 วงของรัศมี R แทนเจนต์ทั้งวงกลม i และ j เมื่อต้องการทำสิ่งนี้ให้ใช้สมการเหล่านี้พร้อมกับภาพนี้ วงกลมสีน้ำเงินสองวงสำหรับคู่ของวงกลมสีแดง

a = R+ri  
b = R+rj  
c = dij  
α = arccos((b^2+c^2-a^2)/(2bc)  

ด้วยข้อมูลข้างต้นคุณสามารถค้นหา (X1ij, Y1ij) และ (X2ij, Y2ij) ศูนย์กลางของวงกลม 2 วงสัมผัสกับวงกลม i และ j สำหรับผู้สมัครแต่ละคนจะวนซ้ำวงกลมสีน้ำเงินมากกว่าวงกลมสีแดงอื่น ๆ ทั้งหมดและดูว่าจะไม่ทับซ้อนกันหรือไม่ หากพวกเขาแยกมันถ้าไม่ตรวจสอบระยะทางวงกลมสีขาว ถ้าคุณรักษาระยะห่างให้เล็กลงฉันคิดว่าคุณจะมีทางออกเมื่อคุณสำรวจรายการวงกลมเป็นคู่ อัลกอริทึมดูเหมือนว่า O (n3)


ไม่ทำงานเมื่อมีวงกลมเพียงวงเดียว
Ewan

หรือวงกลมสองวง แต่มีจุดเป้าหมายอยู่ด้านนอกทั้งสอง
Ewan

ปัญหาคือคุณไม่สามารถแน่ใจได้ว่าคุณได้รับคดีทั้งหมด
Ewan

ด้วย มีวิธีแก้ปัญหาเฉพาะสำหรับกรณีเหล่านั้น
Ewan

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

2

ตำแหน่งที่อยู่ใกล้จุดมากที่สุดจะอยู่ในจุดนั้นหรือแตะเป็นวงกลม

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

กล่าวคือ ตรวจสอบทุกจุดบนเส้นสีเขียวรวมทั้งวงกลมสีขาว โดยที่เส้นสีเขียวคือวงกลมที่มีรัศมีของสีแดงบวกกับสีน้ำเงิน

จุดศูนย์กลางที่เป็นไปได้

คุณต้องตรวจสอบเส้นสีเขียวทั้งหมดไม่ใช่แค่ทางแยกเพื่อให้ครอบคลุมกรณีขอบเหล่านี้

กรณีวงกลมเดียว

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

คำชี้แจง:

ข้อเสนอแนะของฉันคือการเดรัจฉานบังคับให้คะแนนทุกรอบการทดสอบวงกลมแต่ละวงซ้อนทับกับวงกลมอื่น ๆในแต่ละจุด ไม่มีความฉลาด

หากรูปภาพตัวอย่างนั้นบ่งบอกถึงจำนวนวงกลมและความละเอียดมันก็ไม่น่าจะเป็นปัญหาสำหรับพีซีมาตรฐาน

เรามีรัศมีเฉลี่ย 20 วงกลม 200 ค่านั่นคือประมาณ 20 * 2 π * 200 คะแนน * 20 การทดสอบทางแยก = 4800000 ซ้ำ

บันทึก:

วิธีการวนซ้ำเช่นนี้มีข้อบกพร่องในขนาดขั้นตอนของคุณซึ่งในกรณีนี้ความละเอียดของเอาต์พุตของคุณอาจส่งผลกระทบอย่างมากต่อผลลัพธ์

สมมติว่าฉันมีวงกลมสีแดงสองวงแยกออกจากกัน 2 พิกเซลและวงกลมสีน้ำเงินรัศมี 1 พิกเซลเพื่อบีบระหว่างทั้งสอง ชัดเจนด้วยสองพิกเซลใดจุดหนึ่งในศูนย์กลางของวงกลมสีน้ำเงินมันจะซ้อนทับหนึ่งในสีแดง แต่เห็นได้ชัดว่ามีที่ว่างสำหรับวงกลมหากจุดศูนย์กลางอยู่ระหว่างพิกเซลทั้งสอง

ดังนั้นความคิดเห็นของฉันถามเกี่ยวกับความละเอียดของผลลัพธ์ ซึ่งคุณบอกว่าอาจเป็นอะไรก็ได้

คุณยังสามารถแก้สมการพร้อมกันสำหรับวงกลมแต่ละคู่ด้วยรัศมีที่เพิ่มขึ้นตามรัศมีของวงกลมสีน้ำเงิน

สิ่งนี้จะช่วยให้คุณทราบจุดที่วงกลมสีน้ำเงินจะสัมผัสทั้งสองวงกลมสีแดงแม่นยำกว่าการวนซ้ำ

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

1 หรือไม่มีแวดวง

วงกลม 2 วงขึ้นไป แต่มีจุดเป้าหมายอยู่ไกลและอยู่นอกวงกลม

วงกลมหลายวง แต่มีจุดเป้าหมายอยู่ใกล้กับพื้นผิว


2
การที่เขาต้องม้วนขอบของวงกลมสีน้ำเงินรอบ ๆ ด้านนอกของวงกลมอื่นเป็นส่วนที่ง่ายในการหา ส่วนที่ยากคือการหาสมการ / การคำนวณที่จะทำ
Robert Harvey

1
จริงๆ? มันแค่ (x-x1) ^ 2 + (y-y1) ^ 2 = (r + r1) ^ 2
Ewan

2
จากนั้นคุณต้องทำทั้งหมดอีกครั้งเมื่อคุณลองทำสิ่งต่อไป ฉันรู้ว่า OP กล่าวว่าการแสดงนั้นไม่ได้เป็นปัญหา แต่มันต้องทำให้เสร็จก่อนที่ความร้อนจากเอกภพจะตาย
Robert Harvey

2
วิธีเดียวที่จะรู้ว่าคุณจะได้รับ upvotes สิบหรือไม่ก็คือโพสต์รหัส C # ของคุณและดูว่าเกิดอะไรขึ้น
Robert Harvey

2
สิ่งที่ฉันคิดว่าจะเกิดขึ้นคือ OP จะเขียนโค้ดนี้ขึ้นมาเป็นคำตอบการบ้านของเขาและเราจะไม่ได้ยินจากเขาอีกเลย
4463 Ewan

1

เสียงดังปังนี้มีรหัสการทำงาน

แนวคิด

วงที่ให้ไว้คือ C1, C2 .... Cn

และพิกัดของวงกลม Cn คือ Cnx, Cny และ radius คือ Cr

และรัศมีของวงกลมที่ต้องการคือ R

หากวงกลมสีน้ำเงินอยู่ในตำแหน่ง X, Y และหากไม่ขัดแย้งกับวงกลมอื่น ๆ สมการต่อไปนี้จะเป็นจริง

(C1x - X)^2 + (C1y - Y)^2 > (C1r + R)^2
(C2x - X)^2 + (C2y - Y)^2 > (C2r + R)^2
....
(Cnx - X)^2 + (Cny - Y)^2 > (Cnr + R)^2

เปลี่ยนสมการแรก

C1x^2 - 2C1x*X + X^2 + C1y^2 - 2C1y*Y + Y^2 > C1r^2 + 2C1r*R + R^2
X^2 + Y^2 - 2C1x*X - 2C1y*Y > C1r^2 + 2C1r*R + R^2 - C1x^2 - C1y^2

ดังนั้นสมการจึงสามารถเขียนใหม่เป็น

X^2 + Y^2 - 2C1x*X - 2C1y*Y > C1r^2 + 2C1r*R + R^2 - C1x^2 - C1y^2
X^2 + Y^2 - 2C2x*X - 2C2y*Y > C2r^2 + 2C2r*R + R^2 - C2x^2 - C2y^2
....
X^2 + Y^2 - 2Cnx*X - 2Cny*Y > Cnr^2 + 2Cnr*R + R^2 - Cnx^2 - Cny^2

การดำเนินงาน

เริ่มจากพิกัดของจุดสีขาว (Xw, Yw)

    var isValidLocation = function(x,y,r){
       var valid = true;
       for (var i = 0; i< circles.length; i++){
          var circle = circles[i];
          valid = valid && ((x*x + y*y - 2*circle.x*x - 2*circle.y*y) > (circle.radius*circle.radius + 2*circle.radius*r + r*r - circle.x*circle.x - circle.y*circle.y));
       }
       return valid;
      };

      var find = function(Xw,Yw,Rw){
        var radius = 0;
        while(true){
          for (var x=-1 * radius ;x <= radius; x++) {
            for (var y=-1 * radius;y <= radius; y++) {
               if (isValidLocation(Xw + x,Yw + y, Rw)){
                 drawCircle(Xw + x,Yw + y,Rw,"#0000FF");
                 return;
               }
            }   
          } 
          radius++;
        }
     }; 

พิกัดแรกที่พบเพื่อตอบสนองสมการทั้งหมดคือตำแหน่งของวงกลมสีน้ำเงิน


ใครช่วยอธิบายสิ่งที่ผิดกับวิธีนี้ได้บ้าง?
นกกระทุงบินต่ำ

มันอ่านยาก ใช้ชื่อและ abstractions ที่ดี มันจะฆ่าคุณเพื่อเพิ่มไดอะแกรมหรือไม่?
candied_orange

เท่าที่ฉันเห็นวิธีการนี้พยายามค้นหาเฉพาะตำแหน่งที่ถูกต้องสำหรับวงกลมสีน้ำเงิน แต่ไม่ใช่ตำแหน่งที่ใกล้ที่สุด สิ่งนี้สามารถแก้ไขได้อย่างไรก็ตามวิธีการนี้ยังทำให้สมมติฐาน (ส่วนใหญ่อาจไม่ถูกต้อง) มีเพียงจำนวนเต็มของค่าจำนวนเต็มพิกัด
Doc Brown

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

1
... สำหรับโซลูชันที่ถูกต้องในพิกัดจำนวนเต็มคุณต้องใช้รัศมีที่เพิ่มขึ้นและทำให้พื้นที่การค้นหาของคุณเป็นวงกลมของรัศมีนี้รอบ ๆ จุดสีขาว และถึงแม้ว่า OP จะไม่ได้มีประสิทธิภาพ แต่ก็เป็นความคิดที่ดีที่จะไม่ทดสอบคู่พิกัดที่ทดสอบแล้วในทุก ๆ วงซ้ำแล้วซ้ำอีก
Doc Brown

0
  • Oเป็นจุดที่คุณกำลังพยายามที่จะใกล้เคียงกับ
  • Pคือจุดที่คุณกำลังมองหา (ศูนย์กลางของวงกลมสีน้ำเงิน)
  • rคือรัศมีของวงกลมสีน้ำเงิน
  • C0 ..เป็นศูนย์กลางของวงกลมทั้งหมดที่ จำกัด ตำแหน่งของสีน้ำเงินไว้
  • วงกลมขยายเป็นหนึ่งในวงกลมที่มีรัศมีขยายโดยr

    มีงานพิเศษบางอย่างถ้าOไม่ได้อยู่ที่ศูนย์กลางวงกลม ดังนั้นตอนนี้สมมติ O == C0

คำนวณจุดตัดทั้งหมดของวงกลมทั้งหมดด้วย C0 โดยใช้รัศมีของพวกเขาบวกกับr , Ie ตัดวงกลมขยายด้วย C0 ที่ขยาย หากไม่มีจุดตัดจุดที่คุณมองหาอยู่ที่ใดก็ได้ใน C0 หากมีจุดตัดสำหรับแต่ละจุดตรวจสอบว่าอยู่ในวงกลมขยายอีกวงหนึ่งหรือไม่ (คุณสามารถ จำกัด ตัวเองเป็นวงกลมที่มีจุดตัดด้วย C0) ใช้จุดตัดแรกที่ไม่อยู่ในวงกลมขยายอีกอันหนึ่งเป็น P อาจมีคนอื่น ๆ

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

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

นี่คือ O (n ^ 2) มีบางวิธีที่จะปรับปรุงสิ่งนี้แม้ว่ากริดสามารถใช้เพื่อลดความพยายามในการค้นหาคู่ที่ชาญฉลาดและฉันคิดว่าการเรียงลำดับวงกลมโดยความใกล้ชิดกับ O (ระยะห่างระหว่าง วงกลมสองวงถูกลดโดยวิทยุ) จะช่วย จำกัด พื้นที่การค้นหาสำหรับการครอบคลุมและการค้นหาสี่แยก


0

ค้นหาแนวทางแก้ไขที่เป็นไปได้

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

การค้นหาโซลูชันที่แท้จริงระหว่างโซลูชันที่เป็นไปได้

ตอนนี้คุณมีชุดของจุดที่เป็นวิธีแก้ปัญหาที่เป็นไปได้วนซ้ำพวกเขาและตรวจสอบแต่ละจุด

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

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

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