Vogel's approximation method: Difference between revisions

m
m (→‎{{header|Wren}}: Minor tidy)
 
(18 intermediate revisions by 8 users not shown)
Line 74:
* [[Transportation_problem|Transportation problem]]
 
=={{header|11l}}==
{{trans|Python}}
 
<syntaxhighlight lang="11l">V costs = [‘W’ = [‘A’ = 16, ‘B’ = 16, ‘C’ = 13, ‘D’ = 22, ‘E’ = 17],
‘X’ = [‘A’ = 14, ‘B’ = 14, ‘C’ = 13, ‘D’ = 19, ‘E’ = 15],
‘Y’ = [‘A’ = 19, ‘B’ = 19, ‘C’ = 20, ‘D’ = 23, ‘E’ = 50],
‘Z’ = [‘A’ = 50, ‘B’ = 12, ‘C’ = 50, ‘D’ = 15, ‘E’ = 11]]
V demand = [‘A’ = 30, ‘B’ = 20, ‘C’ = 70, ‘D’ = 30, ‘E’ = 60]
V cols = sorted(demand.keys())
V supply = [‘W’ = 50, ‘X’ = 60, ‘Y’ = 50, ‘Z’ = 50]
V res = Dict(costs.keys().map(k -> (k, DefaultDict[Char, Int]())))
[Char = [Char]] g
L(x) supply.keys()
g[x] = sorted(costs[x].keys(), key' g -> :costs[@x][g])
L(x) demand.keys()
g[x] = sorted(costs.keys(), key' g -> :costs[g][@x])
 
L !g.empty
[Char = Int] d
L(x) demand.keys()
d[x] = I g[x].len > 1 {(costs[g[x][1]][x] - costs[g[x][0]][x])} E costs[g[x][0]][x]
[Char = Int] s
L(x) supply.keys()
s[x] = I g[x].len > 1 {(costs[x][g[x][1]] - costs[x][g[x][0]])} E costs[x][g[x][0]]
V f = max(d.keys(), key' n -> @d[n])
V t = max(s.keys(), key' n -> @s[n])
(t, f) = I d[f] > s[t] {(f, g[f][0])} E (g[t][0], t)
V v = min(supply[f], demand[t])
res[f][t] += v
demand[t] -= v
I demand[t] == 0
L(k, n) supply
I n != 0
g[k].remove(t)
g.pop(t)
demand.pop(t)
supply[f] -= v
I supply[f] == 0
L(k, n) demand
I n != 0
g[k].remove(f)
g.pop(f)
supply.pop(f)
 
L(n) cols
print("\t "n, end' ‘ ’)
print()
V cost = 0
L(g) sorted(costs.keys())
print(g" \t", end' ‘ ’)
L(n) cols
V y = res[g][n]
I y != 0
print(y, end' ‘ ’)
cost += y * costs[g][n]
print("\t", end' ‘ ’)
print()
print("\n\nTotal Cost = "cost)</syntaxhighlight>
 
{{out}}
<pre>
A B C D E
W 50
X 20 40
Y 30 20
Z 30 20
 
 
Total Cost = 3130
</pre>
 
=={{header|C}}==
{{trans|Kotlin}}
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <limits.h>
 
Line 184 ⟶ 254:
printf("\nTotal cost = %d\n", total_cost);
return 0;
}</langsyntaxhighlight>
 
{{output}}
Line 198 ⟶ 268:
 
If the program is changed to this (to accomodate the second Ruby example):
<langsyntaxhighlight lang="go">#include <stdio.h>
#include <limits.h>
Line 232 ⟶ 302:
printf("\nTotal cost = %d\n", total_cost);
return 0;
}</langsyntaxhighlight>
 
then the output, which agrees with the Phix output but not with the Ruby output itself is:
Line 245 ⟶ 315:
Total cost = 60748
</pre>
 
=={{header|C++}}==
{{trans|Java}}
<syntaxhighlight lang="cpp">#include <iostream>
#include <numeric>
#include <vector>
 
template <typename T>
std::ostream &operator<<(std::ostream &os, const std::vector<T> &v) {
auto it = v.cbegin();
auto end = v.cend();
 
os << '[';
if (it != end) {
os << *it;
it = std::next(it);
}
while (it != end) {
os << ", " << *it;
it = std::next(it);
}
 
return os << ']';
}
 
std::vector<int> demand = { 30, 20, 70, 30, 60 };
std::vector<int> supply = { 50, 60, 50, 50 };
std::vector<std::vector<int>> costs = {
{16, 16, 13, 22, 17},
{14, 14, 13, 19, 15},
{19, 19, 20, 23, 50},
{50, 12, 50, 15, 11}
};
 
int nRows = supply.size();
int nCols = demand.size();
 
std::vector<bool> rowDone(nRows, false);
std::vector<bool> colDone(nCols, false);
std::vector<std::vector<int>> result(nRows, std::vector<int>(nCols, 0));
 
std::vector<int> diff(int j, int len, bool isRow) {
int min1 = INT_MAX;
int min2 = INT_MAX;
int minP = -1;
for (int i = 0; i < len; i++) {
if (isRow ? colDone[i] : rowDone[i]) {
continue;
}
int c = isRow
? costs[j][i]
: costs[i][j];
if (c < min1) {
min2 = min1;
min1 = c;
minP = i;
} else if (c < min2) {
min2 = c;
}
}
return { min2 - min1, min1, minP };
}
 
std::vector<int> maxPenalty(int len1, int len2, bool isRow) {
int md = INT_MIN;
int pc = -1;
int pm = -1;
int mc = -1;
for (int i = 0; i < len1; i++) {
if (isRow ? rowDone[i] : colDone[i]) {
continue;
}
std::vector<int> res = diff(i, len2, isRow);
if (res[0] > md) {
md = res[0]; // max diff
pm = i; // pos of max diff
mc = res[1]; // min cost
pc = res[2]; // pos of min cost
}
}
return isRow
? std::vector<int> { pm, pc, mc, md }
: std::vector<int>{ pc, pm, mc, md };
}
 
std::vector<int> nextCell() {
auto res1 = maxPenalty(nRows, nCols, true);
auto res2 = maxPenalty(nCols, nRows, false);
 
if (res1[3] == res2[3]) {
return res1[2] < res2[2]
? res1
: res2;
}
return res1[3] > res2[3]
? res2
: res1;
}
 
int main() {
int supplyLeft = std::accumulate(supply.cbegin(), supply.cend(), 0, [](int a, int b) { return a + b; });
int totalCost = 0;
 
while (supplyLeft > 0) {
auto cell = nextCell();
int r = cell[0];
int c = cell[1];
 
int quantity = std::min(demand[c], supply[r]);
 
demand[c] -= quantity;
if (demand[c] == 0) {
colDone[c] = true;
}
 
supply[r] -= quantity;
if (supply[r] == 0) {
rowDone[r] = true;
}
 
result[r][c] = quantity;
supplyLeft -= quantity;
 
totalCost += quantity * costs[r][c];
}
 
for (auto &a : result) {
std::cout << a << '\n';
}
 
std::cout << "Total cost: " << totalCost;
 
return 0;
}</syntaxhighlight>
{{out}}
<pre>[0, 0, 50, 0, 0]
[30, 0, 20, 0, 10]
[0, 20, 0, 30, 0]
[0, 0, 0, 0, 50]
Total cost: 3100</pre>
 
=={{header|D}}==
Strongly typed version (but K is not divided in Task and Contractor types to keep code simpler).
{{trans|Python}}
<langsyntaxhighlight lang="d">void main() {
import std.stdio, std.string, std.algorithm, std.range;
 
Line 263 ⟶ 473:
supply = [W: 50, X: 60, Y: 50, Z: 50];
 
immutableauto cols = demand.keys.sort().release;
auto res = costs.byKey.zip((int[K]).init.repeat).assocArray;
K[][K] g;
Line 328 ⟶ 538:
}
writeln("\nTotal Cost = ", cost);
}</langsyntaxhighlight>
{{out}}
<pre>
<pre> A B C D E
A B C D E
W 50
X 30 20 10
X 20 40
Y 20 30
Y 30 20
Z 50
Z 30 20
W 50
 
Total Cost = 3130</pre>3100
</pre>
 
=={{header|Go}}==
{{trans|Kotlin}}
<langsyntaxhighlight lang="go">package main
 
import (
Line 478 ⟶ 690:
}
fmt.Println("\nTotal cost =", totalCost)
}</langsyntaxhighlight>
 
{{out}}
Line 492 ⟶ 704:
 
If the program is changed as follows to accomodate the second Ruby example:
<langsyntaxhighlight lang="go">package main
 
import (
Line 537 ⟶ 749:
}
fmt.Println("\nTotal cost =", totalCost)
}</langsyntaxhighlight>
 
then the output, which agrees with the C and Phix output but not with the Ruby output itself, is:
Line 555 ⟶ 767:
Implementation:
 
<langsyntaxhighlight Jlang="j">vam=:1 :0
:
exceeding=. 0 <. -&(+/)
Line 582 ⟶ 794:
end.
_1 _1 }. R
)</langsyntaxhighlight>
 
Note that for our penalty we are using the difference between the two smallest relevant costs multiplied by 1 larger than the highest represented cost and we subtract from that multiple the smallest relevant cost. This gives us the tiebreaker mechanism currently specified for this task.
Line 588 ⟶ 800:
Task example:
 
<langsyntaxhighlight Jlang="j">demand=: 30 20 70 30 60
src=: 50 60 50 50
cost=: 16 16 13 22 17,14 14 13 19 15,19 19 20 23 50,:50 12 50 15 11
Line 596 ⟶ 808:
30 0 20 0 10
0 20 0 30 0
0 0 0 0 50</langsyntaxhighlight>
 
=={{header|Java}}==
{{works with|Java|8}}
<langsyntaxhighlight lang="java">import java.util.Arrays;
import static java.util.Arrays.stream;
import java.util.concurrent.*;
Line 696 ⟶ 908:
return isRow ? new int[]{pm, pc, mc, md} : new int[]{pc, pm, mc, md};
}
}</langsyntaxhighlight>
 
<pre>[0, 0, 50, 0, 0]
Line 714 ⟶ 926:
 
<code>Resource</code> stores the currently available quantity of a given supply or demand as well as its penalty, cost, and some meta-data. <code>isavailable</code> indicates whether any of the given resource remains. <code>isless</code> is designed to make the currently most usable resource appear as a maximum compared to other resources.
<syntaxhighlight lang="julia">
<lang Julia>
immutable TProblem{T<:Integer,U<:String}
sd::Array{Array{T,1},1}
Line 763 ⟶ 975:
isavailable(r::Resource) = 0 < r.quant
Base.isless(a::Resource, b::Resource) = a.p < b.p || (a.p == b.p && b.q < a.q)
</syntaxhighlight>
</lang>
 
'''Functions'''
Line 770 ⟶ 982:
 
<code>vogel</code> implements Vogel's approximation method on a <code>TProblem</code>. It is somewhat straightforward, given the types and <code>penalize!</code>.
<syntaxhighlight lang="julia">
<lang Julia>
function penalize!{T<:Integer,U<:String}(sd::Array{Array{Resource{T},1},1},
tp::TProblem{T,U})
Line 818 ⟶ 1,030:
return sol
end
</syntaxhighlight>
</lang>
 
'''Main'''
<langsyntaxhighlight Julialang="julia">using Printf
 
sup = [50, 60, 50, 50]
Line 850 ⟶ 1,062:
end
println("The total cost is: ", cost)
</syntaxhighlight>
</lang>
 
{{out}}
Line 865 ⟶ 1,077:
=={{header|Kotlin}}==
{{trans|Java}}
<langsyntaxhighlight lang="scala">// version 1.1.3
 
val supply = intArrayOf(50, 60, 50, 50)
Line 954 ⟶ 1,166:
}
println("\nTotal Cost = $totalCost")
}</langsyntaxhighlight>
 
{{out}}
Line 967 ⟶ 1,179:
</pre>
 
=={{header|Perl 6Lua}}==
{{trans|Kotlin}}
{{works with|Rakudo|2019.03.1}}
<syntaxhighlight lang="lua">function initArray(n,v)
{{trans|Sidef}}
local tbl = {}
for i=1,n do
table.insert(tbl,v)
end
return tbl
end
 
function initArray2(m,n,v)
<lang perl6>my %costs =
:W{:16A,local :16B,tbl :13C,= :22D, :17E{},
for i=1,m do
:X{:14A, :14B, :13C, :19D, :15E},
table.insert(tbl,initArray(n,v))
:Y{:19A, :19B, :20C, :23D, :50E},
end
:Z{:50A, :12B, :50C, :15D, :11E};
return tbl
end
 
my %demandsupply = :30A, :20B{50, :70C60, :30D50, :60E;50}
my %supplydemand = :50W{30, 20, :60X70, :50Y30, :50Z;60}
costs = {
{16, 16, 13, 22, 17},
{14, 14, 13, 19, 15},
{19, 19, 20, 23, 50},
{50, 12, 50, 15, 11}
}
 
nRows = table.getn(supply)
my @cols = %demand.keys.sort;
nCols = table.getn(demand)
 
rowDone = initArray(nRows, false)
my %res;
colDone = initArray(nCols, false)
my %g = (|%supply.keys.map: -> $x { $x => [%costs{$x}.sort(*.value)».key]}),
results = initArray2(nRows, nCols, 0)
(|%demand.keys.map: -> $x { $x => [%costs.keys.sort({%costs{$_}{$x}})]});
 
function diff(j,le,isRow)
while (+%g) {
local min1 = 100000000
my @d = %demand.keys.map: -> $x
local min2 = min1
{[$x, my $z = %costs{%g{$x}[0]}{$x},%g{$x}[1] ?? %costs{%g{$x}[1]}{$x} - $z !! $z]}
local minP = -1
for i=1,le do
local done = false
if isRow then
done = colDone[i]
else
done = rowDone[i]
end
if not done then
local c = 0
if isRow then
c = costs[j][i]
else
c = costs[i][j]
end
if c < min1 then
min2 = min1
min1 = c
minP = i
elseif c < min2 then
min2 = c
end
end
end
return {min2 - min1, min1, minP}
end
 
function maxPenalty(len1,len2,isRow)
my @s = %supply.keys.map: -> $x
local md = -100000000
{[$x, my $z = %costs{$x}{%g{$x}[0]},%g{$x}[1] ?? %costs{$x}{%g{$x}[1]} - $z !! $z]}
local pc = -1
local pm = -1
local mc = -1
 
for i=1,len1 do
@d = |@d.grep({ (.[2] == max @d».[2]) }).&min: :by(*.[1]);
local done = false
@s = |@s.grep({ (.[2] == max @s».[2]) }).&min: :by(*.[1]);
if isRow then
done = rowDone[i]
else
done = colDone[i]
end
if not done then
local res = diff(i, len2, isRow)
if res[1] > md then
md = res[1] -- max diff
pm = i -- pos of max diff
mc = res[2] -- min cost
pc = res[3] -- pos of min cost
end
end
end
 
if isRow then
my ($t, $f) = @d[2] == @s[2] ?? (@s[1],@d[1]) !! (@d[2],@s[2]);
return {pm, pc, mc, md}
my ($d, $s) = $t > $f ?? (@d[0],%g{@d[0]}[0]) !! (%g{@s[0]}[0], @s[0]);
else
return {pc, pm, mc, md}
end
end
 
function nextCell()
my $v = %supply{$s} min %demand{$d};
local res1 = maxPenalty(nRows, nCols, true)
local res2 = maxPenalty(nCols, nRows, false)
if res1[4] == res2[4] then
if res1[3] < res2[3] then
return res1
else
return res2
end
else
if res1[4] > res2[4] then
return res2
else
return res1
end
end
end
 
function main()
%res{$s}{$d} += $v;
%demand{$d}local supplyLeft -= $v;0
for i,v in pairs(supply) do
supplyLeft = supplyLeft + v
end
local totalCost = 0
while supplyLeft > 0 do
local cell = nextCell()
local r = cell[1]
local c = cell[2]
local q = math.min(demand[c], supply[r])
demand[c] = demand[c] - q
if demand[c] == 0 then
colDone[c] = true
end
supply[r] = supply[r] - q
if supply[r] == 0 then
rowDone[r] = true
end
results[r][c] = q
supplyLeft = supplyLeft - q
totalCost = totalCost + q * costs[r][c]
end
 
print(" A B C D E")
if (%demand{$d} == 0) {
local labels = {'W','X','Y','Z'}
%supply.grep( *.value != 0 )».key.map: -> $v
for i,r in pairs(results) do
{ %g{$v}.splice((%g{$v}.first: * eq $d, :k),1) };
%g{$d}:delete;io.write(labels[i])
%demand{$d}:delete;for j,c in pairs(r) do
io.write(string.format(" %2d", c))
}
end
print()
end
print("Total Cost = " .. totalCost)
end
 
main()</syntaxhighlight>
%supply{$s} -= $v;
{{out}}
<pre> A B C D E
W 0 0 50 0 0
X 30 0 20 0 10
Y 0 20 0 30 0
Z 0 0 0 0 50
Total Cost = 3100</pre>
 
=={{header|Nim}}==
if (%supply{$s} == 0) {
{{trans|Kotlin}}
%demand.grep( *.value != 0 )».key.map: -> $v
<syntaxhighlight lang="nim">import math, sequtils, strutils
{ %g{$v}.splice((%g{$v}.first: * eq $s, :k),1) };
%g{$s}:delete;
%supply{$s}:delete;
}
}
 
var
say join "\t", flat '', @cols;
supply = [50, 60, 50, 50]
my $total;
demand = [30, 20, 70, 30, 60]
for %costs.keys.sort -> $g {
 
print "$g\t";
let
for @cols -> $col {
costs = [[16, 16, 13, 22, 17],
print %res{$g}{$col} // '-', "\t";
$total += (%res{$g}{$col} //[14, 0)14, *13, %costs{$g}{$col};19, 15],
[19, 19, 20, 23, 50],
[50, 12, 50, 15, 11]]
 
nRows = supply.len
nCols = demand.len
 
var
rowDone = newSeq[bool](nRows)
colDone = newSeq[bool](nCols)
results = newSeqWith(nRows, newSeq[int](nCols))
 
 
proc diff(j, len: int; isRow: bool): array[3, int] =
var min1, min2 = int.high
var minP = -1
for i in 0..<len:
let done = if isRow: colDone[i] else: rowDone[i]
if done: continue
let c = if isRow: costs[j][i] else: costs[i][j]
if c < min1:
min2 = min1
min1 = c
minP = i
elif c < min2:
min2 = c
result = [min2 - min1, min1, minP]
 
 
proc maxPenalty(len1, len2: int; isRow: bool): array[4, int] =
var md = int.low
var pc, pm, mc = -1
for i in 0..<len1:
let done = if isRow: rowDone[i] else: colDone[i]
if done: continue
let res = diff(i, len2, isRow)
if res[0] > md:
md = res[0] # max diff
pm = i # pos of max diff
mc = res[1] # min cost
pc = res[2] # pos of min cost
result = if isRow: [pm, pc, mc, md] else: [pc, pm, mc, md]
 
 
proc nextCell(): array[4, int] =
let res1 = maxPenalty(nRows, nCols, true)
let res2 = maxPenalty(nCols, nRows, false)
if res1[3] == res2[3]:
return if res1[2] < res2[2]: res1 else: res2
result = if res1[3] > res2[3]: res2 else: res1
 
 
when isMainModule:
 
var supplyLeft = sum(supply)
var totalCost = 0
 
while supplyLeft > 0:
let cell = nextCell()
let r = cell[0]
let c = cell[1]
let q = min(demand[c], supply[r])
dec demand[c], q
if demand[c] == 0: colDone[c] = true
dec supply[r], q
if supply[r] == 0: rowDone[r] = true
results[r][c] = q
dec supplyLeft, q
inc totalCost, q * costs[r][c]
 
echo " A B C D E"
for i, result in results:
stdout.write chr(i + ord('W'))
for item in result:
stdout.write " ", ($item).align(2)
echo()
echo "\nTotal cost = ", totalCost</syntaxhighlight>
 
{{out}}
<pre> A B C D E
W 0 0 50 0 0
X 30 0 20 0 10
Y 0 20 0 30 0
Z 0 0 0 0 50
 
Total cost = 3100</pre>
 
=={{header|Perl}}==
<syntaxhighlight lang="perl">#!/usr/bin/perl
 
use strict; # https://rosettacode.org/wiki/Vogel%27s_approximation_method
use warnings;
use List::AllUtils qw( max_by nsort_by min );
 
my $data = <<END;
A=30 B=20 C=70 D=30 E=60
W=50 X=60 Y=50 Z=50
AW=16 BW=16 CW=13 DW=22 EW=17
AX=14 BX=14 CX=13 DX=19 EX=15
AY=19 BY=19 CY=20 DY=23 EY=50
AZ=50 BZ=12 CZ=50 DZ=15 EZ=11
END
my $table = sprintf +('%4s' x 6 . "\n") x 5,
map {my $t = $_; map "$_$t", '', 'A' .. 'E' } '' , 'W' .. 'Z';
 
my ($cost, %assign) = (0);
while( $data =~ /\b\w=\d/ )
{
my @penalty;
for ( $data =~ /\b(\w)=\d/g )
{
my @all = map /(\d+)/, nsort_by { /\d+/ && $& }
grep { my ($t, $c) = /(.)(.)=/; $data =~ /\b$c=\d/ and $data =~ /\b$t=\d/ }
$data =~ /$_\w=\d+|\w$_=\d+/g;
push @penalty, [ $_, ($all[1] // 0) - $all[0] ];
}
my $rc = (max_by { $_->[1] } nsort_by
print "\n";
{ my $x = $_->[0]; $data =~ /(?:$x\w|\w$x)=(\d+)/ && $1 } @penalty)->[0];
}
my @lowest = nsort_by { /\d+/ && $& }
say "\nTotal cost: $total";</lang>
grep { my ($t, $c) = /(.)(.)=/; $data =~ /\b$c=\d/ and $data =~ /\b$t=\d/ }
$data =~ /$rc\w=\d+|\w$rc=\d+/g;
my ($t, $c) = $lowest[0] =~ /(.)(.)/;
my $allocate = min $data =~ /\b[$t$c]=(\d+)/g;
$table =~ s/$t$c/ sprintf "%2d", $allocate/e;
$cost += $data =~ /$t$c=(\d+)/ && $1 * $allocate;
$data =~ s/\b$_=\K\d+/ $& - $allocate || '' /e for $t, $c;
}
print "cost $cost\n\n", $table =~ s/[A-Z]{2}/--/gr;</syntaxhighlight>
{{out}}
<pre> A B C D E
cost 3100
W - - 50 - -
X 30 - 20 - 10
Y - 20 - 30 -
Z - - - - 50
 
A B C D E
Total cost: 3100</pre>
W -- -- 50 -- --
X 30 -- 20 -- 10
Y -- 20 -- 30 --
Z -- -- -- -- 50
</pre>
 
=={{header|Phix}}==
Line 1,045 ⟶ 1,490:
{{trans|YaBasic}}
{{trans|Go}}
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>sequence supply = {50,60,50,50},
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
demand = {30,20,70,30,60},
<span style="color: #004080;">sequence</span> <span style="color: #000000;">supply</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">50</span><span style="color: #0000FF;">,</span><span style="color: #000000;">60</span><span style="color: #0000FF;">,</span><span style="color: #000000;">50</span><span style="color: #0000FF;">,</span><span style="color: #000000;">50</span><span style="color: #0000FF;">},</span>
costs = {{16,16,13,22,17},
<span style="color: #000000;">demand</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">30</span><span style="color: #0000FF;">,</span><span style="color: #000000;">20</span><span style="color: #0000FF;">,</span><span style="color: #000000;">70</span><span style="color: #0000FF;">,</span><span style="color: #000000;">30</span><span style="color: #0000FF;">,</span><span style="color: #000000;">60</span><span style="color: #0000FF;">},</span>
{14,14,13,19,15},
<span style="color: #000000;">costs</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{{</span><span style="color: #000000;">16</span><span style="color: #0000FF;">,</span><span style="color: #000000;">16</span><span style="color: #0000FF;">,</span><span style="color: #000000;">13</span><span style="color: #0000FF;">,</span><span style="color: #000000;">22</span><span style="color: #0000FF;">,</span><span style="color: #000000;">17</span><span style="color: #0000FF;">},</span>
{19,19,20,23,50},
<span style="color: #0000FF;">{</span><span style="color: #000000;">14</span><span style="color: #0000FF;">,</span><span style="color: #000000;">14</span><span style="color: #0000FF;">,</span><span style="color: #000000;">13</span><span style="color: #0000FF;">,</span><span style="color: #000000;">19</span><span style="color: #0000FF;">,</span><span style="color: #000000;">15</span><span style="color: #0000FF;">},</span>
{50,12,50,15,11}}
<span style="color: #0000FF;">{</span><span style="color: #000000;">19</span><span style="color: #0000FF;">,</span><span style="color: #000000;">19</span><span style="color: #0000FF;">,</span><span style="color: #000000;">20</span><span style="color: #0000FF;">,</span><span style="color: #000000;">23</span><span style="color: #0000FF;">,</span><span style="color: #000000;">50</span><span style="color: #0000FF;">},</span>
 
<span style="color: #0000FF;">{</span><span style="color: #000000;">50</span><span style="color: #0000FF;">,</span><span style="color: #000000;">12</span><span style="color: #0000FF;">,</span><span style="color: #000000;">50</span><span style="color: #0000FF;">,</span><span style="color: #000000;">15</span><span style="color: #0000FF;">,</span><span style="color: #000000;">11</span><span style="color: #0000FF;">}}</span>
sequence row_done = repeat(false,length(supply)),
col_done = repeat(false,length(demand))
<span style="color: #004080;">sequence</span> <span style="color: #000000;">row_done</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #004600;">false</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">supply</span><span style="color: #0000FF;">)),</span>
 
<span style="color: #000000;">col_done</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #004600;">false</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">demand</span><span style="color: #0000FF;">))</span>
function diff(integer j, leng, bool is_row)
integer min1 = #3FFFFFFF, min2 = min1, min_p = -1
<span style="color: #008080;">function</span> <span style="color: #000000;">diff</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">leng</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">bool</span> <span style="color: #000000;">is_row</span><span style="color: #0000FF;">)</span>
for i=1 to leng do
<span style="color: #004080;">integer</span> <span style="color: #000000;">min1</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">#3FFFFFFF</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">min2</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">min1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">min_p</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span>
if not iff(is_row?col_done:row_done)[i] then
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">leng</span> <span style="color: #008080;">do</span>
integer c = iff(is_row?costs[j,i]:costs[i,j])
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">is_row</span><span style="color: #0000FF;">?</span><span style="color: #000000;">col_done</span><span style="color: #0000FF;">:</span><span style="color: #000000;">row_done</span><span style="color: #0000FF;">)[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">then</span>
if c<min1 then
<span style="color: #004080;">integer</span> <span style="color: #000000;">c</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">is_row</span><span style="color: #0000FF;">?</span><span style="color: #000000;">costs</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">,</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]:</span><span style="color: #000000;">costs</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">,</span><span style="color: #000000;">j</span><span style="color: #0000FF;">])</span>
min2 = min1
<span style="color: #008080;">if</span> <span style="color: #000000;">c</span><span style="color: #0000FF;"><</span><span style="color: #000000;">min1</span> <span style="color: #008080;">then</span>
min1 = c
<span style="color: #000000;">min2</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">min1</span>
min_p = i
<span style="color: #000000;">min1</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">c</span>
elsif c<min2 then
<span style="color: #000000;">min_p</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">i</span>
min2 = c
<span style="color: #008080;">elsif</span> <span style="color: #000000;">c</span><span style="color: #0000FF;"><</span><span style="color: #000000;">min2</span> <span style="color: #008080;">then</span>
end if
<span style="color: #000000;">min2</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">c</span>
end if
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
return {min2-min1,min1,min_p,j}
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end function
<span style="color: #008080;">return</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">min2</span><span style="color: #0000FF;">-</span><span style="color: #000000;">min1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">min1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">min_p</span><span style="color: #0000FF;">,</span><span style="color: #000000;">j</span><span style="color: #0000FF;">}</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
function max_penalty(integer len1, len2, bool is_row)
integer pc = -1, pm = -1, mc = -1, md = -#3FFFFFFF
<span style="color: #008080;">function</span> <span style="color: #000000;">max_penalty</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">len1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">len2</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">bool</span> <span style="color: #000000;">is_row</span><span style="color: #0000FF;">)</span>
for i=1 to len1 do
<span style="color: #004080;">integer</span> <span style="color: #000000;">pc</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">pm</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">mc</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">md</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">#3FFFFFFF</span>
if not iff(is_row?row_done:col_done)[i] then
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">len1</span> <span style="color: #008080;">do</span>
sequence res2 = diff(i, len2, is_row)
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">is_row</span><span style="color: #0000FF;">?</span><span style="color: #000000;">row_done</span><span style="color: #0000FF;">:</span><span style="color: #000000;">col_done</span><span style="color: #0000FF;">)[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">then</span>
if res2[1]>md then
<span style="color: #004080;">sequence</span> <span style="color: #000000;">res2</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">diff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">len2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">is_row</span><span style="color: #0000FF;">)</span>
{md,mc,pc,pm} = res2
<span style="color: #008080;">if</span> <span style="color: #000000;">res2</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]></span><span style="color: #000000;">md</span> <span style="color: #008080;">then</span>
end if
<span style="color: #0000FF;">{</span><span style="color: #000000;">md</span><span style="color: #0000FF;">,</span><span style="color: #000000;">mc</span><span style="color: #0000FF;">,</span><span style="color: #000000;">pc</span><span style="color: #0000FF;">,</span><span style="color: #000000;">pm</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">res2</span>
end if
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
return {md,mc}&iff(is_row?{pm,pc}:{pc,pm})
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end function
<span style="color: #008080;">return</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">md</span><span style="color: #0000FF;">,</span><span style="color: #000000;">mc</span><span style="color: #0000FF;">}&</span><span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">is_row</span><span style="color: #0000FF;">?{</span><span style="color: #000000;">pm</span><span style="color: #0000FF;">,</span><span style="color: #000000;">pc</span><span style="color: #0000FF;">}:{</span><span style="color: #000000;">pc</span><span style="color: #0000FF;">,</span><span style="color: #000000;">pm</span><span style="color: #0000FF;">})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
integer supply_left = sum(supply),
total_cost = 0
<span style="color: #004080;">integer</span> <span style="color: #000000;">supply_left</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sum</span><span style="color: #0000FF;">(</span><span style="color: #000000;">supply</span><span style="color: #0000FF;">),</span>
 
<span style="color: #000000;">total_cost</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
sequence results = repeat(repeat(0,length(demand)),length(supply))
<span style="color: #004080;">sequence</span> <span style="color: #000000;">results</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">demand</span><span style="color: #0000FF;">)),</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">supply</span><span style="color: #0000FF;">))</span>
while supply_left>0 do
sequence cell = min(max_penalty(length(supply), length(demand), true),
<span style="color: #008080;">while</span> <span style="color: #000000;">supply_left</span><span style="color: #0000FF;">></span><span style="color: #000000;">0</span> <span style="color: #008080;">do</span>
max_penalty(length(demand), length(supply), false))
<span style="color: #004080;">sequence</span> <span style="color: #000000;">cell</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">min</span><span style="color: #0000FF;">(</span><span style="color: #000000;">max_penalty</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">supply</span><span style="color: #0000FF;">),</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">demand</span><span style="color: #0000FF;">),</span> <span style="color: #004600;">true</span><span style="color: #0000FF;">),</span>
integer {{},{},r,c} = cell,
<span style="color: #000000;">max_penalty</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">demand</span><span style="color: #0000FF;">),</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">supply</span><span style="color: #0000FF;">),</span> <span style="color: #004600;">false</span><span style="color: #0000FF;">))</span>
q = min(demand[c], supply[r])
<span style="color: #004080;">integer</span> <span style="color: #0000FF;">{{},{},</span><span style="color: #000000;">r</span><span style="color: #0000FF;">,</span><span style="color: #000000;">c</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">cell</span><span style="color: #0000FF;">,</span>
demand[c] -= q
<span style="color: #000000;">q</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">min</span><span style="color: #0000FF;">(</span><span style="color: #000000;">demand</span><span style="color: #0000FF;">[</span><span style="color: #000000;">c</span><span style="color: #0000FF;">],</span> <span style="color: #000000;">supply</span><span style="color: #0000FF;">[</span><span style="color: #000000;">r</span><span style="color: #0000FF;">])</span>
col_done[c] = (demand[c]==0)
<span style="color: #000000;">demand</span><span style="color: #0000FF;">[</span><span style="color: #000000;">c</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">q</span>
supply[r] -= q
<span style="color: #000000;">col_done</span><span style="color: #0000FF;">[</span><span style="color: #000000;">c</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">demand</span><span style="color: #0000FF;">[</span><span style="color: #000000;">c</span><span style="color: #0000FF;">]==</span><span style="color: #000000;">0</span><span style="color: #0000FF;">)</span>
row_done[r] = (supply[r]==0)
<span style="color: #000000;">supply</span><span style="color: #0000FF;">[</span><span style="color: #000000;">r</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">q</span>
results[r, c] = q
<span style="color: #000000;">row_done</span><span style="color: #0000FF;">[</span><span style="color: #000000;">r</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">supply</span><span style="color: #0000FF;">[</span><span style="color: #000000;">r</span><span style="color: #0000FF;">]==</span><span style="color: #000000;">0</span><span style="color: #0000FF;">)</span>
supply_left -= q
<span style="color: #000000;">results</span><span style="color: #0000FF;">[</span><span style="color: #000000;">r</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">q</span>
total_cost += q * costs[r, c]
<span style="color: #000000;">supply_left</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">q</span>
end while
<span style="color: #000000;">total_cost</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">q</span> <span style="color: #0000FF;">*</span> <span style="color: #000000;">costs</span><span style="color: #0000FF;">[</span><span style="color: #000000;">r</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
printf(1," A B C D E\n")
for i=1 to length(supply) do
<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;">" A B C D E\n"</span><span style="color: #0000FF;">)</span>
printf(1,"%c ",'Z'-length(supply)+i)
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">supply</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
for j=1 to length(demand) do
<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;">"%c "</span><span style="color: #0000FF;">,</span><span style="color: #008000;">'Z'</span><span style="color: #0000FF;">-</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">supply</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">i</span><span style="color: #0000FF;">)</span>
printf(1,"%4d",results[i,j])
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">demand</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
end for
<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;">"%4d"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">results</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">,</span><span style="color: #000000;">j</span><span style="color: #0000FF;">])</span>
printf(1,"\n")
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end for
<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;">"\n"</span><span style="color: #0000FF;">)</span>
printf(1,"\nTotal cost = %d\n", total_cost)</lang>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<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;">"\nTotal cost = %d\n"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">total_cost</span><span style="color: #0000FF;">)</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
Line 1,124 ⟶ 1,572:
</pre>
Using the sample from Ruby:
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>sequence supply = {461, 277, 356, 488, 393},
<span style="color: #004080;">sequence</span> <span style="color: #000000;">supply</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">461</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">277</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">356</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">488</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">393</span><span style="color: #0000FF;">},</span>
demand = {278, 60, 461, 116, 1060},
<span style="color: #000000;">demand</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">278</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">60</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">461</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">116</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1060</span><span style="color: #0000FF;">},</span>
costs = {{46, 74, 9, 28, 99},
<span style="color: #000000;">costs</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{{</span><span style="color: #000000;">46</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">74</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">28</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">99</span><span style="color: #0000FF;">},</span>
{12, 75, 6, 36, 48},
<span style="color: #0000FF;">{</span><span style="color: #000000;">12</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">75</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">6</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">36</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">48</span><span style="color: #0000FF;">},</span>
{35, 199, 4, 5, 71},
<span style="color: #0000FF;">{</span><span style="color: #000000;">35</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">199</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">4</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">5</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">71</span><span style="color: #0000FF;">},</span>
{61, 81, 44, 88, 9},
<span style="color: #0000FF;">{</span><span style="color: #000000;">61</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">81</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">44</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">88</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9</span><span style="color: #0000FF;">},</span>
{85, 60, 14, 25, 79}}</lang>
<span style="color: #0000FF;">{</span><span style="color: #000000;">85</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">60</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">14</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">25</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">79</span><span style="color: #0000FF;">}}</span>
<!--</syntaxhighlight>-->
{{Out}}
Note this agrees with C and Go but not Ruby
Line 1,146 ⟶ 1,596:
=={{header|Python}}==
{{trans|Ruby}}
<langsyntaxhighlight lang="python">from collections import defaultdict
 
costs = {'W': {'A': 16, 'B': 16, 'C': 13, 'D': 22, 'E': 17},
Line 1,202 ⟶ 1,652:
print "\t",
print
print "\n\nTotal Cost = ", cost</langsyntaxhighlight>
{{out}}
<pre> A B C D E
Line 1,220 ⟶ 1,670:
somehow at the same total cost!
 
<langsyntaxhighlight lang="racket">#lang racket
(define-values (1st 2nd 3rd) (values first second third))
 
Line 1,322 ⟶ 1,772:
(DEMAND (hash 'A 30 'B 20 'C 70 'D 30 'E 60))
(SUPPLY (hash 'W 50 'X 60 'Y 50 'Z 50)))
(displayln (describe-VAM-solution COSTS DEMAND (VAM COSTS SUPPLY DEMAND))))</langsyntaxhighlight>
 
{{out}}
Line 1,333 ⟶ 1,783:
 
Total Cost: 3100</pre>
 
=={{header|Raku}}==
(formerly Perl 6)
{{works with|Rakudo|2019.03.1}}
{{trans|Sidef}}
 
<syntaxhighlight lang="raku" line>my %costs =
:W{:16A, :16B, :13C, :22D, :17E},
:X{:14A, :14B, :13C, :19D, :15E},
:Y{:19A, :19B, :20C, :23D, :50E},
:Z{:50A, :12B, :50C, :15D, :11E};
 
my %demand = :30A, :20B, :70C, :30D, :60E;
my %supply = :50W, :60X, :50Y, :50Z;
 
my @cols = %demand.keys.sort;
 
my %res;
my %g = (|%supply.keys.map: -> $x { $x => [%costs{$x}.sort(*.value)».key]}),
(|%demand.keys.map: -> $x { $x => [%costs.keys.sort({%costs{$_}{$x}})]});
 
while (+%g) {
my @d = %demand.keys.map: -> $x
{[$x, my $z = %costs{%g{$x}[0]}{$x},%g{$x}[1] ?? %costs{%g{$x}[1]}{$x} - $z !! $z]}
 
my @s = %supply.keys.map: -> $x
{[$x, my $z = %costs{$x}{%g{$x}[0]},%g{$x}[1] ?? %costs{$x}{%g{$x}[1]} - $z !! $z]}
 
@d = |@d.grep({ (.[2] == max @d».[2]) }).&min: :by(*.[1]);
@s = |@s.grep({ (.[2] == max @s».[2]) }).&min: :by(*.[1]);
 
my ($t, $f) = @d[2] == @s[2] ?? (@s[1],@d[1]) !! (@d[2],@s[2]);
my ($d, $s) = $t > $f ?? (@d[0],%g{@d[0]}[0]) !! (%g{@s[0]}[0], @s[0]);
 
my $v = %supply{$s} min %demand{$d};
 
%res{$s}{$d} += $v;
%demand{$d} -= $v;
 
if (%demand{$d} == 0) {
%supply.grep( *.value != 0 )».key.map: -> $v
{ %g{$v}.splice((%g{$v}.first: * eq $d, :k),1) };
%g{$d}:delete;
%demand{$d}:delete;
}
 
%supply{$s} -= $v;
 
if (%supply{$s} == 0) {
%demand.grep( *.value != 0 )».key.map: -> $v
{ %g{$v}.splice((%g{$v}.first: * eq $s, :k),1) };
%g{$s}:delete;
%supply{$s}:delete;
}
}
 
say join "\t", flat '', @cols;
my $total;
for %costs.keys.sort -> $g {
print "$g\t";
for @cols -> $col {
print %res{$g}{$col} // '-', "\t";
$total += (%res{$g}{$col} // 0) * %costs{$g}{$col};
}
print "\n";
}
say "\nTotal cost: $total";</syntaxhighlight>
{{out}}
<pre> A B C D E
W - - 50 - -
X 30 - 20 - 10
Y - 20 - 30 -
Z - - - - 50
 
Total cost: 3100</pre>
 
=={{header|REXX}}==
{{trans|java}}
===Vogel's Approximation===
<syntaxhighlight lang="rexx">/* REXX ***************************************************************
* Solve the Transportation Problem using Vogel's Approximation
Default Input
2 3 # of sources / # of demands
25 35 sources
20 30 10 demands
3 5 7 cost matrix <
3 2 5
* 20201210 support no input file -courtesy GS
* Note: correctness of input is not checked
* 20210102 restored Vogel's Approximation and added Optimization
* 20210103 eliminated debug code
**********************************************************************/
Signal On Halt
Signal On Novalue
Signal On Syntax
 
Parse Arg fid
If fid='' Then
fid='input1.txt'
Call init
m.=0
Do Forever
dmax.=0
dmax=0
Do r=1 To rr
dr.r=''
Do c=1 To cc
If cost.r.c<>'*' Then
dr.r=dr.r cost.r.c
End
dr.r=words(dr.r) dr.r
dr.r=diff(dr.r)
If dr.r>dmax Then Do; dmax=dr.r; dmax.0='R'; dmax.1=r; dmax.2=dr.r; End
End
Do c=1 To cc
dc.c=''
Do r=1 To rr
If cost.r.c<>'*' Then
dc.c=dc.c cost.r.c
End
dc.c=words(dc.c) dc.c
dc.c=diff(dc.c)
If dc.c>dmax Then Do; dmax=dc.c; dmax.0='C'; dmax.1=c; dmax.2=dc.c; End
End
cmin=999
Select
When dmax.0='R' Then Do
r=dmax.1
Do c=1 To cc
If cost.r.c<>'*' &,
cost.r.c<cmin Then Do
cmin=cost.r.c
cx=c
End
End
Call allocate r cx
End
When dmax.0='C' Then Do
c=dmax.1
Do r=1 To rr
If cost.r.c<>'*' &,
cost.r.c<cmin Then Do
cmin=cost.r.c
rx=r
End
End
Call allocate rx c
End
Otherwise
Leave
End
End
 
Do r=1 To rr
Do c=1 To cc
If cost.r.c<>'*' Then Do
Call allocate r c
cost.r.c='*'
End
End
End
 
Call show_alloc 'Vogel''s Approximation'
 
Do r=1 To rr
Do c=1 To cc
cost.r.c=word(matrix.r.c,3) /* restore cost.*.* */
End
End
 
Call steppingstone
Exit
 
/**********************************************************************
* Subroutines for Vogel's Approximation
**********************************************************************/
 
init:
If lines(fid)=0 Then Do
Say 'Input file not specified or not found. Using default input instead.'
fid='Default input'
in.1=sourceline(4)
Parse Var in.1 numSources .
Do i=2 To numSources+3
in.i=sourceline(i+3)
End
End
Else Do
Do i=1 By 1 while lines(fid)>0
in.i=linein(fid)
End
End
Parse Var in.1 numSources numDestinations . 1 rr cc .
source.=0
demand.=0
source_sum=0
Do i=1 To numSources
Parse Var in.2 source.i in.2
ss.i=source.i
source_in.i=source.i
source_sum=source_sum+source.i
End
l=linein(fid)
demand_sum=0
Do i=1 To numDestinations
Parse Var in.3 demand.i in.3
dd.i=demand.i
demand_in.i=demand.i
demand_sum=demand_sum+demand.i
End
Do i=1 To numSources
j=i+3
l=in.j
Do j=1 To numDestinations
Parse Var l cost.i.j l
End
End
Do i=1 To numSources
ol=format(source.i,3)
Do j=1 To numDestinations
ol=ol format(cost.i.j,4)
End
End
ol=' '
Do j=1 To numDestinations
ol=ol format(demand.j,4)
End
 
Select
When source_sum=demand_sum Then Nop /* balanced */
When source_sum>demand_sum Then Do /* unbalanced - add dummy demand */
Say 'This is an unbalanced case (sources exceed demands). We add a dummy consumer.'
cc=cc+1
demand.cc=source_sum-demand_sum
demand_in.cc=demand.cc
dd.cc=demand.cc
Do r=1 To rr
cost.r.cc=0
End
End
Otherwise /* demand_sum>source_sum */ Do /* unbalanced - add dummy source */
Say 'This is an unbalanced case (demands exceed sources). We add a dummy source.'
rr=rr+1
source.rr=demand_sum-source_sum
source_in.rr=source.rr
ss.rr=source.rr
Do c=1 To cc
cost.rr.c=0
End
End
End
 
Say 'Sources / Demands / Cost'
ol=' '
Do c=1 To cc
ol=ol format(demand.c,3)
End
Say ol
 
Do r=1 To rr
ol=format(source.r,4)
Do c=1 To cc
ol=ol format(cost.r.c,3)
matrix.r.c=r c cost.r.c 0
End
Say ol
End
Return
 
allocate: Procedure Expose m. source. demand. cost. rr cc matrix.
Parse Arg r c
sh=min(source.r,demand.c)
source.r=source.r-sh
demand.c=demand.c-sh
m.r.c=sh
matrix.r.c=subword(matrix.r.c,1,3) sh
If source.r=0 Then Do
Do c=1 To cc
cost.r.c='*'
End
End
If demand.c=0 Then Do
Do r=1 To rr
cost.r.c='*'
End
End
Return
 
diff: Procedure
Parse Value arg(1) With n list
If n<2 Then Return 0
list=wordsort(list)
Return word(list,2)-word(list,1)
 
wordsort: Procedure
/**********************************************************************
* Sort the list of words supplied as argument. Return the sorted list
**********************************************************************/
Parse Arg wl
wa.=''
wa.0=0
Do While wl<>''
Parse Var wl w wl
Do i=1 To wa.0
If wa.i>w Then Leave
End
If i<=wa.0 Then Do
Do j=wa.0 To i By -1
ii=j+1
wa.ii=wa.j
End
End
wa.i=w
wa.0=wa.0+1
End
swl=''
Do i=1 To wa.0
swl=swl wa.i
End
/* Say swl */
Return strip(swl)
 
show_alloc: Procedure Expose matrix. rr cc demand_in. source_in.
Parse Arg header
If header='' Then
Return
Say ''
Say header
total=0
ol=' '
Do c=1 to cc
ol=ol format(demand_in.c,3)
End
Say ol
as=''
Do r=1 to rr
ol=format(source_in.r,4)
a=word(matrix.r.1,4)
If a=0.0000000001 Then a=0
If a>0 Then
ol=ol format(a,3)
Else
ol=ol ' - '
total=total+word(matrix.r.1,4)*word(matrix.r.1,3)
Do c=2 To cc
a=word(matrix.r.c,4)
If a=0.0000000001 Then a=0
If a>0 Then
ol=ol format(a,3)
Else
ol=ol ' - '
total=total+word(matrix.r.c,4)*word(matrix.r.c,3)
as=as a
End
Say ol
End
Say 'Total costs:' format(total,4,1)
Return
 
 
/**********************************************************************
* Subroutines for Optimization
**********************************************************************/
 
steppingstone: Procedure Expose matrix. cost. rr cc matrix. demand_in.,
source_in. ms fid move cnt.
maxReduction=0
move=''
Call fixDegenerateCase
Do r=1 To rr
Do c=1 To cc
Parse Var matrix.r.c r c cost qrc
If qrc=0 Then Do
path=getclosedpath(r,c)
If pelems(path)<4 Then Do
Iterate
End
reduction = 0
lowestQuantity = 1e10
leavingCandidate = ''
plus=1
pathx=path
Do While pathx<>''
Parse Var pathx s '|' pathx
If plus Then
reduction=reduction+word(s,3)
Else Do
reduction=reduction-word(s,3)
If word(s,4)<lowestQuantity Then Do
leavingCandidate = s
lowestQuantity = word(s,4)
End
End
plus=\plus
End
If reduction < maxreduction Then Do
move=path
leaving=leavingCandidate
maxReduction = reduction
End
End
End
End
if move<>'' Then Do
quant=word(leaving,4)
If quant=0 Then Do
Call show_alloc 'Optimum'
Exit
End
plus=1
Do While move<>''
Parse Var move m '|' move
Parse Var m r c cpu qrc
Parse Var matrix.r.c vr vc vcost vquant
If plus Then
nquant=vquant+quant
Else
nquant=vquant-quant
matrix.r.c = vr vc vcost nquant
plus=\plus
End
move=''
Call steppingStone
End
Else
Call show_alloc 'Optimal Solution' fid
Return
 
getclosedpath: Procedure Expose matrix. cost. rr cc matrix.
Parse Arg rd,cd
path=rd cd cost.rd.cd word(matrix.rd.cd,4)
do r=1 To rr
Do c=1 To cc
If word(matrix.r.c,4)>0 Then Do
path=path'|'r c cost.r.c word(matrix.r.c,4)
End
End
End
path=magic(path)
Return stones(path)
 
magic: Procedure
Parse Arg list
Do Forever
list_1=remove_1(list)
If list_1=list Then Leave
list=list_1
End
Return list_1
 
remove_1: Procedure
Parse Arg list
cntr.=0
cntc.=0
Do i=1 By 1 While list<>''
parse Var list e.i '|' list
Parse Var e.i r c .
cntr.r=cntr.r+1
cntc.c=cntc.c+1
End
n=i-1
keep.=1
Do i=1 To n
Parse Var e.i r c .
If cntr.r<2 |,
cntc.c<2 Then Do
keep.i=0
End
End
list=e.1
Do i=2 To n
If keep.i Then
list=list'|'e.i
End
Return list
 
stones: Procedure
Parse Arg lst
tstc=lst
Do i=1 By 1 While tstc<>''
Parse Var tstc o.i '|' tstc
end
stones=lst
o.0=i-1
prev=o.1
Do i=1 To o.0
st.i=prev
k=i//2
nbrs=getNeighbors(prev,lst)
Parse Var nbrs n.1 '|' n.2
If k=0 Then
prev=n.2
Else
prev=n.1
End
stones=st.1
Do i=2 To o.0
stones=stones'|'st.i
End
Return stones
 
getNeighbors: Procedure Expose o.
parse Arg s, lst
Do i=1 To 4
Parse Var lst o.i '|' lst
End
nbrs.=''
sr=word(s,1)
sc=word(s,2)
Do i=1 To o.0
If o.i<>s Then Do
or=word(o.i,1)
oc=word(o.i,2)
If or=sr & nbrs.0='' Then
nbrs.0 = o.i
else if oc=sc & nbrs.1='' Then
nbrs.1 = o.i
If nbrs.0<>'' & nbrs.1<>'' Then
Leave
End
End
return nbrs.0'|'nbrs.1
 
m1: Procedure
Parse Arg z
Return z-1
 
pelems: Procedure
Call Trace 'O'
Parse Arg p
n=0
Do While p<>''
Parse Var p x '|' p
If x<>'' Then n=n+1
End
Return n
 
fixDegenerateCase: Procedure Expose matrix. rr cc ms
Call matrixtolist
If (rr+cc-1)<>ms Then Do
Do r=1 To rr
Do c=1 To cc
If word(matrix.r.c,4)=0 Then Do
matrix.r.c=subword(matrix.r.c,1,3) 1.e-10
Return
End
End
End
End
Return
 
matrixtolist: Procedure Expose matrix. rr cc ms
ms=0
list=''
Do r=1 To rr
Do c=1 To cc
If word(matrix.r.c,4)>0 Then Do
list=list'|'matrix.r.c
ms=ms+1
End
End
End
Return strip(list,,'|')
 
Novalue:
Say 'Novalue raised in line' sigl
Say sourceline(sigl)
Say 'Variable' condition('D')
Signal lookaround
 
Syntax:
Say 'Syntax raised in line' sigl
Say sourceline(sigl)
Say 'rc='rc '('errortext(rc)')'
 
halt:
lookaround:
If fore() Then Do
Say 'You can look around now.'
Trace ?R
Nop
End
Exit 12</syntaxhighlight>
{{out}}
<pre>F:\>regina tpv vv.txt
Sources / Demands / Cost
30 20 70 30 60
50 16 16 13 22 17
60 14 14 13 19 15
50 19 19 20 23 50
50 50 12 50 15 11
 
Vogel's Approximation
30 20 70 30 60
50 - - 50 - -
60 - - 20 - 40
50 30 20 - - -
50 - - - 30 20
Total costs: 3130.0
 
Optimum
30 20 70 30 60
50 - - 50 - -
60 30 - 20 - 10
50 - 20 - 30 -
50 - - - - 50
Total costs: 3100.0</pre>
 
===Low Cost Algorithm===
<syntaxhighlight lang="rexx">/* REXX ***************************************************************
* Solve the Transportation Problem using the Least Cost Method
Default Input
2 3 # of sources / # of demands
25 35 sources
20 30 10 demands
3 5 7 cost matrix
3 2 5
* 20201228 corresponds to NWC above
* Note: correctness of input is not checked
* 20210102 add optimization
* 20210103 remove debug code
**********************************************************************/
Signal On Halt
Signal On Novalue
Signal On Syntax
 
Parse Arg fid
If fid='' Then
fid='input1.txt'
Call init
Do r=1 To rr
Do c=1 To cc
matrix.r.c=r c cost.r.c 0
End
End
Do Until source_sum=0
mincost=1e10
Do r=1 To rr
If source.r>0 Then Do
Do c=1 To cc
If demand.c>0 Then Do
cost=word(matrix.r.c,3)
If cost>0 & cost<mincost |,
source_sum=source.r |,
demand_sum=demand.c Then Do
tgt=r c cost
mincost=cost
End
End
End
End
End
Parse Var tgt tr tc .
a=min(source.tr,demand.tc)
matrix.tr.tc=subword(matrix.tr.tc,1,3) word(matrix.tr.tc,4)+a
source.tr=source.tr-a
demand.tc=demand.tc-a
source_sum=source_sum-a
demand_sum=demand_sum-a
 
End
Call show_alloc 'Low Cost Algorithm'
Call steppingstone
Exit
 
/**********************************************************************
* Subroutines for Low Cost Algorithm
**********************************************************************/
 
init:
If lines(fid)=0 Then Do
Say 'Input file not specified or not found. Using default input instead.'
fid='Default input'
in.1=sourceline(4)
Parse Var in.1 numSources .
Do i=2 To numSources+3
in.i=sourceline(i+3)
End
End
Else Do
Do i=1 By 1 while lines(fid)>0
in.i=linein(fid)
End
End
Parse Var in.1 numSources numDestinations . 1 rr cc .
source_sum=0
Do i=1 To numSources
Parse Var in.2 source.i in.2
ss.i=source.i
source_sum=source_sum+source.i
source_in.i=source.i
End
demand_sum=0
Do i=1 To numDestinations
Parse Var in.3 demand.i in.3
dd.i=demand.i
demand_in.i=demand.i
demand_sum=demand_sum+demand.i
End
Do i=1 To numSources
j=i+3
l=in.j
Do j=1 To numDestinations
Parse Var l cost.i.j l
End
End
Do i=1 To numSources
ol=format(source.i,3)
Do j=1 To numDestinations
ol=ol format(cost.i.j,4)
End
End
Select
When source_sum=demand_sum Then Nop /* balanced */
When source_sum>demand_sum Then Do /* unbalanced - add dummy demand */
Say 'This is an unbalanced case (sources exceed demands). We add a dummy consumer.'
cc=cc+1
demand.cc=source_sum-demand_sum
demand_in.cc=demand.cc
dd.cc=demand.cc
Do r=1 To rr
cost.r.cc=0
End
End
Otherwise /* demand_sum>source_sum */ Do /* unbalanced - add dummy source */
Say 'This is an unbalanced case (demands exceed sources). We add a dummy source.'
rr=rr+1
source.rr=demand_sum-source_sum
ss.rr=source.rr
source_in.rr=source.rr
Do c=1 To cc
cost.rr.c=0
End
End
End
 
Say 'Sources / Demands / Cost'
ol=' '
Do c=1 To cc
ol=ol format(demand.c,3)
End
Say ol
Do r=1 To rr
ol=format(source.r,4)
Do c=1 To cc
ol=ol format(cost.r.c,3)
End
Say ol
End
Return
 
show_alloc: Procedure Expose matrix. rr cc demand_in. source_in.
Parse Arg header
If header='' Then
Return
Say ''
Say header
total=0
ol=' '
Do c=1 to cc
ol=ol format(demand_in.c,3)
End
Say ol
as=''
Do r=1 to rr
ol=format(source_in.r,4)
a=word(matrix.r.1,4)
If a=0.0000000001 Then a=0
If a>0 Then
ol=ol format(a,3)
Else
ol=ol ' - '
total=total+word(matrix.r.1,4)*word(matrix.r.1,3)
Do c=2 To cc
a=word(matrix.r.c,4)
If a=0.0000000001 Then a=0
If a>0 Then
ol=ol format(a,3)
Else
ol=ol ' - '
total=total+word(matrix.r.c,4)*word(matrix.r.c,3)
as=as a
End
Say ol
End
Say 'Total costs:' format(total,4,1)
Return
 
 
/**********************************************************************
* Subroutines for Optimization
**********************************************************************/
 
steppingstone: Procedure Expose matrix. cost. rr cc matrix. demand_in.,
source_in. fid move cnt.
maxReduction=0
move=''
Call fixDegenerateCase
Do r=1 To rr
Do c=1 To cc
Parse Var matrix.r.c r c cost qrc
If qrc=0 Then Do
path=getclosedpath(r,c)
If pelems(path)<4 then
Iterate
reduction = 0
lowestQuantity = 1e10
leavingCandidate = ''
plus=1
pathx=path
Do While pathx<>''
Parse Var pathx s '|' pathx
If plus Then
reduction=reduction+word(s,3)
Else Do
reduction=reduction-word(s,3)
If word(s,4)<lowestQuantity Then Do
leavingCandidate = s
lowestQuantity = word(s,4)
End
End
plus=\plus
End
If reduction < maxreduction Then Do
move=path
leaving=leavingCandidate
maxReduction = reduction
End
End
End
End
if move<>'' Then Do
quant=word(leaving,4)
If quant=0 Then Do
Call show_alloc 'Optimum'
Exit
End
plus=1
Do While move<>''
Parse Var move m '|' move
Parse Var m r c cpu qrc
Parse Var matrix.r.c vr vc vcost vquant
If plus Then
nquant=vquant+quant
Else
nquant=vquant-quant
matrix.r.c = vr vc vcost nquant
plus=\plus
End
move=''
Call steppingStone
End
Else
Call show_alloc 'Optimal Solution' fid
Return
 
getclosedpath: Procedure Expose matrix. cost. rr cc
Parse Arg rd,cd
path=rd cd cost.rd.cd word(matrix.rd.cd,4)
do r=1 To rr
Do c=1 To cc
If word(matrix.r.c,4)>0 Then Do
path=path'|'r c cost.r.c word(matrix.r.c,4)
End
End
End
path=magic(path)
Return stones(path)
 
magic: Procedure
Parse Arg list
Do Forever
list_1=remove_1(list)
If list_1=list Then Leave
list=list_1
End
Return list_1
 
remove_1: Procedure
Parse Arg list
cntr.=0
cntc.=0
Do i=1 By 1 While list<>''
parse Var list e.i '|' list
Parse Var e.i r c .
cntr.r=cntr.r+1
cntc.c=cntc.c+1
End
n=i-1
keep.=1
Do i=1 To n
Parse Var e.i r c .
If cntr.r<2 |,
cntc.c<2 Then Do
keep.i=0
End
End
list=e.1
Do i=2 To n
If keep.i Then
list=list'|'e.i
End
Return list
 
stones: Procedure
Parse Arg lst
stones=lst
tstc=lst
Do i=1 By 1 While tstc<>''
Parse Var tstc o.i '|' tstc
End
o.0=i-1
prev=o.1
Do i=1 To o.0
st.i=prev
k=i//2
nbrs=getNeighbors(prev, lst)
Parse Var nbrs n.1 '|' n.2
If k=0 Then
prev=n.2
Else
prev=n.1
End
stones=st.1
Do i=2 To o.0
stones=stones'|'st.i
End
Return stones
 
getNeighbors: Procedure
parse Arg s, lst
Do i=1 By 1 While lst<>''
Parse Var lst o.i '|' lst
End
o.0=i-1
nbrs.=''
sr=word(s,1)
sc=word(s,2)
Do i=1 To o.0
If o.i<>s Then Do
or=word(o.i,1)
oc=word(o.i,2)
If or=sr & nbrs.0='' Then
nbrs.0 = o.i
else if oc=sc & nbrs.1='' Then
nbrs.1 = o.i
If nbrs.0<>'' & nbrs.1<>'' Then
Leave
End
End
return nbrs.0'|'nbrs.1
 
m1: Procedure
Parse Arg z
Return z-1
 
pelems: Procedure
Call Trace 'O'
Parse Arg p
n=0
Do While p<>''
Parse Var p x '|' p
If x<>'' Then n=n+1
End
Return n
 
fixDegenerateCase: Procedure Expose matrix. rr cc ms ms demand_in. source_in. move cnt.
Call matrixtolist
If (rr+cc-1)<>ms Then Do
Do r=1 To rr
Do c=1 To cc
If word(matrix.r.c,4)=0 Then Do
matrix.r.c=subword(matrix.r.c,1,3) 1.e-10
Return
End
End
End
End
Return
 
matrixtolist: Procedure Expose matrix. rr cc ms
ms=0
list=''
Do r=1 To rr
Do c=1 To cc
If word(matrix.r.c,4)>0 Then Do
list=list'|'matrix.r.c
ms=ms+1
End
End
End
Return strip(list,,'|')
 
Novalue:
Say 'Novalue raised in line' sigl
Say sourceline(sigl)
Say 'Variable' condition('D')
Signal lookaround
 
Syntax:
Say 'Syntax raised in line' sigl
Say sourceline(sigl)
Say 'rc='rc '('errortext(rc)')'
 
halt:
lookaround:
If fore() Then Do
Say 'You can look around now.'
Trace ?R
Nop
End
Exit 12
</syntaxhighlight>
{{out}}
<pre>F:\>rexx tpl vv.txt
Sources / Demands / Cost
30 20 70 30 60
50 16 16 13 22 17
60 14 14 13 19 15
50 19 19 20 23 50
50 50 12 50 15 11
 
Low Cost Algorithm
30 20 70 30 60
50 - - 50 - -
60 30 10 20 - -
50 - 10 - 30 10
50 - - - - 50
Total costs: 3400.0
 
Optimum
30 20 70 30 60
50 - - 50 - -
60 30 - 20 - 10
50 - 20 - 30 -
50 - - - - 50
Total costs: 3100.0</pre>
 
=={{header|Ruby}}==
Breaks ties using lowest cost cell.
===Task Example===
<langsyntaxhighlight lang="ruby"># VAM
#
# Nigel_Galloway
Line 1,390 ⟶ 2,877:
puts
end
print "\n\nTotal Cost = ", cost</langsyntaxhighlight>
{{out}}
<pre>
Line 1,405 ⟶ 2,892:
===Reference Example===
Replacing the data in the Task Example with:
<langsyntaxhighlight lang="ruby">COSTS = {S1: {D1: 46, D2: 74, D3: 9, D4: 28, D5: 99},
S2: {D1: 12, D2: 75, D3: 6, D4: 36, D5: 48},
S3: {D1: 35, D2: 199, D3: 4, D4: 5, D5: 71},
Line 1,411 ⟶ 2,898:
S5: {D1: 85, D2: 60, D3: 14, D4: 25, D5: 79}}
demand = {D1: 278, D2: 60, D3: 461, D4: 116, D5: 1060}
supply = {S1: 461, S2: 277, S3: 356, S4: 488, S5: 393}</langsyntaxhighlight>
Produces:
<pre>
Line 1,427 ⟶ 2,914:
=={{header|Sidef}}==
{{trans|Ruby}}
<langsyntaxhighlight lang="ruby">var costs = :(
W => :(A => 16, B => 16, C => 13, D => 22, E => 17),
X => :(A => 14, B => 14, C => 13, D => 19, E => 15),
Line 1,493 ⟶ 2,980:
}
 
say "\n\nTotal Cost = #{cost}"</langsyntaxhighlight>
{{out}}
<pre>
Line 1,508 ⟶ 2,995:
=={{header|Tcl}}==
{{works with|Tcl|8.6}}
<langsyntaxhighlight lang="tcl">package require Tcl 8.6
 
# A sort that works by sorting by an auxiliary key computed by a lambda term
Line 1,611 ⟶ 3,098:
}
return $res
}</langsyntaxhighlight>
Demonstration:
<langsyntaxhighlight lang="tcl">set COSTS {
W {A 16 B 16 C 13 D 22 E 17}
X {A 14 B 14 C 13 D 19 E 15}
Line 1,633 ⟶ 3,120:
}] \t]
}
puts "\nTotal Cost = $cost"</langsyntaxhighlight>
{{out}}
<pre>
Line 1,641 ⟶ 3,128:
Y 20 30
Z 50
 
Total Cost = 3100
</pre>
 
=={{header|Wren}}==
{{trans|Kotlin}}
{{libheader|Wren-math}}
{{libheader|Wren-fmt}}
<syntaxhighlight lang="wren">import "./math" for Nums
import "./fmt" for Fmt
 
var supply = [50, 60, 50, 50]
var demand = [30, 20, 70, 30, 60]
 
var costs = [
[16, 16, 13, 22, 17],
[14, 14, 13, 19, 15],
[19, 19, 20, 23, 50],
[50, 12, 50, 15, 11]
]
 
var nRows = supply.count
var nCols = demand.count
 
var rowDone = List.filled(nRows, false)
var colDone = List.filled(nCols, false)
var results = List.filled(nRows, null)
for (i in 0...nRows) results[i] = List.filled(nCols, 0)
 
var diff = Fn.new { |j, len, isRow|
var min1 = Num.maxSafeInteger
var min2 = min1
var minP = -1
for (i in 0...len) {
var done = isRow ? colDone[i] : rowDone[i]
if (!done) {
var c = isRow ? costs[j][i] : costs[i][j]
if (c < min1) {
min2 = min1
min1 = c
minP = i
} else if (c < min2) min2 = c
}
}
return [min2 - min1, min1, minP]
}
 
var maxPenalty = Fn.new { |len1, len2, isRow|
var md = Num.minSafeInteger
var pc = -1
var pm = -1
var mc = -1
for (i in 0...len1) {
var done = isRow ? rowDone[i] : colDone[i]
if (!done) {
var res = diff.call(i, len2, isRow)
if (res[0] > md) {
md = res[0] // max diff
pm = i // pos of max diff
mc = res[1] // min cost
pc = res[2] // pos of min cost
}
}
}
return isRow ? [pm, pc, mc, md] : [pc, pm, mc, md]
}
 
var nextCell = Fn.new {
var res1 = maxPenalty.call(nRows, nCols, true)
var res2 = maxPenalty.call(nCols, nRows, false)
if (res1[3] == res2[3]) return (res1[2] < res2[2]) ? res1 : res2
return (res1[3] > res2[3]) ? res2 : res1
}
 
var supplyLeft = Nums.sum(supply)
var totalCost = 0
while (supplyLeft > 0) {
var cell = nextCell.call()
var r = cell[0]
var c = cell[1]
var q = demand[c].min(supply[r])
demand[c] = demand[c] - q
if (demand[c] == 0) colDone[c] = true
supply[r] = supply[r] - q
if (supply[r] == 0) rowDone[r] = true
results[r][c] = q
supplyLeft = supplyLeft - q
totalCost = totalCost + q*costs[r][c]
}
 
System.print(" A B C D E")
var i = 0
for (result in results) {
Fmt.write("$c", "W".bytes[0] + i)
for (item in result) Fmt.write(" $2d", item)
System.print()
i = i + 1
}
System.print("\nTotal Cost = %(totalCost)")</syntaxhighlight>
 
{{out}}
<pre>
A B C D E
W 0 0 50 0 0
X 30 0 20 0 10
Y 0 20 0 30 0
Z 0 0 0 0 50
 
Total Cost = 3100
Line 1,647 ⟶ 3,241:
=={{header|Yabasic}}==
{{trans|C}}
<syntaxhighlight lang="yabasic">
<lang Yabasic>
N_ROWS = 4 : N_COLS = 5
Line 1,795 ⟶ 3,389:
print
next i
print "\nTotal cost = ", total_cost</langsyntaxhighlight>
 
=={{header|zkl}}==
{{trans|Python}}{{trans|Ruby}}
<langsyntaxhighlight lang="zkl">costs:=Dictionary(
"W",Dictionary("A",16, "B",16, "C",13, "D",22, "E",17),
"X",Dictionary("A",14, "B",14, "C",13, "D",19, "E",15),
Line 1,805 ⟶ 3,399:
"Z",Dictionary("A",50, "B",12, "C",50, "D",15, "E",11)).makeReadOnly();
demand:=Dictionary("A",30, "B",20, "C",70, "D",30, "E",60); // gonna be modified
supply:=Dictionary("W",50, "X",60, "Y",50, "Z",50); // gonna be modified</langsyntaxhighlight>
<langsyntaxhighlight lang="zkl">cols:=demand.keys.sort();
res :=vogel(costs,supply,demand);
cost:=0;
Line 1,819 ⟶ 3,413:
println();
}
println("\nTotal Cost = ",cost);</langsyntaxhighlight>
<langsyntaxhighlight lang="zkl">fcn vogel(costs,supply,demand){
// a Dictionary can be created via a list of (k,v) pairs
res:= Dictionary(costs.pump(List,fcn([(k,_)]){ return(k,D()) }));
Line 1,849 ⟶ 3,443:
}//while
res
}</langsyntaxhighlight>
{{out}}
<pre>
9,476

edits