การค้นหารูปร่างใน 2D Array จากนั้นปรับให้เหมาะสม


11

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

พบรูปแบบที่ต้องการ แต่ยังไม่ได้ปรับให้เหมาะสม

รหัสของฉันวนซ้ำผ่าน x / y ทำเครื่องหมายบล็อกที่ใช้หมุนรูปร่างทำซ้ำเปลี่ยนสีทำซ้ำ

ฉันเริ่มพยายามแก้ไขการตรวจสอบนี้ด้วยความกังวลใจมาก แนวคิดปัจจุบันคือ:

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

รู้สึกอย่างนั้น ... ฉันจะทำยังไงดี?

ฉันคิดว่าฉันจะต้อง

  • ลองผสมผสานรูปร่างที่ขัดแย้งกันหลายแบบเริ่มต้นด้วยสิ่งกีดขวางรูปแบบส่วนใหญ่ก่อน ฉันจะเข้าใกล้คนนี้ได้อย่างไร
  • ใช้เหตุผลที่บอกว่าฉันมี 3 รูปร่างที่ขัดแย้งกันครอบครอง 8 บล็อกและรูปร่างเป็น 4 บล็อกต่อหนึ่งดังนั้นฉันจึงสามารถมีได้สูงสุดสองรูปร่าง

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

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

แก้ไขแม้จะมีความชัดเจนของคำถามทุกคนดูเหมือนจะเข้าใจใช่

ฉันต้องการค้นหารูปร่าง "T" สูงสุดภายในแต่ละสี

(เพราะถ้าฉันให้คะแนนสองและคุณได้สามคุณจะรำคาญเล็กน้อย)


อัลกอริทึมโลภ coudld คือการแบ่งบอร์ดออกเป็นกลุ่มของบล็อกที่เข้าร่วม จากนั้นสำหรับการสะสมแต่ละครั้งคุณสามารถลองเติมรูปร่างและเติมคะแนนขึ้นอยู่กับจำนวนบล็อกที่เหลือซึ่งจะไม่มืด ชนิดของการทำให้ฉันคิดว่าของen.wikipedia.org/wiki/Knapsack_problem
Jonathan Connell

2
ฉันคิดว่ามีบางอย่างขาดหายไปในคำถาม คุณต้องการสร้างอัลกอริทึมที่ค้นหากลุ่มรูป "T" ให้มากที่สุดหรือไม่?
Markus von Broady

ถ้าฉันเข้าใจคุณคุณก็กำลังมุ่งหน้าไปทางที่ถูกต้อง คุณไม่ชัดเจนและฉันจะรักถ้าคุณสามารถทำอย่างละเอียด
AturSams

คำตอบ:


3

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

หากฉันถูกต้องต่อไปนี้เป็นทางออกที่ดีที่สุดสำหรับสถานการณ์ของคุณในความคิดของฉัน

เราจะใช้การเขียนโปรแกรมเชิงเส้นจำนวนเต็ม

ฉันเชื่อว่าฉันเคยใช้สิ่งนี้ในอดีต:

http://sourceforge.net/projects/lpsolve/

http://lpsolve.sourceforge.net/5.5/Java/README.html

(คุณสามารถใช้งานได้กับหลายภาษาฉันใช้กับ PHP, Java และ C)

สิ่งที่เราจะทำคือลงทะเบียนรูปร่าง T ทุกอย่างที่เป็นไปได้บนกระดานแล้วใช้ ILP เพื่อเพิ่มจำนวนบล็อกที่ครอบคลุมมากที่สุด ILP นั้นซับซ้อนอย่างมาก พิจารณาขนาดของบอร์ดของคุณว่าจะไม่เป็นปัญหา ฉันใช้คำถามที่มีความซับซ้อนน้อยกว่า / สูงสุดในกราฟที่มี ILP และใช้เวลาเพียงเสี้ยววินาทีในการดำเนินการและถึง 30-90 วินาทีกับจุดยอดนับร้อย (ในกรณีของคุณมันอยู่ในเสี้ยววินาที)

สิ่งที่ฉันอยากจะแนะนำให้ทำ:

  1. ค้นหารูปร่าง Line ที่เป็นไปได้ทั้งหมด
  2. ค้นหาทางแยกทั้งหมดระหว่างรูปร่างเส้นที่มีสีเดียวกัน
  3. ค้นหารูปร่าง T ที่เป็นไปได้ทั้งหมดค้นหาจุดตัดทั้งหมด
  4. กำหนดตัวแปรบูลีนในปัญหาเชิงเส้นสำหรับแต่ละรูปร่าง T ( 0 <= Bi <= 1) เนื่องจากค่าเป็นจำนวนเต็มนั่นจะเหลือ 0 หรือ 1
  5. กำหนดเงื่อนไขสำหรับรูปร่างแต่ละคู่ของ T ที่ตัดกัน ( Bi + Bj <= 1)
  6. ฟังก์ชันวัตถุประสงค์จะเป็น (ผลรวมของบล็อกในรูปทรง "T" (i) * Bi)
  7. เรียกใช้ตัวแก้ไขและทำให้รูปร่าง T เข้มขึ้นซึ่งบูลีนที่สอดคล้องกันของตัวแก้ปัญหาโดยที่ 1 ในโซลูชันที่ดีที่สุด

นี่เป็นความรู้ที่มีค่าฉันใช้ตัวแก้ปัญหาเชิงเส้นบ่อยครั้งสำหรับโครงการทำงาน

ILP นั้นเป็นวิธีการแก้ปัญหาการเลือกที่คุณต้องการบรรลุสูงสุดหรือต่ำสุดสำหรับฟังก์ชั่นเชิงเส้นบางอย่าง

คุณสามารถอ่านเพิ่มเติมได้ที่นี่การใช้ Integer Linear Programming และ Linear Programming เหมือนกันสำหรับโปรแกรมเมอร์เท่านั้นที่ Integer นั้นซับซ้อนกว่าสำหรับคอมพิวเตอร์มากซึ่งอาจส่งผลให้ใช้เวลานาน ไม่ใช่ในกรณีของคุณมันง่ายมากและควรใช้เวลาน้อยกว่ามิลลิวินาทีในกรณีที่เลวร้ายที่สุด

ฉันเดาว่าคุณสามารถอ่านเพิ่มเติมได้ที่นี่:

http://en.wikipedia.org/wiki/Integer_linear_programming#Integer_unknowns

สิ่งนี้อธิบายได้ดี:

http://fisher.osu.edu/~croxton_4/tutorial/

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

ในทางคณิตศาสตร์, วิธีการตั้งค่าตัวแปร: ในกรณีปัจจุบันของเรา Booleans (ฉันทำให้รูปร่าง T มืดลงด้วยดัชนี i หรือไม่) เป็นค่าที่เหมาะสมที่สุดเพื่อให้ได้ผลลัพธ์สูงสุดที่เราต้องการ: ทำการบล็อกให้มากที่สุดเท่าที่จะเป็นไปได้ ตราบใดที่ผลลัพธ์ที่คุณต้องการสามารถคำนวณได้ด้วยฟังก์ชันเชิงเส้นเมื่อคุณมีตัวแปรทั้งหมดที่ตั้งค่าไว้มันจะแก้ปัญหาได้ ในกรณีของเราเราตรวจสอบว่า T รูปร่างใดที่เรามืดและรวมบล็อกที่ครอบคลุม

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

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


ขอบคุณ Arthur สำหรับความช่วยเหลือของคุณ อาจใช้เวลาสองสามอ่านย่อย และใช่คุณเข้าใจปัญหาอย่างถูกต้อง ฉันสนใจมากถ้าคุณจะทำอย่างละเอียด (ไม่ไม่มันไม่ใช่เรื่องไร้สาระ) แต่นี่จะช่วยให้ฉันไปถึงที่ที่ฉันจะไป!
Assembler

คุณใช้ภาษาใดในการติดตั้ง
AturSams

actionscript 3! ทุกคนชื่นชอบ!
Assembler

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

คุณมีพื้นที่เฉพาะ 1-7 ที่คุณต้องการให้ฉันเพิ่มความคิดเห็นหรือทำอย่างละเอียด? btw ข่าวดีสำหรับคนรัก AS3 ของเรา Adobe ปล่อย FlasCC ซึ่งรองรับ C ++ ดังนั้นเราจึงสามารถใช้ตัวแก้ปัญหาเชิงเส้นที่มีอยู่ได้อย่างง่ายดาย :)
AturSams

4

เมื่อคุณมีรายการของรูปร่าง T ทั้งหมด (อาจทับซ้อนกัน) ที่เกิดขึ้นในตารางของคุณสิ่งที่คุณเหลืออยู่คือปัญหาการบรรจุที่กำหนดสูงสุด

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


ภาคผนวก:นี่คืออัลกอริทึมการค้นหาย้อนรอยขั้นพื้นฐานที่อาจทำเคล็ดลับ:

function max_packing_recursive ( set A, set S, set M ):
    if |M| < |S| then let M = S;
    for each shape X in A do:
        remove X from A;
        let B = A;
        remove all shapes that intersect with X from B;
        if |M| < |B| + |S| + 1 then:        // upper bound
            let M = max_packing_recursive( B, S + {X}, M );
        end if
        if |M| >= |A| + |S| then return M;  // shortcut
    end for
    return M;
end function

function max_packing( set A ):
    return max_packing_recursive( A, {}, {} );
end function

นี่{X, Y, Z}หมายถึงชุดที่มีองค์ประกอบX, YและZ(มี{}เป็นเซตว่าง) และหมายถึงขนาดของชุด|Q|Q

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

(อันที่จริงแล้วเนื่องจากเรารู้ว่าแต่ละ T-shape มีสี่ไซต์แน่นอนขอบเขตบนที่ดีกว่านั้นสามารถรับได้โดยแทนที่|B|ด้วยจำนวนไซต์ที่แตกต่างซึ่งครอบคลุมโดยรูปร่างในBหารด้วยสี่และปัดเศษลง (และคล้ายกันสำหรับ|A|บน บรรทัดที่ทำเครื่องหมายด้วย// shortcut) อย่างไรก็ตามอัลกอริทึมตามที่ระบุข้างต้นใช้งานได้กับคอลเลกชันรูปร่างโดยพลการ)

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


ใช่ฉันคิดว่าเขาสามารถใช้ ILP เพื่อแก้ปัญหาได้ค่อนข้างลำบากเนื่องจากขนาดของปัญหา .. 2 ^ 20 ~ = 1,000,000 ดังนั้นเนื่องจากมีเพียงรูปร่าง T จำนวนมากเขาจึงควรใช้ตัวแก้เชิงเส้นสำหรับสิ่งนี้ . มันมีความซับซ้อนอย่างชัดเจนชี้แจง (อย่างน้อยก็จนกว่าจะมีคนจัดการเพื่อพิสูจน์ว่า p = np) ขนาดช่วยให้หลีกเลี่ยงการวิเคราะห์พฤติกรรมในกรณีที่ค่อนข้างง่ายนี้
AturSams

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