บรรจุรูปหลายเหลี่ยมภายในรูปหลายเหลี่ยมโดยใช้ ArcGIS Desktop หรือไม่


25

ฉันมีแรนด์บูลีน

ในพื้นที่สีเทาของแรสเตอร์ฉันต้องการให้พอดีกับรูปหลายเหลี่ยมขนาดที่กำหนดภายในขอบเขตที่ต่อเนื่องกัน

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

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

ฉันใช้ ArcGIS Desktop 10


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

1
@whuber ขอบคุณสำหรับการแก้ไขโพสต์ของฉัน ใช่จำนวนครั้งที่เพียงพอจะทำงาน หรือวิธีการเกี่ยวกับการวางแนวมุมที่กำหนด อดีต ในภาพด้านบนฉันมีรูปหลายเหลี่ยมพอดีหลาย ๆ ครั้งที่ฉันสามารถหาได้ในทิศทางนั้นถ้าฉันหมุนพวกเขา 90 องศาคุณจะได้อีกหนึ่งรูปแบบ ...
Thad

1
ใช่ แต่มันก็เต็มไปด้วยข้อผิดพลาด บางคนเป็นระดับประถม ตัวอย่างเช่นข้อความที่เขียนโดย ESRI และ - เผยแพร่ "ทำความรู้จักกับ ArcView GIS" (สำหรับรุ่น 3) รวมถึงการออกกำลังกายที่สี่เหลี่ยมผืนผ้าซึ่งเป็นตัวแทนของสนามฟุตบอลถูกวางไว้ภายในรูปหลายเหลี่ยม ปัญหาคือคำตอบของแบบฝึกหัดผิดเพราะผู้เขียนไม่สามารถคาดการณ์ข้อมูลและข้อผิดพลาดในการใช้พิกัดทางภูมิศาสตร์มีขนาดใหญ่พอที่จะส่งผลกระทบต่อผลลัพธ์ คำตอบนั้นดูดีใน GIS แต่ถ้ามีใครพยายามสร้างฟิลด์นั้นพวกเขาจะพบว่ามีที่ว่างไม่เพียงพอสำหรับมัน :-)
whuber

6
@ โฮเบอร์ฉันคิดว่าพวกเขาคิดว่า "ball ball" นั้นเพียงพอแล้ว
Kirk Kuykendall

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

คำตอบ:


22

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

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

ข้อ จำกัด ของปัญหานี้ก็คือว่าไม่มีสองไทล์ภายในโซลูชันอาจทับซ้อนกัน

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

หนึ่งในสิ่งที่เป็นนามธรรมเล็ก ๆ น้อย ๆ : ชุดของตำแหน่งกระเบื้องที่เป็นไปได้ของตัวเองสามารถแจกแจงพูด 1, 2, ... , N การเลือกชุดตำแหน่งใด ๆ ของกระเบื้องนั้นสอดคล้องกับเวกเตอร์ตัวบ่งชี้ที่ตำแหน่งนั้นจะกำหนดให้วางแผ่น

นี่คือตัวอย่างเล็ก ๆ ในการแก้ไขปัญหาความคิด มันมาพร้อมกับรหัสMathematica ที่ใช้ในการคำนวณเพื่อให้ปัญหาการเขียนโปรแกรม (หรือขาดมัน) สามารถเห็นได้

อันดับแรกเราแสดงพื้นที่ที่จะปูกระเบื้อง:

region =  {{0, 0, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}};

รูปที่ 1: ภูมิภาค

ถ้าเรานับจำนวนเซลล์จากซ้ายไปขวาเริ่มต้นที่ด้านบนเวกเตอร์ตัวบ่งชี้สำหรับภูมิภาคมี 16 รายการ:

Flatten[region]

{0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}

ลองใช้ไทล์ต่อไปนี้พร้อมกับการหมุนทั้งหมดด้วยทวีคูณ 90 องศา:

tileSet = {{{1, 1}, {1, 0}}};

รูปที่ 2: กระเบื้อง

รหัสเพื่อสร้างการหมุน (และการสะท้อน):

apply[s_List, alpha] := Reverse /@ s;
apply[s_List, beta] := Transpose[s];
apply[s_List, g_List] := Fold[apply, s, g];
group = FoldList[Append, {}, Riffle[ConstantArray[alpha, 4], beta]];
tiles = Union[Flatten[Outer[apply[#1, #2] &, tileSet, group, 1], 1]];

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

สมมติว่าเราต้องวางกระเบื้องดังที่แสดงไว้ที่นี่:

รูปที่ 3: การจัดวางไทล์

เซลล์ 3, 6 และ 7 ครอบคลุมอยู่ในตำแหน่งนี้ ที่ถูกกำหนดโดยตัวบ่งชี้เวกเตอร์

{0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}

ถ้าเราเลื่อนไทล์นี้หนึ่งคอลัมน์ไปทางขวาเวกเตอร์ตัวบ่งชี้นั้นจะเป็นแทน

{0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}

การรวมกันของความพยายามที่จะวางกระเบื้องที่ตำแหน่งทั้งสองเหล่านี้พร้อมกันจะถูกกำหนดโดยผลรวมของตัวบ่งชี้เหล่านี้

{0, 0, 1, 1, 0, 1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}

2 ในตำแหน่งที่เจ็ดแสดงการเหลื่อมกันเหล่านี้ในเซลล์เดียว (แถวที่สองลงมาคอลัมน์ที่สามจากด้านซ้าย) เนื่องจากเราไม่ต้องการเหลื่อมกันเราจึงต้องการให้ผลรวมของเวกเตอร์ในโซลูชันที่ถูกต้องใด ๆ ต้องไม่มีรายการเกิน 1

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

makeAllTiles[tile_, {n_Integer, m_Integer}] := 
  With[{ m0 = Length[tile], n0 = Length[First[tile]]},
   Flatten[
    Table[ArrayPad[tile, {{i, m - m0 - i}, {j, n - n0 - j}}],  {i, 0, m - m0}, {j, 0, n - n0}], 1]];
allTiles = Flatten[ParallelMap[makeAllTiles[#, ImageDimensions[regionImage]] & , tiles], 1];
allTiles = Parallelize[
   Select[allTiles, (regionVector . Flatten[#]) >= (Plus @@ (Flatten[#])) &]];
options = Transpose[Flatten /@ allTiles];

รูปที่ 4: อาร์เรย์ตัวเลือก

(เวกเตอร์ตัวบ่งชี้ที่สองก่อนหน้านี้ปรากฏเป็นสองคอลัมน์แรกทางด้านซ้าย) เครื่องอ่านแบบตาเดียวอาจสังเกตเห็นโอกาสหลายอย่างสำหรับการประมวลผลแบบขนาน: การคำนวณเหล่านี้อาจใช้เวลาสองสามวินาที

ทั้งหมดที่กล่าวมาสามารถปรับปรุงใหม่ได้อย่างกะทัดรัดโดยใช้สัญกรณ์เมทริกซ์:

  • Fคืออาร์เรย์ของตัวเลือกนี้ด้วยแถวMและคอลัมน์N

  • Xเป็นตัวบ่งชี้ของชุดของตำแหน่งกระเบื้องที่มีความยาวN

  • bคือN -vector ของอันใดอันหนึ่ง

  • Rคือตัวบ่งชี้สำหรับภูมิภาค มันเป็นM -vector

"ความดี" ทั้งหมดที่เกี่ยวข้องกับโซลูชันXใด ๆ ที่เป็นไปได้เท่ากับRFXเนื่องจากFXเป็นตัวบ่งชี้ของเซลล์ที่ครอบคลุมโดยXและผลิตภัณฑ์ที่มีR จะรวมค่าเหล่านี้ (เราสามารถให้น้ำหนักR ได้หากเราต้องการวิธีแก้ปัญหาเพื่อช่วยเหลือหรือหลีกเลี่ยงบางพื้นที่ในภูมิภาค) นี่คือการขยายให้ใหญ่สุด เพราะเราสามารถเขียนมันเป็น ( RF ) Xมันเป็นฟังก์ชันเชิงเส้นของX : นี่คือสิ่งสำคัญ (ในรหัสด้านล่างตัวแปรcมีRF )

ข้อ จำกัด อยู่ที่ว่า

  1. องค์ประกอบทั้งหมดของXต้องไม่เป็นลบ

  2. องค์ประกอบทั้งหมดของXจะต้องน้อยกว่า 1 (ซึ่งเป็นรายการที่สอดคล้องกันในb );

  3. องค์ประกอบทั้งหมดของXจะต้องเป็นส่วนประกอบสำคัญ

ข้อ จำกัด (1) และ (2) ทำให้โปรแกรมเชิงเส้นตรงในขณะที่ข้อกำหนดที่สามเปลี่ยนเป็นโปรแกรมเชิงเส้นจำนวนเต็ม

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


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

b = ConstantArray[-1, Length[options]];
c = -Flatten[region].options;
lu = ConstantArray[{0, 1}, Length[First[options]]];
x = LinearProgramming[c, -options, b, lu, Integers, Tolerance -> 0.05];
If[! ListQ[x] || Max[options.x] > 1, x = {}];
solution = allTiles[[Select[x Range[Length[x]], # > 0 &]]];

รูปที่ 5: ทางออก

เซลล์สีเทาไม่ได้อยู่ในพื้นที่เลย สารละลายนี้ไม่ได้ครอบคลุมเซลล์สีขาว

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

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

รูปที่ 6: ภูมิภาค

ภูมิภาคประกอบด้วยเซลล์ 2156 ของตารางนี้

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

รูปที่ 7: กระเบื้อง

หนึ่งคือ 17 โดย 9 (153 เซลล์) และอีกอันคือ 15 โดย 11 (165 เซลล์) เราอาจชอบที่จะใช้อันที่สองเพราะมันมีขนาดใหญ่กว่า แต่อันแรกนั้นน่าจะเหมาะกว่าและน่าอยู่กว่า มาดูกัน!

ตอนนี้โปรแกรมเกี่ยวข้องกับตำแหน่งที่เป็นไปได้ของN = 5589 มันค่อนข้างใหญ่! หลังจากการคำนวณ 6.3 วินาทีMathematicaก็เกิดปัญหากับกระเบื้องสิบแผ่นนี้:

รูปที่ 8: วิธีแก้ปัญหา

เนื่องจากความหย่อนบาง ( .egเราสามารถเลื่อนไทล์ซ้ายล่างสูงสุดสี่คอลัมน์ไปทางซ้าย) จึงมีวิธีแก้ปัญหาอื่นที่แตกต่างจากอันนี้เล็กน้อย


1
รุ่นก่อนหน้าของการแก้ปัญหานี้ ( แต่ไม่ได้ค่อนข้างดี) จะปรากฏขึ้นบนMathematicaเว็บไซต์ที่mathematica.stackexchange.com/a/6888 มันอาจจะคุ้มค่าที่สังเกตเช่นกันว่าการเปลี่ยนแปลงเล็กน้อยของสูตรสามารถใช้ในการแก้ปัญหาของการปิดพื้นที่ทั้งหมดที่มีแผ่นกระเบื้องน้อยที่สุดเท่าที่จะเป็นไปได้ ปัญหา.
whuber

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

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

ว้าว! ฉันสนใจปัญหาที่คล้ายกันและโพสต์นี้ให้มุมมองใหม่ ขอขอบคุณ. จะเกิดอะไรขึ้นถ้า R ใหญ่กว่า (เช่น140x140≈20000) มีวิธีใดในการลดต้นทุนการคำนวณ คุณรู้เอกสารใด ๆ ที่เกี่ยวข้องกับปัญหานี้หรือไม่? คำค้นหาของฉันไม่นำฉันไปสู่ทางที่ถูกต้อง (จนถึงตอนนี้)
nimcap

@nimcap นี่เป็นปัญหาที่สำคัญมากการวิจัยหลายอย่างดำเนินต่อไป คำหลักที่จะค้นหาจะเริ่มต้นด้วย "โปรแกรมเชิงเส้นจำนวนเต็มแบบผสม" และแยกสาขาออกจากที่นั่นตามสิ่งที่คุณค้นหา
whuber

5

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


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

2

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

สมมติว่าเป็นสี่เหลี่ยมจัตุรัสที่มีด้านยาว L

สร้างรูปแบบตารางหมากรุกที่มีขนาดอย่างน้อยที่สุดเท่ากับขอบเขตของคอนเทนเนอร์และอย่างน้อย 1 ลิตรในแต่ละทิศทาง

N = 0

DX = 0

DY = 0

DR = 0

รีเซ็ตตำแหน่งกระดานหมากรุกเป็น centroid ดั้งเดิม

สำหรับ (R = 1: 100)

สำหรับ (Y = 1: 100)

สำหรับ (X = 1: 100)

M = นับจำนวนของช่องสี่เหลี่ยมทั้งหมดในตู้คอนเทนเนอร์

ถ้า (M> N)

DR = R

DY = Y

DX = X

N = M

ย้ายกระดานหมากรุกไปทางตะวันออกด้วย L / 100

รีเซ็ตกระดานหมากรุกตะวันออก

ย้ายกระดานหมากรุกไปทางเหนือด้วย L / 100

รีเซ็ตกระดานหมากรุกทิศเหนือ

หมุนกระดานหมากรุกประมาณ 3.6 องศา CW รอบ ๆ เซนทรอยด์

DY = DY * L

DX = DX * L

รีเซ็ตกระดานหมากรุกเป็นตำแหน่งและการหมุนแบบเดิม

พิมพ์ DR & "," & DX & "และ" & DY & "เป็นเมทริกซ์การแปล / การหมุนขั้นสุดท้าย"

หมุนกระดานหมากรุกโดย DR

แปลกระดานหมากรุกโดย DX, DY

เลือกสี่เหลี่ยมที่อยู่ในภาชนะอย่างสมบูรณ์

ส่งออกสี่เหลี่ยม


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

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