优化矩阵链乘法


9

挑战在于为几个矩阵的乘积计算最有效的乘法顺序

矩阵的大小在标准输入的一行中指定。您应该在标准输出中打印一个整数列表,该整数列表指示进行乘法的顺序以最大程度地减少总乘法成本。

例子1

输入

5x6 6x12 12x100 100x7

输出

3 2 1

输入行将是用空格分隔的矩阵大小列表,每个矩阵大小是行数,后跟一个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

@霍华德:是的,是的,我的代码中有一个错误。固定。
基思·兰德尔

Answers:


1

Ruby,176172205 字符

这是另一个版本(更长的几个字符),也将在合理的时间内运行以进行大量输入。

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个矩阵,而这段代码却没有。
基思·兰德尔

@KeithRandall啊,我没看过那句话(我不喜欢它-约束很严格)。我将尝试构建一个也可以处理这种情况的解决方案。
霍华德
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.