September 2017 Update
This commit is contained in:
parent
bba7bfd280
commit
ba8067c3b7
14570 changed files with 153136 additions and 63871 deletions
|
|
@ -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")
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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);
|
||||
|
|
@ -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
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue