Jump to content

Matrix chain multiplication: Difference between revisions

→‎{{header|Perl 6}}: simplified code to directly address the task specifications
(→‎{{header|Perl 6}}: simplified code to directly address the task specifications)
Line 592:
 
=={{header|Perl 6}}==
This example is based on Moritz Lenz's code, written for Carl Mäsak's Perl 6 Coding Contest, in 2010. Slightly simplified, it fulfills the Rosetta Code task as well.
<lang perl6>sub matrix-mult-chaining(@dimensions) {
my @cp;
# @cp has a dual function: the upper triangle of the diagonal matrix
# * the upper triangle of the diagonal matrix stores the cost (c) for
# stores the cost (c) for mulplyingmultiplying matrices $i and $j in @cp[$j][$i], where $j > $i
# * the lower triangle stores the path (p) that was used for the lowest cost
# multiplication to get from $i to $j.
 
# a matrix never needs to be multiplied with itself, so it has cost 0
{{incomplete|Perl 6|Does not show computed cost}}
<lang perl6># Reference:
# "Find the optimal way to multiply a chain of matrices. " was the first tasks at
# "masak's Perl 6 Coding Contest 2010". Here is the task definition
# http://strangelyconsistent.org/p6cc2010/p1.zip
#
# There are five finalist entries on the task, here are the relevant codes and contest host's comments
# 1) http://strangelyconsistent.org/p6cc2010/p1-colomon/
# 2) http://strangelyconsistent.org/p6cc2010/p1-fox/
# 3) http://strangelyconsistent.org/p6cc2010/p1-moritz/
# 4) http://strangelyconsistent.org/p6cc2010/p1-matthias/
# 5) http://strangelyconsistent.org/p6cc2010/p1-util/
#
# All entries passed perl6.d -c but during run time only the 3) entry (from moritz) produced the correct results.
 
#!/usr/bin/env perl6
use v6;
# after http://en.wikipedia.org/wiki/Matrix_chain_multiplication#A_Dynamic_Programming_Algorithm
sub matrix-mult-chaining(@dimensions) {
# @cp has a dual function: the upper triangle of the diagonal matrix
# stores the cost (c) for mulplying matrices $i and $j in @cp[$j][$i],
# $j > $i
# the lower triangle stores the path (p) that was used for the lowest cost
# multiplication to get from $i to $j.
#
# wikipedia this program
# m[i][j] @cp[$j][$i]
# s[i][j] @cp[$i][$j]
#
# it makes the code harder to read, but hey, it saves memory!
my @cp;
# a matrix never needs to be multiplied with itself,
# so it has cost 0
@cp[$_][$_] = 0 for @dimensions.keys;
my @path;
Line 636 ⟶ 612:
for $start .. $end - 1 -> $step {
my $new-cost = @cp[$step][$start]
+ @cp[$end][$step + 1]
+ [*] @dimensions[$start, $step+1, $end+1];
if $new-cost < @cp[$end][$start] {
@cp[$end][$start] = $new-cost; # cost
@cp[$endstart][$startend] = $new-coststep; # path
# path
@cp[$start][$end] = $step;
}
}
}
}
 
sub find-path(Int $start, Int $end) {
if $start == $end {
Line 657 ⟶ 632:
}
}
return @cp[$n-1][0], gather { find-path(0, $n - 1) }.join;
}
multi MAIN {
my $line = get;
my @dimensions = $line.comb: /\d+/;
if @dimensions < 2 {
say "Input must consist of at least two integers.";
} else {
say matrix-mult-chaining(@dimensions);
}
}
multi MAIN ('test') {
use Test;
plan *;
is matrix-mult-chaining(<10 30 5 60>), '((A1A2)A3)', 'wp example';
# http://www.cs.auckland.ac.nz/~jmor159/PLDS210/mat_chain.html
is matrix-mult-chaining(<10 100 5 50>), '((A1A2)A3)', 'auckland';
# an example verified by http://modoogle.com/matrixchainorder/
is matrix-mult-chaining(<6 2 5 1 6 3 9 1 25 18>),
'((A1((A2A3)((A4A5)(A6A7))))(A8A9))', 'modoogle';
# done_testing;
}</lang>
 
issay matrix-mult-chaining(<6 21 5 125 630 3100 970 2 1 25100 18250 1 1000 2>),;
{{Out}}
say matrix-mult-chaining(<1000, 1, 500, 12, 1, 700, 2500, 3, 2, 5, 14, 10>);</lang>
<pre>
 
./mcm3.p6
{{Outout}}
1, 5, 25, 30, 100, 70, 2, 1, 100, 250, 1, 1000, 2
<pre>(38120 ((((((((A1A2)A3)A4)A5)A6)A7)(A8(A9A10)))(A11A12)))
(1773740 (A1((((((A2A3)A4)(((A5A6)A7)A8))A9)A10)A11)))</pre>
</pre>
<pre>
./mcm3.p6
1000, 1, 500, 12, 1, 700, 2500, 3, 2, 5, 14, 10
(A1((((((A2A3)A4)(((A5A6)A7)A8))A9)A10)A11))
</pre>
 
=={{header|Phix}}==
2,392

edits

Cookies help us deliver our services. By using our services, you agree to our use of cookies.