Just another update

This commit is contained in:
Ingy döt Net 2015-02-20 00:35:01 -05:00
parent a25938f123
commit 00a190b0a6
6591 changed files with 94363 additions and 23227 deletions

View file

@ -1,22 +1,22 @@
import std.stdio, std.algorithm, std.typecons;
void main() @safe /*@nogc*/ {
import std.stdio, std.algorithm, std.typecons, std.conv;
struct Bounty {
int value;
double weight, volume;
}
static struct Bounty {
int value;
double weight, volume;
}
void main() {
immutable Bounty panacea = {3000, 0.3, 0.025};
immutable Bounty ichor = {1800, 0.2, 0.015};
immutable Bounty gold = {2500, 2.0, 0.002};
immutable Bounty sack = { 0, 25.0, 0.25};
immutable Bounty sack = { 0, 25.0, 0.25 };
immutable maxPanacea = cast(int)(min(sack.weight / panacea.weight,
sack.volume / panacea.volume));
immutable maxIchor = cast(int)(min(sack.weight / ichor.weight,
sack.volume / ichor.volume));
immutable maxGold = cast(int)(min(sack.weight / gold.weight,
sack.volume / gold.volume));
immutable maxPanacea = min(sack.weight / panacea.weight,
sack.volume / panacea.volume).to!int;
immutable maxIchor = min(sack.weight / ichor.weight,
sack.volume / ichor.volume).to!int;
immutable maxGold = min(sack.weight / gold.weight,
sack.volume / gold.volume).to!int;
Bounty best = {0, 0, 0};
Tuple!(int, int, int) bestAmounts;
@ -38,16 +38,14 @@ void main() {
if (current.value > best.value &&
current.weight <= sack.weight &&
current.volume <= sack.volume) {
best = Bounty(current.value,
current.weight,
current.volume);
best = Bounty(current.value, current.weight, current.volume);
bestAmounts = tuple(nPanacea, nIchor, nGold);
}
}
writeln("Maximum value achievable is ", best.value);
writefln("This is achieved by carrying (one solution) %d" ~
" panacea, %d ichor and %d gold", bestAmounts.tupleof);
" panacea, %d ichor and %d gold", bestAmounts[]);
writefln("The weight to carry is %4.1f and the volume used is %5.3f",
best.weight, best.volume);
}

View file

@ -1,38 +1,26 @@
import std.stdio, std.algorithm, std.typecons, std.range;
alias Bounty = Tuple!(int,"value", double,"weight", double,"volume");
void main() {
immutable panacea = Bounty(3000, 0.3, 0.025);
immutable ichor = Bounty(1800, 0.2, 0.015);
immutable gold = Bounty(2500, 2.0, 0.002);
immutable sack = Bounty( 0, 25.0, 0.25);
import std.stdio, std.algorithm, std.typecons, std.range, std.conv;
immutable maxPanacea= cast(int)(min(sack.weight / panacea.weight,
sack.volume / panacea.volume));
immutable maxIchor = cast(int)(min(sack.weight / ichor.weight,
sack.volume / ichor.volume));
immutable maxGold = cast(int)(min(sack.weight / gold.weight,
sack.volume / gold.volume));
alias Bounty = Tuple!(int,"value", double,"weight", double,"volume");
immutable best =
immutable panacea = Bounty(3000, 0.3, 0.025);
immutable ichor = Bounty(1800, 0.2, 0.015);
immutable gold = Bounty(2500, 2.0, 0.002);
immutable sack = Bounty( 0, 25.0, 0.25);
immutable maxPanacea = min(sack.weight / panacea.weight, sack.volume / panacea.volume).to!int;
immutable maxIchor = min(sack.weight / ichor.weight, sack.volume / ichor.volume).to!int;
immutable maxGold = min(sack.weight / gold.weight, sack.volume / gold.volume).to!int;
immutable best =
cartesianProduct(maxPanacea.iota, maxIchor.iota, maxGold.iota)
.map!(t => tuple(Bounty(t[0] * panacea.value
+ t[1] * ichor.value
+ t[2] * gold.value,
t[0] * panacea.weight
+ t[1] * ichor.weight
+ t[2] * gold.weight,
t[0] * panacea.volume
+ t[1] * ichor.volume
+ t[2] * gold.volume), t))
.filter!(t => t[0].weight <= sack.weight
&& t[0].volume <= sack.volume)
.map!(t => tuple(Bounty(t[0] * panacea.value + t[1] * ichor.value + t[2] * gold.value,
t[0] * panacea.weight + t[1] * ichor.weight + t[2] * gold.weight,
t[0] * panacea.volume + t[1] * ichor.volume + t[2] * gold.volume), t))
.filter!(t => t[0].weight <= sack.weight && t[0].volume <= sack.volume)
.reduce!max;
writeln("Maximum value achievable is ", best[0].value);
writefln("This is achieved by carrying (one solution) %d" ~
" panacea, %d ichor and %d gold", best[1].tupleof);
writefln("The weight to carry is %4.1f and the" ~
" volume used is %5.3f", best[0].weight, best[0].volume);
writeln("Maximum value achievable is ", best[0].value);
writefln("This is achieved by carrying (one solution) %d panacea, %d ichor and %d gold", best[1][]);
writefln("The weight to carry is %4.1f and the volume used is %5.3f", best[0][1..$]);
}

View file

@ -3,68 +3,64 @@ package main
import "fmt"
type Item struct {
Name string
Value int
Weight, Volume float64
Name string
Value int
Weight, Volume float64
}
type Result struct {
Counts []int
Sum int
Counts []int
Sum int
}
func min(a, b int) int {
if a < b {
return a
}
return b
if a < b {
return a
}
return b
}
func Knapsack(items []Item, index int, weight, volume float64) (best *Result) {
if index == len(items) {
return &Result{make([]int, len(items)), 0}
}
itemValue := items[index].Value
itemWeight := items[index].Weight
itemVolume := items[index].Volume
maxCount := min(int(weight/itemWeight), int(volume/itemVolume))
for count := 0; count <= maxCount; count++ {
sol := Knapsack(items, index+1,
weight-float64(count)*itemWeight,
volume-float64(count)*itemVolume)
if sol != nil {
sol.Counts[index] = count
sol.Sum += itemValue * count
if best == nil || sol.Sum > best.Sum {
best = sol
}
}
}
return
func Knapsack(items []Item, weight, volume float64) (best Result) {
if len(items) == 0 {
return
}
n := len(items) - 1
maxCount := min(int(weight/items[n].Weight), int(volume/items[n].Volume))
for count := 0; count <= maxCount; count++ {
sol := Knapsack(items[:n],
weight-float64(count)*items[n].Weight,
volume-float64(count)*items[n].Volume)
sol.Sum += items[n].Value * count
if sol.Sum > best.Sum {
sol.Counts = append(sol.Counts, count)
best = sol
}
}
return
}
func main() {
items := []Item{
Item{"Panacea", 3000, 0.3, 0.025},
Item{"Ichor", 1800, 0.2, 0.015},
Item{"Gold", 2500, 2.0, 0.002},
}
var sumCount, sumValue int
var sumWeight, sumVolume float64
items := []Item{
{"Panacea", 3000, 0.3, 0.025},
{"Ichor", 1800, 0.2, 0.015},
{"Gold", 2500, 2.0, 0.002},
}
var sumCount, sumValue int
var sumWeight, sumVolume float64
result := Knapsack(items, 0, 25, 0.25)
result := Knapsack(items, 25, 0.25)
for i := range result.Counts {
fmt.Printf("%-8s x%3d -> Weight: %4.1f Volume: %5.3f Value: %6d\n",
items[i].Name, result.Counts[i], items[i].Weight*float64(result.Counts[i]),
items[i].Volume*float64(result.Counts[i]), items[i].Value*result.Counts[i])
for i := range result.Counts {
fmt.Printf("%-8s x%3d -> Weight: %4.1f Volume: %5.3f Value: %6d\n",
items[i].Name, result.Counts[i], items[i].Weight*float64(result.Counts[i]),
items[i].Volume*float64(result.Counts[i]), items[i].Value*result.Counts[i])
sumCount += result.Counts[i]
sumValue += items[i].Value * result.Counts[i]
sumWeight += items[i].Weight * float64(result.Counts[i])
sumVolume += items[i].Volume * float64(result.Counts[i])
}
sumCount += result.Counts[i]
sumValue += items[i].Value * result.Counts[i]
sumWeight += items[i].Weight * float64(result.Counts[i])
sumVolume += items[i].Volume * float64(result.Counts[i])
}
fmt.Printf("TOTAL (%3d items) Weight: %4.1f Volume: %5.3f Value: %6d\n",
sumCount, sumWeight, sumVolume, sumValue)
fmt.Printf("TOTAL (%3d items) Weight: %4.1f Volume: %5.3f Value: %6d\n",
sumCount, sumWeight, sumVolume, sumValue)
}

View file

@ -1,46 +1,45 @@
/*REXX program solves a knapsack/unbounded problem. */
maxPanacea=0
maxIchor =0
maxGold =0
max$ =0
current. =0
maxPanacea = 0
maxIchor = 0
maxGold = 0
max$ = 0
current. = 0
/* value weight volume */
/* ═══════ ═══════ ══════ */
panacea.$ = 3000 ; panacea.w = 0.3 ; panacea.v = 0.025
ichor.$ = 1800 ; ichor.w = 0.2 ; ichor.v = 0.015
gold.$ = 2500 ; gold.w = 2 ; gold.v = 0.002
sack.$ = 0 ; sack.w = 25 ; sack.v = 0.25
/* value weight volume */
/* ═══════ ═══════ ══════ */
panacea.$= 3000 ; panacea.w= 0.3 ; panacea.v= 0.025
ichor.$= 1800 ; ichor.w= 0.2 ; ichor.v= 0.015
gold.$= 2500 ; gold.w= 2 ; gold.v= 0.002
sack.$= 0 ; sack.w= 25 ; sack.v= 0.25
maxPanacea = min(sack.w/panacea.w, sack.v/panacea.v)
maxIchor = min(sack.w/ ichor.w, sack.v/ ichor.v)
maxGold = min(sack.w/ gold.w, sack.v/ gold.v)
maxPanacea = min(sack.w / panacea.w, sack.v / panacea.v)
maxIchor = min(sack.w / ichor.w, sack.v / ichor.v)
maxGold = min(sack.w / gold.w, sack.v / gold.v)
do p=0 to maxpanacea
do i=0 to maxichor
do g=0 to maxgold
current.$=g*gold.$ + i*ichor.$ + p*panacea.$
current.w=g*gold.w + i*ichor.w + p*panacea.w
current.v=g*gold.v + i*ichor.v + p*panacea.v
if current.w>sack.w | current.v>sack.v then iterate
current.$ = g*gold.$ + i*ichor.$ + p*panacea.$
current.w = g*gold.w + i*ichor.w + p*panacea.w
current.v = g*gold.v + i*ichor.v + p*panacea.v
if current.w>sack.w | current.v>sack.v then iterate
if current.$>max$ then do
max$ = current.$
totalW = current.w
totalV = current.v
maxP=p; maxI=i; maxG=g
maxP = p; maxI = i; maxG = g
end
end /*g (gold) */
end /*i (ichor) */
end /*p (panacea)*/
cTot=maxP+maxI+maxG
L=length(cTot)+1
say ' panacea in sack:' right(maxP,L)
say ' ichors in sack:' right(maxI,L)
say ' gold items in sack:' right(maxG,L)
say '' copies('',L)
say 'carrying a total of:' right(cTot,L)
say left('',40) 'total value: ' max$/1
say left('',40) 'total weight: ' totalW/1
say left('',40) 'total volume: ' totalV/1
cTot = maxP + maxI + maxG
L = length(cTot) + 1
say ' panacea in sack:' right(maxP,L)
say ' ichors in sack:' right(maxI,L)
say ' gold items in sack:' right(maxG,L)
say '' copies('',L)
say 'carrying a total of:' right(cTot,L)
say left('',40) 'total value: ' max$/1
say left('',40) 'total weight: ' totalW/1
say left('',40) 'total volume: ' totalV/1
/*stick a fork in it, we're done.*/

View file

@ -15,8 +15,8 @@ solutions = []
0.upto(max_items[ichor]) do |i|
0.upto(max_items[panacea]) do |p|
0.upto(max_items[gold]) do |g|
next if i*ichor.weight + p*panacea.weight + g*gold.weight > maximum.weight
next if i*ichor.volume + p*panacea.volume + g*gold.volume > maximum.volume
break if i*ichor.weight + p*panacea.weight + g*gold.weight > maximum.weight
break if i*ichor.volume + p*panacea.volume + g*gold.volume > maximum.volume
val = i*ichor.value + p*panacea.value + g*gold.value
if val > maxval
maxval = val

View file

@ -0,0 +1,25 @@
Function Min(E1, E2): Min = IIf(E1 < E2, E1, E2): End Function 'small Helper-Function
Sub Main()
Const Value = 0, Weight = 1, Volume = 2, PC = 3, IC = 4, GC = 5
Dim P&, I&, G&, A&, M, Cur(Value To Volume)
Dim S As New Collection: S.Add Array(0) '<- init Solutions-Coll.
Const SackW = 25, SackV = 0.25
Dim Panacea: Panacea = Array(3000, 0.3, 0.025)
Dim Ichor: Ichor = Array(1800, 0.2, 0.015)
Dim Gold: Gold = Array(2500, 2, 0.002)
For P = 0 To Int(Min(SackW / Panacea(Weight), SackV / Panacea(Volume)))
For I = 0 To Int(Min(SackW / Ichor(Weight), SackV / Ichor(Volume)))
For G = 0 To Int(Min(SackW / Gold(Weight), SackV / Gold(Volume)))
For A = Value To Volume: Cur(A) = G * Gold(A) + I * Ichor(A) + P * Panacea(A): Next
If Cur(Value) >= S(1)(Value) And Cur(Weight) <= SackW And Cur(Volume) <= SackV Then _
S.Add Array(Cur(Value), Cur(Weight), Cur(Volume), P, I, G), , 1
Next G, I, P
Debug.Print "Value", "Weight", "Volume", "PanaceaCount", "IchorCount", "GoldCount"
For Each M In S '<- enumerate the Attributes of the Maxima
If M(Value) = S(1)(Value) Then Debug.Print M(Value), M(Weight), M(Volume), M(PC), M(IC), M(GC)
Next
End Sub