อัลกอริทึมในการสร้างชุด m ทุกจุดใน nxnxn cubic lattice ซึ่งมีเอกลักษณ์ภายใต้สมมาตร


10

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

มีโครงตาข่ายลูกบาศก์ nxnxn เช่นถ้า n = 2 ประกอบด้วย (0,0,0), (0,1,0), (1,0,0), (1,1,0), (0, 1,1), (0,0,1), (1,0,1), (1,1,1)

จากขัดแตะนี้ฉันจะสร้างจุด m ซ้ำซ้ำทุกอย่างเช่น:

solve(set_of_points) {
     if set_of_points.size = m, finish

     do some useful computation here

     for each point in lattice not in set_of_points:
         solve(set_of_points + new_point);
}

ซึ่งสามารถเรียกได้ว่าเริ่มต้นด้วย set_of_point ที่ว่างเปล่า

ลักษณะของปัญหาที่เกิดขึ้นเป็นเช่นนั้นฉันไม่จริงต้องทุกการเปลี่ยนแปลงของจุดเมตรเพียงแค่คนที่เป็นเอกลักษณ์ภายใต้ symmetries ธรรมชาติของลูกบาศก์

ตัวอย่างเช่นใช้ 2x2x2 cube และสมมติว่าเราต้องการชุด 1 จุด ภายใต้อัลกอริทึมพื้นฐานด้านบนมี 8 ชุดที่แตกต่างกัน 1 จุด

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

หากคิวบ์คือ 2x2x2 และ m = 2 จะมี 28 ชุดในอัลกอริทึมพื้นฐาน แต่จะลดลงเหลือเพียง 3 ภายใต้สมมาตร (เช่น {(0,0,0), (1,0,0)}, {(0 , 0,0), (1,1,0)}, {(0,0,0), (1,1,1)})

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

(หมายเหตุ - ถ้า m = 1 สิ่งนี้ค่อนข้างง่าย - เพียงแค่เลือกจุดที่ใกล้เคียงกับ (0,0,0) มากกว่าจุดยอดอื่นใด ๆ โดยมีความยุ่งเหยิงเล็กน้อยที่ขอบเขตสำหรับ m> 1 ที่สิ่งนี้ได้รับ เป็นปัญหาจริง)


1
คุณจะรวมการดำเนินการใดที่เทียบเท่ากับสมมาตร: ระนาบสะท้อนผ่านศูนย์กลาง? การกลับจุดผ่านจุดศูนย์กลาง? ทั้งสี่แกนหมุนผ่านจุดศูนย์กลาง?
BmyGuest

ไอโซโทปใด ๆ ที่จะทำเคล็ดลับ
rbennett485

หากคุณยังอยู่ใกล้จะอนุญาตให้มีการทำซ้ำในจุด m-set หรือไม่ ตัวอย่างเช่นสำหรับ m = 3 คือ {(0,0,0), (1,1,1), (0,0,0)} ถือเป็นตัวเลือกที่ถูกต้องหรือไม่
blackpen

@blackpen ไม่ต้องเป็น 3 คะแนนที่ไม่ซ้ำกัน
rbennett485

คำตอบ:


1

แนวคิดพื้นฐาน:

(1) เราสามารถดูจุด (0,0,0) ได้อย่างง่ายดายเพียงแค่ 000 จุดแต่ละจุดในโครงข่ายจะอยู่ในลำดับที่เรียบง่าย จุดแรกคือ 000 จากนั้น 001 จากนั้น 010 011 100 101 110 และ 111 นี่คือคำสั่งที่คุณจะลองเพิ่มลงในจุดที่ตั้งไว้

(2) ในทำนองเดียวกันชุด {(0,0,0), (0,0,1), (0,1,0)} ก็สามารถมองเห็นได้เป็น 000001010 และชุด {(0,0,0) , (0,1,0), (0,0,1)} สามารถมองเห็นได้ง่าย ๆ เป็น 000010001 สองชุดที่แตกต่างกันไม่สามารถมีลำดับเดียวกันและคุณสามารถดู 000001010 ว่าเป็นตัวเลขหรือตัวอักษรน้อยกว่า 000010001 เรียกสิ่งนี้ว่า set-value ทุกชุดที่เป็นไปได้ของคะแนน N ตอนนี้มีค่าที่กำหนดไว้และชุดของคะแนน N ที่เป็นไปได้ทั้งหมดจะอยู่ในรายการที่เรียงลำดับอย่างง่าย

(3) ทุกกลุ่ม isomorphic ของชุดจุดมีสมาชิกหนึ่งคนที่จะมีชุดค่าต่ำสุด สิ่งเหล่านี้เป็นสิ่งเดียวที่เราทำ "การคำนวณที่มีประโยชน์"

(4) นี่คือส่วนที่จะต้องมีการทำงานที่สำคัญ ก่อนที่คุณจะแก้ปัญหา (set_of_points + new_point) คุณต้องการดูว่า isomorphism ใด ๆ ที่จะลดค่า set สำหรับ set_of_points + new_point หรือไม่ หาก isomorphism ใด ๆ จะลดค่าที่ตั้งไว้นี่ไม่ใช่ค่าต่ำสุดของ isomorphic-set เราข้ามไปทำงานใด ๆ กับ new_point นี้ เรากำลังข้ามงานที่เรียกซ้ำทั้งหมดที่เราได้ทำไปในการแก้ปัญหานี้ (set_of_points, candidate_point)

solve(set_of_points,new_point) {
 set_of_points = set_of_points + new_point
 do some useful computation here
 if set_of_points.size = m, compute how many isomophisms exist, apply that multiple, finish
 for(candidate_point = new_point+1 to last_point) { /skips point-permutations for free!/
  if ISOMORPH_TESTS_CANNOT_LOWER_VALUE_OF(set_of_points+candidate_point) {
   solve(set_of_points,candidate_point);
  }
 }
}

1

จดบันทึกคำตอบข้างต้น

ให้ก่อนกำหนด symmertry ที่เสนอโดยฟังก์ชั่นหมุน (ทิศทาง, number_of_time)

สารละลาย:

(1) สร้างแฮชของการเปลี่ยนแปลงทั้งหมดที่มีการตั้งค่าสถานะ = 0 ในแต่ละ ตัวอย่างเช่น n = 2, m = 2 000,001 = 0 000,010 = 0 000,011 = 0 ect '...

(2) เริ่มต้นจากชุดเริ่มต้นตัวอย่างเช่น i = 000,001

(3) หมุนชุด i ไปทุกทิศทุกทางโดยใช้ฟังก์ชั่นหมุน (หรือสมมาตรอื่น ๆ ที่คุณชอบ) เช่นฟังก์ชั่นหมุนควรจะเรียก 24 ครั้งสำหรับการเปลี่ยนรูปแบบการหมุนแต่ละครั้ง

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

คำอธิบาย: หมายเลข 1-6 ใด ๆ สามารถอยู่ต่อหน้าคุณและแต่ละหมายเลขสามารถหมุนได้ 4 ครั้งดังนั้น 6 * 4 = 24

(4) สำหรับแต่ละชุดที่ถอนการรวมกันให้ตั้งค่าสถานะแฮชเป็น 1 (มีชุดสมมาตรแล้ว)

(5) อัปเดต i เป็นชุดถัดไปเช่น i = 000,010

(6) หากชุด i ในแฮชที่ทำเครื่องหมายไว้แล้วให้ไปที่ (5) มิฉะนั้นไปที่ (3)

เราจะทำเมื่อแฮชทั้งหมดถูกทำเครื่องหมายเป็น 1


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

1

หมายเหตุ: ฉันคิดเฉพาะเกี่ยวกับกระจกสมมาตรไม่ใช่แบบหมุนได้ที่นี่

สมมุติว่าเรามีลูกบาศก์ (ไฮเปอร์) ขนาดdแต่ละหน่วยnยาว (ลูกบาศก์ของรูบิคจะเป็นd = 3, n = 3 )

อัลกอริธึมไร้เดียงสาจะสร้างจุดรวมn ^ dและตรวจสอบการปะทะกันแบบสมมาตรกับผู้อื่นทั้งหมด

ถ้าเราเป็นตัวแทนของการรวมกันของจุดที่เป็นเวกเตอร์บิตn ^ dบิตยาวเราสามารถใช้แผนที่ (เวกเตอร์บิต -> บูล) เพื่อทำเครื่องหมาย symmetries ทั้งหมดของเวกเตอร์บิตที่มีจริง จากนั้นเราสามารถข้ามชุดค่าผสมได้หากมีการทำเครื่องหมายไว้ในแผนที่แล้ว

วิธีการนี้ไม่มีประสิทธิภาพในพื้นที่มาก: ใช้แผนที่ที่มีรายการ2 ^ (n ^ d)นั่นคือบิตแมปที่มีบิตจำนวนมาก (สำหรับลูกบาศก์ของ Rubik มันจะเป็น 2 ^ 27 = 128Mbit = 16 Mbytes)

เราสามารถจดจำการแทนค่าแบบบัญญัติซึ่งก็คือบิตเวคเตอร์ดังกล่าวที่มีค่าจำนวนเต็มที่น้อยที่สุดหากแสดงเป็นคำที่ไม่ได้ลงนามบิตn ^ d-บิต เมื่อเราสร้างจุดเปลี่ยนรูปแบบใหม่เราจะสร้างสมมาตรทั้งหมดและตรวจสอบว่าเราเห็นความสมมาตรด้วยค่าตัวเลขที่น้อยที่สุดเท่านั้น สิ่งนี้จะช่วยให้เราสามารถเก็บแผนที่ด้วยบิต2 ^ nบิต (เพียง 1 ไบต์สำหรับลูกบาศก์ของรูบิค) เพราะเรามีสัดส่วน2 ^ d มันทำให้เราสร้างสมมาตร2 ^ dเหล่านี้ในแต่ละขั้นตอนดังนั้นเราใช้O (2 ^ (d ^ n + d)) = O (2 ^ (d ^ n) * 2 ^ d)เวลา ยังไม่ดี

เราสามารถนำแนวคิดจากย่อหน้าก่อนหน้าไปใช้กับตัวพิมพ์ 1 มิติ ในการสร้างรวมกันทั้งหมดในเวกเตอร์ของความยาวdเราก็สามารถเพิ่มจำนวนไบนารีdบิตนานเริ่มต้นจากทั้งหมด0s ลองแบ่งเวกเตอร์ของเราเป็นสองส่วนd / 2ยาวเช่นซ้ายและขวา เราสามารถสังเกตเห็นได้ว่าสำหรับแต่ละ1บิตในส่วนด้านซ้ายเราจะต้องเห็นชุดค่าผสมที่มี1บิตในตำแหน่งสมมาตรของส่วนด้านขวา มิฉะนั้นเราจะได้สร้างแล้วรวมกันสมมาตรก่อนหน้านี้เมื่อตำแหน่งของบิตที่ถูกสลับและมาก่อน0 1วิธีนี้สำหรับทุก ๆ ตำแหน่งบิตในครึ่งขวา(r)และตำแหน่งสมมาตรในครึ่งซ้าย(l)เราต้องสร้างชุดค่าผสม 3 ชุดเท่านั้น: (l = 0, r = 0); (l = 1, r = 1); (L = 1, r = 0) ดังนั้นเราจำเป็นต้องสร้างการเปลี่ยนแปลง2 ^ (d / 2)ของเวกเตอร์ที่มีความยาวd , ให้ผล 3 ชุดสำหรับการเปลี่ยนรูปแต่ละครั้ง

ก้อนของdมิติสามารถถูกสร้างขึ้นจากn ^ (D-1)เวกเตอร์ เคล็ดลับข้างต้นทำให้เรามีเวกเตอร์ที่ถูกกว่าวิธีการไร้เดียงสา เพื่อสร้างลูกบาศก์เราต้องO (n ^ (D-1) * 2 ^ (d / 2))เวลา

ถ้าเราดูลูกบาศก์ตามมิติของเวกเตอร์ 1 มิติเราจะเห็นว่าเราไม่ต้องตรวจสอบความสมมาตรตามมิตินี้: ในขณะที่สร้างลูกบาศก์เราจะกำจัดสมมาตรสำหรับเวกเตอร์ที่เกี่ยวข้องแต่ละอัน

ตอนนี้ถ้าเรามองข้ามมิตินี้เราสามารถใช้กลอุบายเดิมได้

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

เคล็ดลับนี้สามารถนำไปใช้เพื่อ จำกัด การสร้างพีชคณิตของระนาบต่อไปนี้ในมิติที่สามเป็นต้น

แม้ว่าจะไม่ใช่อัลกอริทึมที่สมบูรณ์ แต่ฉันหวังว่าสิ่งนี้จะช่วยได้

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