langs a-z
This commit is contained in:
parent
db842d013d
commit
d066446780
11389 changed files with 98361 additions and 1020 deletions
|
|
@ -0,0 +1,110 @@
|
|||
type KnapSackItem string name,sys dag,value,tag
|
||||
|
||||
KnapSackItem it[100]
|
||||
|
||||
sys dmax=400
|
||||
sys items=22
|
||||
|
||||
it=>
|
||||
|
||||
"map", 9, 150, 0,
|
||||
"compass", 13, 35, 0,
|
||||
"water", 153, 200, 0,
|
||||
"sandwich", 50, 160, 0,
|
||||
"glucose", 15, 60, 0,
|
||||
"tin", 68, 45, 0,
|
||||
"banana", 27, 60, 0,
|
||||
"apple", 39, 40, 0,
|
||||
"cheese", 23, 30, 0,
|
||||
"beer", 52, 10, 0,
|
||||
"suntan cream", 11, 70, 0,
|
||||
"camera", 32, 30, 0,
|
||||
"T-shirt", 24, 15, 0,
|
||||
"trousers", 48, 10, 0,
|
||||
"umbrella", 73, 40, 0,
|
||||
"waterproof trousers", 42, 70, 0,
|
||||
"waterproof overclothes",43, 75, 0,
|
||||
"note-case", 22, 80, 0,
|
||||
"sunglasses", 7, 20, 0,
|
||||
"towel", 18, 12, 0,
|
||||
"socks", 4, 50, 0,
|
||||
"book", 30, 10, 0
|
||||
|
||||
tot=0
|
||||
for i=1 to items
|
||||
tot+=it(i).dag
|
||||
next
|
||||
xs=tot-dmax
|
||||
|
||||
'REMOVE LOWEST PRIORITY ITEMS TILL XS<=0
|
||||
|
||||
cr=chr(13)+chr(10)
|
||||
tab=chr(9)
|
||||
pr="remove: " cr
|
||||
c=0
|
||||
|
||||
do
|
||||
v=1e9
|
||||
w=0
|
||||
k=0
|
||||
'
|
||||
'FIND NEXT LEAST VALUE ITEM
|
||||
'
|
||||
for i=1 to items
|
||||
if it[i].tag=0
|
||||
'w=it[i].value 'TEST PRIORITY ONLY
|
||||
w=1000*it[i].value/it[i].dag 'TEST PRIORIT/WEIGHT VALUE
|
||||
if w<v then v=w : k=i
|
||||
end if
|
||||
next
|
||||
'
|
||||
'LOG AND REMOVE FROM LIST
|
||||
'
|
||||
if k
|
||||
xs-=it[k].dag 'deduct from excess weight
|
||||
it[k].tag=1
|
||||
pr+=it(k).name tab it(k).dag tab it(k).value cr
|
||||
if xs<=0 then exit do 'Weight within dmax
|
||||
end if
|
||||
c++
|
||||
if c>=items then exit do
|
||||
end do
|
||||
'
|
||||
pr+=cr "Knapsack contents: " cr
|
||||
'
|
||||
for i=1 to items
|
||||
if it(i).tag=0
|
||||
pr+=it(i).name tab it(i).dag tab it(i).value cr
|
||||
end if
|
||||
next
|
||||
|
||||
'TRY FITTING IN LOWER PRIORITY ITEMS
|
||||
|
||||
av=-xs
|
||||
|
||||
for i=1 to items
|
||||
if it[i].tag
|
||||
if av-it[i].dag > 0 then
|
||||
pr+="Can include: " it(i).name tab it(i).dag tab it(i).value cr
|
||||
av-=it[i].dag
|
||||
end if
|
||||
end if
|
||||
next
|
||||
pr+=cr "Weight: " dmax+xs
|
||||
'putfile "s.txt",pr
|
||||
print pr
|
||||
'Knapsack contents:
|
||||
'map 9 150
|
||||
'compass 13 35
|
||||
'water 153 200
|
||||
'sandwich 50 160
|
||||
'glucose 15 60
|
||||
'banana 27 60
|
||||
'suntan cream 11 70
|
||||
'waterproof trousers 42 70
|
||||
'waterproof overclothes 43 75
|
||||
'note-case 22 80
|
||||
'sunglasses 7 20
|
||||
'socks 4 50
|
||||
'
|
||||
'Weight: 396
|
||||
69
Task/Knapsack-problem-Bounded/Oz/knapsack-problem-bounded.oz
Normal file
69
Task/Knapsack-problem-Bounded/Oz/knapsack-problem-bounded.oz
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
declare
|
||||
%% maps items to tuples of
|
||||
%% Weight(hectogram), Value and available Pieces
|
||||
Problem = knapsack('map':9#150#1
|
||||
'compass':13#35#1
|
||||
'water':153#200#2
|
||||
'sandwich':50#60#2
|
||||
'glucose':15#60#2
|
||||
'tin':68#45#3
|
||||
'banana':27#60#3
|
||||
'apple':39#40#3
|
||||
'cheese':23#30#1
|
||||
'beer':52#10#3
|
||||
'suntan cream':11#70#1
|
||||
'camera':32#30#1
|
||||
't-shirt':24#15#2
|
||||
'trousers':48#10#2
|
||||
'umbrella':73#40#1
|
||||
'waterproof trousers':42#70#1
|
||||
'waterproof overclothes':43#75#1
|
||||
'note-case':22#80#1
|
||||
'sunglasses':7#20#1
|
||||
'towel':18#12#2
|
||||
'socks':4#50#1
|
||||
'book':30#10#2
|
||||
)
|
||||
|
||||
%% item -> Weight
|
||||
Weights = {Record.map Problem fun {$ X} X.1 end}
|
||||
%% item -> Value
|
||||
Values = {Record.map Problem fun {$ X} X.2 end}
|
||||
|
||||
proc {Knapsack Solution}
|
||||
%% a solution maps items to finite domain variables
|
||||
%% whose maximum values depend on the item type
|
||||
Solution = {Record.map Problem fun {$ _#_#Max} {FD.int 0#Max} end}
|
||||
%% no more than 400 hectograms
|
||||
{FD.sumC Weights Solution '=<:' 400}
|
||||
%% search through valid solutions
|
||||
{FD.distribute naive Solution}
|
||||
end
|
||||
|
||||
proc {PropagateLargerValue Old New}
|
||||
%% propagate that new solutions must yield a higher value
|
||||
%% than previously found solutions (essential for performance)
|
||||
{FD.sumC Values New '>:' {Value Old}}
|
||||
end
|
||||
|
||||
fun {Value Candidate}
|
||||
{Record.foldL {Record.zip Candidate Values Number.'*'} Number.'+' 0}
|
||||
end
|
||||
|
||||
fun {Weight Candidate}
|
||||
{Record.foldL {Record.zip Candidate Weights Number.'*'} Number.'+' 0}
|
||||
end
|
||||
|
||||
[Best] = {SearchBest Knapsack PropagateLargerValue}
|
||||
in
|
||||
{System.showInfo "Items: "}
|
||||
{Record.forAllInd Best
|
||||
proc {$ I V}
|
||||
if V > 0 then
|
||||
{System.showInfo I#": "#V}
|
||||
end
|
||||
end
|
||||
}
|
||||
{System.printInfo "\n"}
|
||||
{System.showInfo "total value: "#{Value Best}}
|
||||
{System.showInfo "total weight: "#{Weight Best}}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
my class KnapsackItem { has $.name; has $.weight; has $.unit; }
|
||||
|
||||
multi sub pokem ([], $, $v = 0) { $v }
|
||||
multi sub pokem ([$, *@], 0, $v = 0) { $v }
|
||||
multi sub pokem ([$i, *@rest], $w, $v = 0) {
|
||||
my $key = "{+@rest} $w $v";
|
||||
(state %cache){$key} or do {
|
||||
my @skip = pokem @rest, $w, $v;
|
||||
if $w >= $i.weight { # next one fits
|
||||
my @put = pokem @rest, $w - $i.weight, $v + $i.unit;
|
||||
return (%cache{$key} = @put, $i.name).list if @put[0] > @skip[0];
|
||||
}
|
||||
return (%cache{$key} = @skip).list;
|
||||
}
|
||||
}
|
||||
|
||||
my $MAX_WEIGHT = 400;
|
||||
my @table = map -> $name, $weight, $unit, $count {
|
||||
KnapsackItem.new( :$name, :$weight, :$unit ) xx $count;
|
||||
},
|
||||
'map', 9, 150, 1,
|
||||
'compass', 13, 35, 1,
|
||||
'water', 153, 200, 2,
|
||||
'sandwich', 50, 60, 2,
|
||||
'glucose', 15, 60, 2,
|
||||
'tin', 68, 45, 3,
|
||||
'banana', 27, 60, 3,
|
||||
'apple', 39, 40, 3,
|
||||
'cheese', 23, 30, 1,
|
||||
'beer', 52, 10, 3,
|
||||
'suntan cream', 11, 70, 1,
|
||||
'camera', 32, 30, 1,
|
||||
'T-shirt', 24, 15, 2,
|
||||
'trousers', 48, 10, 2,
|
||||
'umbrella', 73, 40, 1,
|
||||
'waterproof trousers', 42, 70, 1,
|
||||
'waterproof overclothes', 43, 75, 1,
|
||||
'note-case', 22, 80, 1,
|
||||
'sunglasses', 7, 20, 1,
|
||||
'towel', 18, 12, 2,
|
||||
'socks', 4, 50, 1,
|
||||
'book', 30, 10, 2,
|
||||
;
|
||||
|
||||
my ($value, @result) = pokem @table, $MAX_WEIGHT;
|
||||
|
||||
(my %hash){$_}++ for @result;
|
||||
|
||||
say "Value = $value";
|
||||
say "Tourist put in the bag:";
|
||||
say " # ITEM";
|
||||
for %hash.kv -> $item, $number {
|
||||
say " $number $item";
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
#import std
|
||||
#import flo
|
||||
#import lin
|
||||
|
||||
items = # name: (weight,value,limit)
|
||||
|
||||
<
|
||||
'map': (9,150,1),
|
||||
'compass': (13,35,1),
|
||||
'water': (153,200,3),
|
||||
'sandwich': (50,60,2),
|
||||
'glucose': (15,60,2),
|
||||
'tin': (68,45,3),
|
||||
'banana': (27,60,3),
|
||||
'apple': (39,40,3),
|
||||
'cheese': (23,30,1),
|
||||
'beer': (52,10,3),
|
||||
'suntan cream': (11,70,1),
|
||||
'camera': (32,30,1),
|
||||
't-shirt': (24,15,2),
|
||||
'trousers': (48,10,2),
|
||||
'umbrella': (73,40,1),
|
||||
'waterproof trousers': (42,70,1),
|
||||
'waterproof overclothes': (43,75,1),
|
||||
'note-case': (22,80,1),
|
||||
'sunglasses': (7,20,1),
|
||||
'towel': (18,12,2),
|
||||
'socks': (4,50,1),
|
||||
'book': (30,10,2)>
|
||||
|
||||
system = # convert the item list to mixed integer programming problem specification
|
||||
|
||||
linear_system$[
|
||||
integers: ~&nS,
|
||||
upper_bounds: * ^|/~& float@rr,
|
||||
lower_bounds: @nS ~&\*0.+ :/'(slack)',
|
||||
costs: * ^|/~& negative+ float@rl,
|
||||
equations: ~&iNC\400.+ :/(1.,'(slack)')+ * ^|rlX/~& float@l]
|
||||
|
||||
format = @t --^*p\pad` @nS @mS printf/*'%0.0f '
|
||||
|
||||
#show+
|
||||
|
||||
main = format solution system items
|
||||
Loading…
Add table
Add a link
Reference in a new issue