Matrix chain multiplication: Difference between revisions

Added FreeBASIC
(Added FreeBASIC)
 
(6 intermediate revisions by 5 users not shown)
Line 1:
{{task|Discrete math}}
[[Category:Matrices]]
 
;Problem
Using the most straightfowardstraightforward algorithm (which we assume here), computing the [[Matrix multiplication|product of two matrices]] of dimensions (n1,n2) and (n2,n3) requires n1*n2*n3 [[wp:Multiply–accumulate_operation|FMA]] operations. The number of operations required to compute the product of matrices A1, A2... An depends on the order of matrix multiplications, hence on where parens are put. Remember that the matrix product is associative, but not commutative, hence only the parens can be moved.
 
For instance, with four matrices, one can compute A(B(CD)), A((BC)D), (AB)(CD), (A(BC))D, (AB)C)D. The number of different ways to put the parens is a [[Catalan numbers|Catalan number]], and grows exponentially with the number of factors.
Line 30 ⟶ 31:
=={{header|11l}}==
{{trans|Nim}}
<syntaxhighlight lang="11l">T Optimizer
 
<lang 11l>T Optimizer
[Int] dims
[[Int]] m, s
Line 70:
print(‘Order: ’opt.optimalChainOrder(0, dims.len - 2))
print(‘Cost: ’opt.m[0][dims.len - 2])
print(‘’)</langsyntaxhighlight>
 
{{out}}
Line 91:
This example implements the pseudocode in the reference Wiki page. The pseudocode states that the index values for the array to multiply begin at 0 while the cost and order matrices employ index values beginning at 1. Ada supports this pseudocode directly because Ada allows the programmer to define the index range for any array type.
This Ada example is implemented using a simple package and a main procedure. The package specification is:
<langsyntaxhighlight lang="ada">
package mat_chain is
type Vector is array (Natural range <>) of Integer;
procedure Chain_Multiplication (Dims : Vector);
end mat_chain;
</syntaxhighlight>
</lang>
The implementation or body of the package is:
<langsyntaxhighlight lang="ada">
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
Line 190:
 
end mat_chain;
</syntaxhighlight>
</lang>
The main procedure is:
<langsyntaxhighlight lang="ada">
with Mat_Chain; use Mat_Chain;
with Ada.Text_IO; use Ada.Text_IO;
Line 207:
Chain_Multiplication(V3);
end chain_main;
</syntaxhighlight>
</lang>
{{output}}
<pre>
Line 225:
=={{header|C}}==
{{trans|Kotlin}}
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <limits.h>
#include <stdlib.h>
Line 296:
}
return 0;
}</langsyntaxhighlight>
 
{{output}}
Line 315:
=={{header|C sharp|C#}}==
{{trans|Kotlin}}
<langsyntaxhighlight lang="csharp">using System;
 
class MatrixChainOrderOptimizer {
Line 374:
}
}
}</langsyntaxhighlight>
 
{{output}}
Line 389:
Order : (A((((((BC)D)(((EF)G)H))I)J)K))
Cost : 1773740
</pre>
 
=={{header|C++}}==
<syntaxhighlight lang="c++">
#include <cstdint>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
 
constexpr int32_t MAXIMUM_VALUE = 2'147'483'647;
 
std::vector<std::vector<int32_t>> cost;
std::vector<std::vector<int32_t>> order;
 
void print_vector(const std::vector<int32_t>& list) {
std::cout << "[";
for ( uint64_t i = 0; i < list.size() - 1; ++i ) {
std::cout << list[i] << ", ";
}
std::cout << list.back() << "]" << std::endl;
}
 
int32_t matrix_chain_order(const std::vector<int32_t>& dimensions) {
const uint64_t size = dimensions.size() - 1;
cost = { size, std::vector<int32_t>(size, 0) };
order = { size, std::vector<int32_t>(size, 0) };
 
for ( uint64_t m = 1; m < size; ++m ) {
for ( uint64_t i = 0; i < size - m; ++i ) {
int32_t j = i + m;
cost[i][j] = MAXIMUM_VALUE;
for ( int32_t k = i; k < j; ++k ) {
int32_t current_cost = cost[i][k] + cost[k + 1][j]
+ dimensions[i] * dimensions[k + 1] * dimensions[j + 1];
if ( current_cost < cost[i][j] ) {
cost[i][j] = current_cost;
order[i][j] = k;
}
}
}
}
return cost[0][size - 1];
}
 
std::string get_optimal_parenthesizations(const std::vector<std::vector<int32_t>>& order,
const uint64_t& i, const uint64_t& j) {
if ( i == j ) {
std::string result(1, char(i + 65));
return result;
} else {
std::stringstream stream;
stream << "(" << get_optimal_parenthesizations(order, i, order[i][j])
<< " * " << get_optimal_parenthesizations(order, order[i][j] + 1, j) << ")";
return stream.str();
}
}
 
void matrix_chain_multiplication(const std::vector<int32_t>& dimensions) {
std::cout << "Array Dimension = "; print_vector(dimensions);
std::cout << "Cost = " << matrix_chain_order(dimensions) << std::endl;
std::cout << "Optimal Multiply = "
<< get_optimal_parenthesizations(order, 0, order.size() - 1) << std::endl << std::endl;
}
 
int main() {
matrix_chain_multiplication({ 5, 6, 3, 1 });
matrix_chain_multiplication({ 1, 5, 25, 30, 100, 70, 2, 1, 100, 250, 1, 1000, 2 });
matrix_chain_multiplication({ 1000, 1, 500, 12, 1, 700, 2500, 3, 2, 5, 14, 10 });
}
</syntaxhighlight>
{{ out }}
<pre>
Array Dimension = [5, 6, 3, 1]
Cost = 48
Optimal Multiply = (A * (B * C))
 
Array Dimension = [1, 5, 25, 30, 100, 70, 2, 1, 100, 250, 1, 1000, 2]
Cost = 38120
Optimal Multiply = ((((((((A * B) * C) * D) * E) * F) * G) * (H * (I * J))) * (K * L))
 
Array Dimension = [1000, 1, 500, 12, 1, 700, 2500, 3, 2, 5, 14, 10]
Cost = 1773740
Optimal Multiply = (A * ((((((B * C) * D) * (((E * F) * G) * H)) * I) * J) * K))
</pre>
 
=={{header|Fortran}}==
{{trans|Python}}
 
This is a translation of the Python iterative solution.
 
<langsyntaxhighlight lang="fortran">module optim_mod
implicit none
contains
Line 451 ⟶ 534:
call optim([1, 5, 25, 30, 100, 70, 2, 1, 100, 250, 1, 1000, 2])
call optim([1000, 1, 500, 12, 1, 700, 2500, 3, 2, 5, 14, 10])
end program</langsyntaxhighlight>
 
'''Output'''
Line 460 ⟶ 543:
1773740 (1*((((((2*3)*4)*(((5*6)*7)*8))*9)*10)*11))
</pre>
 
=={{header|FreeBASIC}}==
{{trans|VBA}}
This is a translation of the Python iterative solution.
<syntaxhighlight lang="vbnet">Dim Shared As Integer U(), V()
 
Sub Aux(i As Integer, j As Integer)
Dim As Integer k = U(i, j)
If k < 0 Then
Print Str(i);
Else
Print "(";
Aux(i, k)
Print "*";
Aux(i + k, j - k)
Print ")";
End If
End Sub
 
Sub Optimize(a() As Integer)
Dim As Integer i, j, k, c
Dim As Integer n = Ubound(a) - 1
Redim U(n, n), V(n, n)
For i = 1 To n
U(i, 1) = -1
V(i, 1) = 0
Next i
For j = 2 To n
For i = 1 To n - j + 1
V(i, j) = &H7FFFFFFF
For k = 1 To j - 1
c = V(i, k) + V(i + k, j - k) + a(i) * a(i + k) * a(i + j)
If c < V(i, j) Then
U(i, j) = k
V(i, j) = c
End If
Next k
Next i
Next j
Print V(1, n); " ";
Aux(1, n)
Print
Erase U, V
End Sub
 
Dim As Integer A1(1 To 4) = {5, 6, 3, 1}
Optimize(A1())
Dim As Integer A2(1 To 13) = {1, 5, 25, 30, 100, 70, 2, 1, 100, 250, 1, 1000, 2}
Optimize(A2())
Dim As Integer A3(1 To 12) = {1000, 1, 500, 12, 1, 700, 2500, 3, 2, 5, 14, 10}
Optimize(A3())
 
Sleep</syntaxhighlight>
{{out}}
<pre> 48(1*(2*3))
38120((((((((1*2)*3)*4)*5)*6)*7)*(8*(9*10)))*(11*12))
1773740(1*((((((2*3)*4)*(((5*6)*7)*8))*9)*10)*11))</pre>
 
=={{header|Go}}==
The first <code>for</code> loop is based on the pseudo and Java code from the
[[wp:Matrix_chain_multiplication#A_dynamic_programming_algorithm|Wikipedia article]].
<langsyntaxhighlight Golang="go">package main
 
import "fmt"
Line 539 ⟶ 681:
fmt.Println()
}
}</langsyntaxhighlight>
{{out}}
<pre>
Line 570 ⟶ 712:
 
=={{header|Haskell}}==
<langsyntaxhighlight Haskelllang="haskell">import Data.List (elemIndex)
import Data.Char (chr, ord)
import Data.Maybe (fromJust)
Line 610 ⟶ 752:
 
main :: IO ()
main = mapM_ printBlock mats</langsyntaxhighlight>
{{out}}
<pre>for [5,6,3,1] we have 48 possibilities, z.B (a(bc))
Line 621 ⟶ 763:
Given J's incredible strengths with arrays and matrices, the author is certain there is a much more succinct and idiomatic approach available, but hasn't spent the time understanding how the Wikipedia algorithm works, so hasn't made an attempt at a more native J solution. Others on RC are welcome and invited to do so.
 
<langsyntaxhighlight lang="j">moo =: verb define
s =. m =. 0 $~ ,~ n=._1+#y
for_lmo. 1+i.<:n do.
Line 654 ⟶ 796:
smoutput 'Cost: ' , ": x: M {~ <0;_1
smoutput 'Order: ', S poco 0 , <:#M
)</langsyntaxhighlight>
 
{{out}}
 
<langsyntaxhighlight lang="j"> optMM 5 6 3 1
Cost: 48
Order: (A(BC))
Line 668 ⟶ 810:
optMM 1000 1 500 12 1 700 2500 3 2 5 14 10
Cost: 1773740
Order: (A((((((BC)D)(((EF)G)H))I)J)K))</langsyntaxhighlight>
 
=={{header|Java}}==
Thanks to the Wikipedia page for a working Java implementation.
<langsyntaxhighlight lang="java">
import java.util.Arrays;
 
Line 733 ⟶ 875:
 
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 754 ⟶ 896:
'''Works with gojq, the Go implementation of jq'''
 
<langsyntaxhighlight lang="jq"># Input: array of dimensions
# output: {m, s}
def optimalMatrixChainOrder:
Line 791 ⟶ 933:
(optimalMatrixChainOrder
| "Order : \(printOptimalChainOrder(0; .s|length - 1))",
"Cost : \(.m[0][.s|length - 1])\n" )</langsyntaxhighlight>
{{out}}
<pre>
Line 806 ⟶ 948:
Cost : 1777600
</pre>
 
 
=={{header|Julia}}==
Line 813 ⟶ 954:
 
'''Module''':
<langsyntaxhighlight lang="julia">module MatrixChainMultiplications
 
using OffsetArrays
Line 842 ⟶ 983:
end
 
end # module MatrixChainMultiplications</langsyntaxhighlight>
 
'''Main''':
<langsyntaxhighlight lang="julia">println(MatrixChainMultiplications.optim([1, 5, 25, 30, 100, 70, 2, 1, 100, 250, 1, 1000, 2]))
println(MatrixChainMultiplications.optim([1000, 1, 500, 12, 1, 700, 2500, 3, 2, 5, 14, 10]))</langsyntaxhighlight>
 
{{out}}
Line 854 ⟶ 995:
=={{header|Kotlin}}==
This is based on the pseudo-code in the Wikipedia article.
<langsyntaxhighlight lang="scala">// Version 1.2.31
 
lateinit var m: List<IntArray>
Line 903 ⟶ 1,044:
println("\nCost : ${m[0][s.size - 1]}\n")
}
}</langsyntaxhighlight>
 
{{out}}
Line 921 ⟶ 1,062:
 
=={{header|Lua}}==
<langsyntaxhighlight lang="lua">-- Matrix A[i] has dimension dims[i-1] x dims[i] for i = 1..n
local function MatrixChainOrder(dims)
local m = {}
Line 977 ⟶ 1,118:
printOptimalChainOrder(s)
print("Cost : "..tostring(m[1][#s]).."\n")
end</langsyntaxhighlight>
 
{{out}}
Line 996 ⟶ 1,137:
=={{header|Mathematica}} / {{header|Wolfram Language}}==
{{trans|Fortran}}
<langsyntaxhighlight Mathematicalang="mathematica">ClearAll[optim, aux]
optim[a_List] := Module[{u, v, n, c, r, s},
n = Length[a] - 1;
Line 1,038 ⟶ 1,179:
{r, s} = optim[{1000, 1, 500, 12, 1, 700, 2500, 3, 2, 5, 14, 10}];
r
s</langsyntaxhighlight>
{{out}}
<pre>38120
Line 1,044 ⟶ 1,185:
1773740
1*((((((2*3)*4)*(((5*6)*7)*8))*9)*10)*11)</pre>
 
 
=={{header|MATLAB}}==
{{trans|Fortran}}
<syntaxhighlight lang="matlab">function [r,s] = optim(a)
 
<lang matlab>function [r,s] = optim(a)
n = length(a)-1;
u = zeros(n,n);
Line 1,077 ⟶ 1,216:
s = sprintf("(%s*%s)",aux(u,i,k),aux(u,i+k,j-k));
end
end</langsyntaxhighlight>
 
{{out}}
 
<langsyntaxhighlight lang="matlab">[r,s] = optim([1,5,25,30,100,70,2,1,100,250,1,1000,2])
 
r =
Line 1,102 ⟶ 1,241:
s =
 
"(1*((((((2*3)*4)*(((5*6)*7)*8))*9)*10)*11))"</langsyntaxhighlight>
 
=={{header|Nim}}==
{{trans|Kotlin}}
<langsyntaxhighlight Nimlang="nim">import sequtils
 
type Optimizer = object
Line 1,160 ⟶ 1,299:
echo "Order: ", opt.optimalChainOrder(0, dims.len - 2)
echo "Cost: ", opt.m[0][dims.len - 2]
echo ""</langsyntaxhighlight>
 
{{out}}
Line 1,177 ⟶ 1,316:
=={{header|Perl}}==
{{trans|Raku}}
<langsyntaxhighlight lang="perl">use strict;
use feature 'say';
 
Line 1,223 ⟶ 1,362:
 
say matrix_mult_chaining(<1 5 25 30 100 70 2 1 100 250 1 1000 2>);
say matrix_mult_chaining(<1000 1 500 12 1 700 2500 3 2 5 14 10>);</langsyntaxhighlight>
{{out}}
<pre>38120 ((((((((A1A2)A3)A4)A5)A6)A7)(A8(A9A10)))(A11A12))
Line 1,230 ⟶ 1,369:
=={{header|Phix}}==
As per the wp pseudocode
<!--<langsyntaxhighlight Phixlang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">optimal_chain_order</span><span style="color: #0000FF;">(</span><span style="color: #004080;">int</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">int</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">sequence</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
Line 1,269 ⟶ 1,408:
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Order : %s\nCost : %d\n"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">optimal_matrix_chain_order</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ti</span><span style="color: #0000FF;">))</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</langsyntaxhighlight>-->
{{out}}
<pre>
Line 1,294 ⟶ 1,433:
=== Enumeration of parenthesizations ===
 
<langsyntaxhighlight lang="python">def parens(n):
def aux(n, k):
if n == 1:
Line 1,306 ⟶ 1,445:
for v in aux(n - i, k + i):
yield [u, v]
yield from aux(n, 0)</langsyntaxhighlight>
 
'''Example''' (in the same order as in the task description)
 
<langsyntaxhighlight lang="python">for u in parens(4):
print(u)
 
Line 1,317 ⟶ 1,456:
[[0, 1], [2, 3]]
[[0, [1, 2]], 3]
[[[0, 1], 2], 3]</langsyntaxhighlight>
 
And here is the optimization step:
 
<langsyntaxhighlight lang="python">def optim1(a):
def cost(k):
if type(k) is int:
Line 1,337 ⟶ 1,476:
cmin = c
umin = u
return cmin, umin</langsyntaxhighlight>
 
=== Recursive cost optimization ===
Line 1,343 ⟶ 1,482:
The previous function optim1 already used recursion, but only to compute the cost of a given parens configuration, whereas another function (a generator actually) provides these configurations. Here we will do both recursively in the same function, avoiding the computation of configurations altogether.
 
<langsyntaxhighlight lang="python">def optim2(a):
def aux(n, k):
if n == 1:
Line 1,365 ⟶ 1,504:
return m, p, q, u
s, p, q, u = aux(len(a) - 1, 0)
return s, u</langsyntaxhighlight>
 
=== Memoized recursive call ===
Line 1,371 ⟶ 1,510:
The only difference between optim2 and optim3 is the [[:wp:https://en.wikipedia.org/wiki/Memoization|@memoize]] [https://www.python.org/dev/peps/pep-0318/ decorator]. Yet the algorithm is way faster with this. According to Wikipedia, the complexity falls from O(2^n) to O(n^3). This is confirmed by plotting log(time) vs log(n) for n up to 580 (this needs [https://docs.python.org/3/library/sys.html#sys.setrecursionlimit changing Python's recursion limit]).
 
<langsyntaxhighlight lang="python">def memoize(f):
h = {}
def g(*u):
Line 1,405 ⟶ 1,544:
return m, p, q, u
s, p, q, u = aux(len(a) - 1, 0)
return s, u</langsyntaxhighlight>
 
=== Putting all together ===
 
<langsyntaxhighlight lang="python">import time
 
u = [[1, 5, 25, 30, 100, 70, 2, 1, 100, 250, 1, 1000, 2],
Line 1,424 ⟶ 1,563:
t2 = time.clock()
print("%s %10.3f %10d %s" % (f.__name__, 1000 * (t2 - t1), s, u))
print()</langsyntaxhighlight>
 
'''Output''' (timings are in milliseconds)
Line 1,451 ⟶ 1,590:
In the previous solution, memoization is done blindly with a dictionary. However, we need to compute the optimal products for all sublists. A sublist is described by its first index and length (resp. i and j+1 in the following function), hence the set of all sublists can be described by the indices of elements in a triangular array u. We first fill the "solution" (there is no product) for sublists of length 1 (u[0]), then for each successive length we optimize using what when know about smaller sublists. Instead of keeping track of the optimal solutions, the single needed one is computed in the end.
 
<langsyntaxhighlight lang="python">def optim4(a):
global u
n = len(a) - 1
Line 1,479 ⟶ 1,618:
 
print(optim4([1, 5, 25, 30, 100, 70, 2, 1, 100, 250, 1, 1000, 2]))
print(optim4([1000, 1, 500, 12, 1, 700, 2500, 3, 2, 5, 14, 10]))</langsyntaxhighlight>
 
'''Output'''
Line 1,488 ⟶ 1,627:
</pre>
 
=={{header|RacketR}}==
<syntaxhighlight lang="rsplus">aux <- function(i, j, u) {
k <- u[[i, j]]
if (k < 0) {
i
} else {
paste0("(", Recall(i, k, u), "*", Recall(i + k, j - k, u), ")")
}
}
 
chain.mul <- function(a) {
n <- length(a) - 1
u <- matrix(0, n, n)
v <- matrix(0, n, n)
u[, 1] <- -1
 
for (j in seq(2, n)) {
for (i in seq(n - j + 1)) {
v[[i, j]] <- Inf
for (k in seq(j - 1)) {
s <- v[[i, k]] + v[[i + k, j - k]] + a[[i]] * a[[i + k]] * a[[i + j]]
if (s < v[[i, j]]) {
u[[i, j]] <- k
v[[i, j]] <- s
}
}
}
}
 
list(cost = v[[1, n]], solution = aux(1, n, u))
}
 
chain.mul(c(5, 6, 3, 1))
# $cost
# [1] 48
 
# $solution
# [1] "(1*(2*3))"
 
chain.mul(c(1, 5, 25, 30, 100, 70, 2, 1, 100, 250, 1, 1000, 2))
# $cost
# [1] 38120
 
# $solution
# [1] "((((((((1*2)*3)*4)*5)*6)*7)*(8*(9*10)))*(11*12))"
 
chain.mul(c(1000, 1, 500, 12, 1, 700, 2500, 3, 2, 5, 14, 10))
# $cost
# [1] 1773740
 
# $solution
# [1] "(1*((((((2*3)*4)*(((5*6)*7)*8))*9)*10)*11))"</syntaxhighlight>
 
=={{header|Racket}}==
'''Memoization'''
 
<langsyntaxhighlight lang="racket">#lang racket
 
(define (memoize f)
Line 1,517 ⟶ 1,708:
#:combine (λ (left-answer right-answer _)
(list left-answer '× right-answer)))))]))))
(loop 0 (sub1 (vector-length dims))))</langsyntaxhighlight>
 
'''Main'''
 
<langsyntaxhighlight lang="racket">(define-syntax-rule (echo <x> ...)
(begin (printf "~a: ~a\n" (~a (quote <x>) #:min-width 12) <x>) ...))
 
Line 1,530 ⟶ 1,721:
 
(solve #(1 5 25 30 100 70 2 1 100 250 1 1000 2))
(solve #(1000 1 500 12 1 700 2500 3 2 5 14 10))</langsyntaxhighlight>
 
'''Output''' (timings are in milliseconds)
Line 1,549 ⟶ 1,740:
(formerly 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.
<syntaxhighlight lang="raku" perl6line>sub matrix-mult-chaining(@dimensions) {
my @cp;
# @cp has a dual function:
Line 1,593 ⟶ 1,784:
 
say matrix-mult-chaining(<1 5 25 30 100 70 2 1 100 250 1 1000 2>);
say matrix-mult-chaining(<1000 1 500 12 1 700 2500 3 2 5 14 10>);</langsyntaxhighlight>
 
{{out}}
Line 1,600 ⟶ 1,791:
 
=={{header|Rust}}==
<langsyntaxhighlight lang="rust">use std::collections::HashMap;
 
fn main() {
Line 1,658 ⟶ 1,849:
}
}
}</langsyntaxhighlight>
{{out}}
<pre>
Line 1,680 ⟶ 1,871:
Here is the equivalent of optim3 in Python's solution. Memoization is done with an [https://www.stata.com/help.cgi?mf_asarray associative array]. Multiple results are returned in a [https://www.stata.com/help.cgi?m2_struct structure]. The same effect as optim2 can be achieved by removing the asarray machinery.
 
<langsyntaxhighlight lang="stata">mata
struct ans {
real scalar p,q,s
Line 1,740 ⟶ 1,931:
optim((1,5,25,30,100,70,2,1,100,250,1,1000,2))
optim((1000,1,500,12,1,700,2500,3,2,5,14,10))
end</langsyntaxhighlight>
 
'''Output'''
Line 1,754 ⟶ 1,945:
{{trans|Fortran}}
 
<langsyntaxhighlight lang="stata">mata
function aux(u,i,j) {
k = u[i,j]
Line 1,792 ⟶ 1,983:
optim((1,5,25,30,100,70,2,1,100,250,1,1000,2))
optim((1000,1,500,12,1,700,2500,3,2,5,14,10))
end</langsyntaxhighlight>
 
'''Output'''
Line 1,806 ⟶ 1,997:
{{trans|Fortran}}
 
<langsyntaxhighlight lang="vb">Option Explicit
Option Base 1
Dim N As Long, U() As Long, V() As Long
Line 1,853 ⟶ 2,044:
Call Optimize(Array(1, 5, 25, 30, 100, 70, 2, 1, 100, 250, 1, 1000, 2))
Call Optimize(Array(1000, 1, 500, 12, 1, 700, 2500, 3, 2, 5, 14, 10))
End Sub</langsyntaxhighlight>
 
'''Output'''
Line 1,865 ⟶ 2,056:
=={{header|Wren}}==
{{trans|Kotlin}}
<langsyntaxhighlight ecmascriptlang="wren">var m = []
var s = []
 
Line 1,915 ⟶ 2,106:
printOptimalChainOrder.call(0, s.count - 1)
System.print("\nCost : %(m[0][s.count - 1])\n")
}</langsyntaxhighlight>
 
{{out}}
Line 1,934 ⟶ 2,125:
=={{header|zkl}}==
{{trans|Python}}
<langsyntaxhighlight lang="zkl">fcn optim3(a){ // list --> (int,list)
aux:=fcn(n,k,a){ // (int,int,list) --> (int,int,int,list)
if(n==1){
Line 1,972 ⟶ 2,163:
h[key]=r;
return(r);
}</langsyntaxhighlight>
<langsyntaxhighlight lang="zkl">fcn pp(u){ // pretty print a list of lists
var letters=["A".."Z"].pump(String);
u.pump(String,
fcn(n){ if(List.isType(n)) String("(",pp(n),")") else letters[n] })
}
fcn prnt(s,u){ "%-9,d %s\n\t-->%s\n".fmt(s,u.toString(*,*),pp(u)).println() }</langsyntaxhighlight>
<langsyntaxhighlight lang="zkl">s,u := optim3(T(1, 5, 25, 30, 100, 70, 2, 1, 100, 250, 1, 1000, 2));
prnt(s,u);
 
Line 1,985 ⟶ 2,176:
prnt(s,u);
 
optim3(T(5,6,3,1)) : prnt(_.xplode());</langsyntaxhighlight>
{{out}}
<pre>
2,123

edits