行列チェーンの乗算を最適化する


9

この課題は、いくつかの行列の積に対して最も効率的な乗算次数を計算することです。

行列のサイズは、標準入力の1行で指定されます。総乗算コストを最小限に抑えるには、乗算を実行する順序を示す整数のリストを標準出力に出力する必要があります。

例1

入力

5x6 6x12 12x100 100x7

出力

3 2 1

入力行は、スペースで区切られた行列サイズのリストであり、それぞれの行は行の数であり、その後に、x列の数が続きます。この例では、一緒に乗算する4つの行列があります(したがって、合計3つの乗算)。行列の乗算は結合的であるため、それらは任意の順序で実行できます。

出力は、総コストを最小限に抑えるために乗算を実行する順序でなければなりません。これは、次に実行する乗算の​​インデックスを表す整数のスペース区切りリストである必要があります。N行列の場合、このリストには1からN-1までの数値が含まれている必要があります。たとえば、出力3 2 1は、12x100 * 100x7最初に乗算を実行し、次に6x12 * 12x7乗算(2番目の行列に前のステップの結果を5x6 * 6x7掛けたもの)、最後に結果の乗算を実行する必要があることを意味します。

行列の乗算は常に互換性があります。つまり、行列の列数は後続の行列の行数と一致します。二つの行列の乗算のコストと想定しAxB * BxCているがA*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

注:確認のため、3つの例の最適な合計コストは9114、750、および1466344です。

最短のコードが勝ちます!


最後の例でよろしいですか?私のコードによって与えられた総コストが1466344.で
ハワード

@ハワード:はい、そうです、私のコードのバグです。修繕。
Keith Randall

回答:


1

ルビー、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]*' '

最初のバージョン: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ああ、私はその文を読みませんでした(そして、私はそれが好きではありません-それは非常に強い抑制です)。このケースにも対応できるソリューションを作ってみます。
ハワード
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.