เพิ่มประสิทธิภาพการคูณเมทริกซ์โซ่


9

ความท้าทายนี้คือการคำนวณลำดับการคูณที่มีประสิทธิภาพที่สุดสำหรับผลิตภัณฑ์ของเมทริกซ์หลายตัว

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

ตัวอย่างที่ 1

อินพุต

5x6 6x12 12x100 100x7

เอาท์พุต

3 2 1

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

ผลลัพธ์ควรเป็นลำดับที่จะทำการคูณเพื่อลดต้นทุนรวม นี่ควรเป็นรายการจำนวนเต็มคั่นด้วยช่องว่างซึ่งแสดงดัชนีของการคูณเพื่อดำเนินการต่อไป สำหรับเมทริกซ์ N รายการนี้ควรมีตัวเลข 1 ถึง N-1 โดยรวม ตัวอย่างเช่น 1 ผลลัพธ์3 2 1หมายความว่าคุณควรทำการ12x100 * 100x7คูณก่อนจากนั้นจึงทำการ6x12 * 12x7คูณ (เมทริกซ์ที่สองคูณผลลัพธ์ของขั้นตอนก่อนหน้า) จากนั้นก็5x6 * 6x7คูณผลลัพธ์ที่ได้

การคูณเมทริกซ์จะเข้ากันได้เสมอเช่นจำนวนคอลัมน์ของเมทริกซ์จะตรงกับจำนวนแถวของเมทริกซ์ที่ตามมา สมมติว่าค่าใช้จ่ายของการคูณสองการฝึกอบรมคือAxB * BxCA*B*C

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

ตัวอย่างที่ 2

อินพุต

5x10 10x5 5x15 15x5

เอาท์พุต

1 3 2

หรือ

3 1 2

ตัวอย่างที่ 3

อินพุต

22x11 11x78 78x123 123x666 666x35 35x97 97x111 111x20 20x50

เอาท์พุต

2 3 4 5 6 7 8 1

หมายเหตุ: สำหรับการตรวจสอบค่าใช้จ่ายรวมที่ดีที่สุดสำหรับตัวอย่างทั้งสามคือ 9114, 750 และ 1466344

รหัสที่สั้นที่สุดชนะ!


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

@ วิธี: ใช่คุณพูดถูกข้อผิดพลาดในรหัสของฉัน แก้ไขแล้ว.
Keith Randall

คำตอบ:


1

Ruby, 176 172 205 ตัวอักษร

นี่คือเวอร์ชั่นอื่น (อีกหลายตัวอักษร) ซึ่งจะทำงานสำหรับอินพุตขนาดใหญ่ในเวลาที่เหมาะสม

q=(gets.split<<$_[/\d+$/]).map &:to_i
r=Hash.new{|h,i|h[i]=Hash.new{|h,j|h[j]=1e12;h[j]=i==j ?[0,[]]:(i...j).map{|k|a,c=r[i][k];b,d=r[k+1][j];[a+b+q[i-1]*q[k]*q[j],c+d+[k]]}.min}}
$><<r[1][q.size-1][1]*' '

เวอร์ชันแรก: การนำ recursive ไปใช้ใน Ruby โดยตรง มันทำการค้นหาที่สมบูรณ์และดังนั้นจึงอาจช้าในอินพุตขนาดใหญ่

k=->m{m[2]?(1..m.size-2).map{|l|s=k[m[0,l]+m[l+1..-1]];[m[l-1]*m[l]*m[l+1]+s[0],[l]+s[1].map{|u|u<l ?u:u+1}]}.min: [0,[]]}
$><<k[(gets.split<<$_[/\d+$/]).map &:to_i][1]*' '

ส่วนหนึ่งของความท้าทายคือการจัดการ 100 เมทริกซ์ในเวลาที่เหมาะสมซึ่งรหัสนี้ไม่ได้
Keith Randall

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