September 2017 Update

This commit is contained in:
Ingy döt Net 2017-09-23 10:01:46 +02:00
parent bba7bfd280
commit ba8067c3b7
14570 changed files with 153136 additions and 63871 deletions

View file

@ -0,0 +1,90 @@
// version 1.1.3
val supply = intArrayOf(50, 60, 50, 50)
val demand = intArrayOf(30, 20, 70, 30, 60)
val costs = arrayOf(
intArrayOf(16, 16, 13, 22, 17),
intArrayOf(14, 14, 13, 19, 15),
intArrayOf(19, 19, 20, 23, 50),
intArrayOf(50, 12, 50, 15, 11)
)
val nRows = supply.size
val nCols = demand.size
val rowDone = BooleanArray(nRows)
val colDone = BooleanArray(nCols)
val results = Array(nRows) { IntArray(nCols) }
fun nextCell(): IntArray {
val res1 = maxPenalty(nRows, nCols, true)
val res2 = maxPenalty(nCols, nRows, false)
if (res1[3] == res2[3])
return if (res1[2] < res2[2]) res1 else res2
return if (res1[3] > res2[3]) res2 else res1
}
fun diff(j: Int, len: Int, isRow: Boolean): IntArray {
var min1 = Int.MAX_VALUE
var min2 = min1
var minP = -1
for (i in 0 until len) {
val done = if (isRow) colDone[i] else rowDone[i]
if (done) continue
val c = if (isRow) costs[j][i] else costs[i][j]
if (c < min1) {
min2 = min1
min1 = c
minP = i
}
else if (c < min2) min2 = c
}
return intArrayOf(min2 - min1, min1, minP)
}
fun maxPenalty(len1: Int, len2: Int, isRow: Boolean): IntArray {
var md = Int.MIN_VALUE
var pc = -1
var pm = -1
var mc = -1
for (i in 0 until len1) {
val done = if (isRow) rowDone[i] else colDone[i]
if (done) continue
val 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 if (isRow) intArrayOf(pm, pc, mc, md) else
intArrayOf(pc, pm, mc, md)
}
fun main(args: Array<String>) {
var supplyLeft = supply.sum()
var totalCost = 0
while (supplyLeft > 0) {
val cell = nextCell()
val r = cell[0]
val c = cell[1]
val q = minOf(demand[c], supply[r])
demand[c] -= q
if (demand[c] == 0) colDone[c] = true
supply[r] -= q
if (supply[r] == 0) rowDone[r] = true
results[r][c] = q
supplyLeft -= q
totalCost += q * costs[r][c]
}
println(" A B C D E")
for ((i, result) in results.withIndex()) {
print(('W'.toInt() + i).toChar())
for (item in result) print(" %2d".format(item))
println()
}
println("\nTotal Cost = $totalCost")
}

View file

@ -0,0 +1,7 @@
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),
"Y",Dictionary("A",19, "B",19, "C",20, "D",23, "E",50),
"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

View file

@ -0,0 +1,14 @@
cols:=demand.keys.sort();
res :=vogel(costs,supply,demand);
cost:=0;
println("\t",cols.concat("\t"));
foreach g in (costs.keys.sort()){
print(g,"\t");
foreach n in (cols){
y:=res[g].find(n);
if(y){ y=y[0]; print(y); cost+=y*costs[g][n]; }
print("\t");
}
println();
}
println("\nTotal Cost = ",cost);

View file

@ -0,0 +1,30 @@
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()) }));
g := Dictionary(); // cross index costs and make writable
supply.pump(Void,'wrap([(k,_)]){ g[k] =
costs[k].keys.sort('wrap(a,b){ costs[k][a]<costs[k][b] }).copy() });
demand.pump(Void,'wrap([(k,_)]){ g[k] =
costs.keys.sort('wrap(a,b){ costs[a][k]<costs[b][k] }).copy() });
while(g){
d:=Dictionary(demand.pump(List,'wrap([(k,_)]){ return(k,
g[k][0,2].apply('wrap(gk){ costs[gk][k] }).reverse().reduce('-)) }));
s:=Dictionary(supply.pump(List,'wrap([(k,_)]){ return(k,
g[k][0,2].apply('wrap(gk){ costs[k][gk] }).reverse().reduce('-)) }));
f:=(0).max(d.values); f=d.filter('wrap([(_,v)]){ v==f })[-1][0];
t:=(0).max(s.values); t=s.filter('wrap([(_,v)]){ v==t })[-1][0];
t,f=(if(d[f]>s[t]) T(f,g[f][0]) else T(g[t][0],t));
v:=supply[f].min(demand[t]);
res[f].appendV(t,v); // create t:(v) or append v to t:(...)
if(0 == (demand[t]-=v)){
supply.pump(Void,'wrap([(k,n)]){ if(n!=0) g[k].remove(t) });
g.del(t); demand.del(t);
}
if(0 == (supply[f]-=v)){
demand.pump(Void,'wrap([(k,n)]){ if(n!=0) g[k].remove(f) });
g.del(f); supply.del(f);
}
}//while
res
}