Matris zinciri çarpımını optimize etme


9

Bu zorluk, birkaç matrisli bir ürün için en verimli çarpma sırasını hesaplamaktır .

Matrislerin boyutu, tek bir standart girdi satırında belirtilmiştir. Toplam çıktı maliyetini en aza indirmek için çarpımların hangi sırayla yapılacağını belirten bir tamsayı listesi standart çıktıya yazdırmalısınız.

örnek 1

giriş

5x6 6x12 12x100 100x7

çıktı

3 2 1

Giriş satırı, her biri satır sayısı, ardından bir xve ardından sütun sayısı olan, boşlukla ayrılmış bir matris boyutları listesi olacaktır . Örnek için, birlikte çoğaltılacak 4 matris vardır (toplam 3 çarpım) ve matris çarpımı ilişkisel olduğu için herhangi bir sırada yapılabilirler.

Çıktı, toplam maliyeti en aza indirmek için çarpımların gerçekleştirilme sırası olmalıdır. Bu, bir sonraki gerçekleştirilecek çarpma dizinini temsil eden, boşlukla ayrılmış bir tam sayı listesi olmalıdır. N matrisleri için, bu liste 1'den N-1'e kadar sayıları içermelidir. Örneğin 1, çıktı 3 2 1, önce 12x100 * 100x7çarpmayı, sonra 6x12 * 12x7çarpmayı (ikinci matris önceki adımın sonucunun 5x6 * 6x7çarpımını ) ve son olarak da ortaya çıkan çarpmayı yapmanız gerektiği anlamına gelir .

Matris çarpımları her zaman uyumlu olacaktır, yani bir matrisin sütun sayısı sonraki matrisin satır sayısıyla eşleşecektir. İki matris çarpma maliyetini varsayalım AxB * BxColduğunu A*B*C.

Kodunuz, her biri 999'a kadar olan boyutlara kadar 100 matris içeren listeleri işlemeli ve bunu makul bir zamanda yapmalıdır.

örnek 2

giriş

5x10 10x5 5x15 15x5

çıktı

1 3 2

veya

3 1 2

örnek 3

giriş

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

çıktı

2 3 4 5 6 7 8 1

Not: doğrulama için üç örnek için en iyi toplam maliyet 9114, 750 ve 1466344'tür.

En kısa kod kazanır!


Son örnekten emin misiniz? Kodum tarafından verilen toplam maliyet 1466344'dir.
Howard

@Howard: Evet, haklısın, kodumdaki bir hata. Sabit.
Keith Randall

Yanıtlar:


1

Yakut, 176 172 205 karakter

Burada makul bir zamanda büyük girdi için çalışacak başka bir sürüm (birkaç karakter daha uzun).

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]*' '

İlk sürüm: Ruby'de düz özyinelemeli uygulama. Tam bir arama yapar ve bu nedenle büyük girdilerde yavaş olabilir.

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]*' '

Zorluğun bir kısmı, bu kodun yapmadığı makul bir sürede 100 matrisi işlemektir.
Keith Randall

@KeithRandall Ah, bu cümleyi okumadım (ve hoşuma gitmedi - çok güçlü bir kısıtlama). Bu durumu da ele alabilecek bir çözüm oluşturmaya çalışacağım.
Howard
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.