langs a-z

This commit is contained in:
Ingy döt Net 2013-04-10 22:43:41 -07:00
parent db842d013d
commit d066446780
11389 changed files with 98361 additions and 1020 deletions

View file

@ -0,0 +1,76 @@
type bounty = { name:string; value:int; weight:float; volume:float }
let bounty n d w v = { name = n; value = d; weight = w; volume = v }
let items =
[ bounty "panacea" 3000 0.3 0.025;
bounty "ichor" 1800 0.2 0.015;
bounty "gold" 2500 2.0 0.002; ]
let max_wgt = 25.0 and max_vol = 0.25
let itmax =
let f it =
let rec aux n =
if float n *. it.weight >= max_wgt
|| float n *. it.volume >= max_vol
then (n)
else aux (succ n)
in
aux 0
in
List.map f items
let mklist n m =
let rec aux i acc =
if i > m then (List.rev acc)
else aux (succ i) (i::acc)
in
aux n []
let comb_items = List.map (mklist 0) itmax
let combs ll =
let f hd acc =
List.concat
(List.map (fun l -> List.map (fun v -> (v::l)) hd) acc)
in
List.fold_right f ll [[]]
let possibles = combs comb_items
let packs =
let f l =
let g (v, wgt, vol) n it =
(v + n * it.value,
wgt +. float n *. it.weight,
vol +. float n *. it.volume)
in
List.fold_left2 g (0, 0.0, 0.0) l items
in
List.map f possibles
let packs = List.combine packs possibles
let results =
let f (_, wgt, vol) = (wgt <= max_wgt && vol <= max_vol) in
List.filter (fun v -> f(fst v)) packs
let best_results =
let max_value = List.fold_left (fun v1 ((v2,_,_),_) -> max v1 v2) 0 results in
List.filter (fun ((v,_,_),_) -> v = max_value) results
let items_name = List.map (fun it -> it.name) items
let print ((v, wgt, vol), ns) =
Printf.printf "\
Maximum value: %d \n \
Total weight: %g \n \
Total volume: %g \n \
Containing: " v wgt vol;
let f n name = string_of_int n ^ " " ^ name in
let ss = List.map2 f ns items_name in
print_endline(String.concat ", " ss);
print_newline()
let () = List.iter print best_results

View file

@ -0,0 +1,24 @@
declare
proc {Knapsack Sol}
solution(panacea:P = {FD.decl}
ichor: I = {FD.decl}
gold: G = {FD.decl} ) = Sol
in
{Show 0#Sol}
3 * P + 2 * I + 20 * G =<: 250 {Show 1#Sol}
25 * P + 15 * I + 2 * G =<: 250 {Show 2#Sol}
{FD.distribute naive Sol} {Show d#Sol}
end
fun {Value solution(panacea:P ichor:I gold:G)}
3000 * P + 1800 * I + 2500 * G
end
{System.showInfo "Search:"}
[Best] = {SearchBest Knapsack proc {$ Old New}
{Value Old} <: {Value New}
end}
in
{System.showInfo "\nResult:"}
{Show Best}
{System.showInfo "total value: "#{Value Best}}

View file

@ -0,0 +1,54 @@
Program Knapsack(output);
uses
math;
type
bounty = record
value: longint;
weight, volume: real;
end;
const
panacea: bounty = (value:3000; weight: 0.3; volume: 0.025);
ichor: bounty = (value:1800; weight: 0.2; volume: 0.015);
gold: bounty = (value:2500; weight: 2.0; volume: 0.002);
sack: bounty = (value: 0; weight: 25.0; volume: 0.25);
var
totalweight, totalvolume: real;
maxpanacea, maxichor, maxgold: longint;
maxvalue: longint = 0;
n: array [1..3] of longint;
current: bounty;
i, j, k: longint;
begin
maxpanacea := round(min(sack.weight / panacea.weight, sack.volume / panacea.volume));
maxichor := round(min(sack.weight / ichor.weight, sack.volume / ichor.volume));
maxgold := round(min(sack.weight / gold.weight, sack.volume / gold.volume));
for i := 0 to maxpanacea do
for j := 0 to maxichor do
for k := 0 to maxgold do
begin
current.value := k * gold.value + j * ichor.value + i * panacea.value;
current.weight := k * gold.weight + j * ichor.weight + i * panacea.weight;
current.volume := k * gold.volume + j * ichor.volume + i * panacea.volume;
if (current.value > maxvalue) and
(current.weight <= sack.weight) and
(current.volume <= sack.volume) then
begin
maxvalue := current.value;
totalweight := current.weight;
totalvolume := current.volume;
n[1] := i;
n[2] := j;
n[3] := k;
end;
end;
writeln ('Maximum value achievable is ', maxValue);
writeln ('This is achieved by carrying ', n[1], ' panacea, ', n[2], ' ichor and ', n[3], ' gold items');
writeln ('The weight of this carry is ', totalWeight:6:3, ' and the volume used is ', totalVolume:6:4);
end.

View file

@ -0,0 +1,41 @@
class KnapsackItem {
has $.volume;
has $.weight;
has $.value;
has $.name;
method new($volume,$weight,$value, $name) {
self.bless(*, :$volume, :$weight, :$value, :$name)
}
};
my KnapsackItem $panacea .= new: 0.025, 0.3, 3000, "panacea";
my KnapsackItem $ichor .= new: 0.015, 0.2, 1800, "ichor";
my KnapsackItem $gold .= new: 0.002, 2.0, 2500, "gold";
my KnapsackItem $maximum .= new: 0.25, 25, 0 , "max";
my $max_val = 0;
my @solutions;
my %max_items;
for $panacea, $ichor, $gold -> $item {
%max_items{$item.name} = floor [min]
$maximum.volume / $item.volume,
$maximum.weight / $item.weight;
}
for 0..%max_items<panacea>
X 0..%max_items<ichor>
X 0..%max_items<gold>
-> $p, $i, $g
{
next if $panacea.volume * $p + $ichor.volume * $i + $gold.volume * $g > $maximum.volume;
next if $panacea.weight * $p + $ichor.weight * $i + $gold.weight * $g > $maximum.weight;
given $panacea.value * $p + $ichor.value * $i + $gold.value * $g {
if $_ > $max_val { $max_val = $_; @solutions = (); }
when $max_val { @solutions.push: [$p,$i,$g] }
}
}
say "maximum value is $max_val\npossible solutions:";
say "panacea\tichor\tgold";
.join("\t").say for @solutions;

View file

@ -0,0 +1,82 @@
Define.f TotalWeight, TotalVolyme
Define.i maxPanacea, maxIchor, maxGold, maxValue
Define.i i, j ,k
Dim n.i(2)
Enumeration
#Panacea
#Ichor
#Gold
#Sack
#Current
EndEnumeration
Structure Bounty
value.i
weight.f
volyme.f
EndStructure
Dim Item.Bounty(4)
CopyMemory(?panacea,@Item(#Panacea),SizeOf(Bounty))
CopyMemory(?ichor, @Item(#Ichor), SizeOf(Bounty))
CopyMemory(?gold, @Item(#gold), SizeOf(Bounty))
CopyMemory(?sack, @Item(#Sack), SizeOf(Bounty))
Procedure.f min(a.f, b.f)
If a<b
ProcedureReturn a
Else
ProcedureReturn b
EndIf
EndProcedure
maxPanacea=min(Item(#Sack)\weight/Item(#Panacea)\weight,Item(#Sack)\volyme/Item(#Panacea)\volyme)
maxIchor =min(Item(#Sack)\weight/Item(#Ichor)\weight, Item(#Sack)\volyme/Item(#Ichor)\volyme)
maxGold =min(Item(#Sack)\weight/Item(#Gold)\weight, Item(#Sack)\volyme/Item(#Gold)\volyme)
For i=0 To maxPanacea
For j=0 To maxIchor
For k=0 To maxGold
Item(#Current)\value=k*Item(#Gold)\value +j*item(#Ichor)\value +i*item(#Panacea)\value
Item(#Current)\weight=k*Item(#Gold)\weight+j*Item(#Ichor)\weight+i*Item(#Panacea)\weight
Item(#Current)\volyme=k*Item(#Gold)\volyme+j*Item(#Ichor)\volyme+i*Item(#Panacea)\volyme
If Item(#Current)\weight>Item(#Sack)\weight Or Item(#Current)\volyme>Item(#Sack)\volyme
Continue
EndIf
If Item(#Current)\value>maxValue
maxValue=Item(#Current)\value
TotalWeight=Item(#Current)\weight
TotalVolyme=Item(#Current)\volyme
n(#Panacea)=i: n(#Ichor)=j: n(#Gold)=k
EndIf
Next k
Next j
Next i
If OpenConsole()
Define txt$
txt$="Maximum value achievable is "+Str(maxValue)+#CRLF$
txt$+"This is achieved by carrying "+Str(n(#Panacea))+" panacea, "
txt$+Str(n(#Ichor))+" ichor and "+Str(n(#Gold))+" gold items."+#CRLF$
txt$+"The weight to carry is "+StrF(totalWeight,2)
txt$+" and the volume used is "+StrF(TotalVolyme,2)
PrintN(txt$)
Print(#CRLF$+"Press Enter to quit"): Input()
EndIf
DataSection
panacea:
Data.i 3000
Data.f 0.3, 0.025
ichor:
Data.i 1800
Data.f 0.2, 0.015
gold:
Data.i 2500
Data.f 2.0, 0.002
sack:
Data.i 0
Data.f 25.0, 0.25
EndDataSection

View file

@ -0,0 +1,30 @@
data one;
wtpanacea=0.3; wtichor=0.2; wtgold=2.0;
volpanacea=0.025; volichor=0.015; volgold=0.002;
valpanacea=3000; valichor=1800; valgold=2500;
maxwt=25; maxvol=0.25;
/* we can prune the possible selections */
maxpanacea = floor(min(maxwt/wtpanacea, maxvol/volpanacea));
maxichor = floor(min(maxwt/wtichor, maxvol/volichor));
maxgold = floor(min(maxwt/wtgold, maxvol/volgold));
do i1 = 0 to maxpanacea;
do i2 = 0 to maxichor;
do i3 = 0 to maxgold;
panacea = i1; ichor=i2; gold=i3; output;
end;
end;
end;
run;
data one; set one;
vals = valpanacea*panacea + valichor*ichor + valgold*gold;
totalweight = wtpanacea*panacea + wtichor*ichor + wtgold*gold;
totalvolume = volpanacea*panacea + volichor*ichor + volgold*gold;
if (totalweight le maxwt) and (totalvolume le maxvol);
run;
proc sort data=one;
by descending vals;
run;
proc print data=one (obs=4);
var panacea ichor gold vals;
run;

View file

@ -0,0 +1,14 @@
#import nat
#import flo
vol = iprod/<0.025,0.015,0.002>+ float*
val = iprod/<3000.,1800.,2500.>+ float*
wgt = iprod/<0.3,0.2,2.0>+ float*
packings = ~&lrlrNCCPCS ~&K0=> iota* <11,17,13>
solutions = fleq$^rS&hl |=&l ^(val,~&)* (fleq\25.+ wgt)*~ (fleq\0.25+ vol)*~ packings
#cast %nmL
human_readable = ~&p/*<'panacea','ichor','gold'> solutions