Data update
This commit is contained in:
parent
4bb20c9b71
commit
cbaf4c4b64
12390 changed files with 318560 additions and 27248 deletions
|
|
@ -0,0 +1,65 @@
|
|||
with Ada.Text_IO;
|
||||
|
||||
procedure Knapsack_Unbounded is
|
||||
|
||||
type Bounty is record
|
||||
Value : Natural;
|
||||
Weight : Float;
|
||||
Volume : Float;
|
||||
end record;
|
||||
|
||||
function Min (A, B : Float) return Float is
|
||||
begin
|
||||
if A < B then
|
||||
return A;
|
||||
else
|
||||
return B;
|
||||
end if;
|
||||
end Min;
|
||||
|
||||
Panacea : Bounty := (3000, 0.3, 0.025);
|
||||
Ichor : Bounty := (1800, 0.2, 0.015);
|
||||
Gold : Bounty := (2500, 2.0, 0.002);
|
||||
Limits : Bounty := ( 0, 25.0, 0.250);
|
||||
Best : Bounty := ( 0, 0.0, 0.000);
|
||||
Current : Bounty := ( 0, 0.0, 0.000);
|
||||
|
||||
Best_Amounts : array (1 .. 3) of Natural := (0, 0, 0);
|
||||
|
||||
Max_Panacea : Natural := Natural (Float'Floor (Min
|
||||
(Limits.Weight / Panacea.Weight,
|
||||
Limits.Volume / Panacea.Volume)));
|
||||
Max_Ichor : Natural := Natural (Float'Floor (Min
|
||||
(Limits.Weight / Ichor.Weight,
|
||||
Limits.Volume / Ichor.Volume)));
|
||||
Max_Gold : Natural := Natural (Float'Floor (Min
|
||||
(Limits.Weight / Gold.Weight,
|
||||
Limits.Volume / Gold.Volume)));
|
||||
|
||||
begin
|
||||
for Panacea_Count in 0 .. Max_Panacea loop
|
||||
for Ichor_Count in 0 .. Max_Ichor loop
|
||||
for Gold_Count in 0 .. Max_Gold loop
|
||||
Current.Value := Panacea_Count * Panacea.Value +
|
||||
Ichor_Count * Ichor.Value +
|
||||
Gold_Count * Gold.Value;
|
||||
Current.Weight := Float (Panacea_Count) * Panacea.Weight +
|
||||
Float (Ichor_Count) * Ichor.Weight +
|
||||
Float (Gold_Count) * Gold.Weight;
|
||||
Current.Volume := Float (Panacea_Count) * Panacea.Volume +
|
||||
Float (Ichor_Count) * Ichor.Volume +
|
||||
Float (Gold_Count) * Gold.Volume;
|
||||
if Current.Value > Best.Value and
|
||||
Current.Weight <= Limits.Weight and
|
||||
Current.Volume <= Limits.Volume then
|
||||
Best := Current;
|
||||
Best_Amounts := (Panacea_Count, Ichor_Count, Gold_Count);
|
||||
end if;
|
||||
end loop;
|
||||
end loop;
|
||||
end loop;
|
||||
Ada.Text_IO.Put_Line ("Maximum value:" & Natural'Image (Best.Value));
|
||||
Ada.Text_IO.Put_Line ("Panacea:" & Natural'Image (Best_Amounts (1)));
|
||||
Ada.Text_IO.Put_Line ("Ichor: " & Natural'Image (Best_Amounts (2)));
|
||||
Ada.Text_IO.Put_Line ("Gold: " & Natural'Image (Best_Amounts (3)));
|
||||
end Knapsack_Unbounded;
|
||||
|
|
@ -7,16 +7,16 @@
|
|||
#include <vector>
|
||||
|
||||
struct Item {
|
||||
std::string name;
|
||||
int32_t value;
|
||||
double weight;
|
||||
double volume;
|
||||
std::string name;
|
||||
int32_t value;
|
||||
double weight;
|
||||
double volume;
|
||||
};
|
||||
|
||||
const std::vector<Item> items = {
|
||||
Item("panacea", 3000, 0.3, 0.025),
|
||||
Item("ichor", 1800, 0.2, 0.015),
|
||||
Item("gold", 2500, 2.0, 0.002)
|
||||
Item("panacea", 3000, 0.3, 0.025),
|
||||
Item("ichor", 1800, 0.2, 0.015),
|
||||
Item("gold", 2500, 2.0, 0.002)
|
||||
};
|
||||
constexpr double MAX_WEIGHT = 25.0;
|
||||
constexpr double MAX_VOLUME = 0.25;
|
||||
|
|
@ -51,35 +51,35 @@ void knapsack(const uint64_t& i, const int32_t& value, const double& weight, con
|
|||
}
|
||||
|
||||
int main() {
|
||||
knapsack(0, 0, MAX_WEIGHT, MAX_VOLUME);
|
||||
std::cout << "Item Chosen Number Value Weight Volume" << std::endl;
|
||||
std::cout << "----------- ------ ----- ------ ------" << std::endl;
|
||||
int32_t item_count = 0;
|
||||
int32_t number_sum = 0;
|
||||
double weight_sum = 0.0;
|
||||
double volume_sum = 0.0;
|
||||
|
||||
for ( uint64_t i = 0; i < items.size(); ++i ) {
|
||||
if ( best[i] == 0 ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
item_count++;
|
||||
std::string name = items[i].name;
|
||||
int32_t number = best[i];
|
||||
int32_t value = items[i].value * number;
|
||||
double weight = items[i].weight * number;
|
||||
double volume = items[i].volume * number;
|
||||
number_sum += number;
|
||||
weight_sum += weight;
|
||||
volume_sum += volume;
|
||||
|
||||
std::cout << std::setw(11) << name << std::setw(6) << number << std::setw(8) << value << std::fixed
|
||||
<< std::setw(8) << std::setprecision(2) << weight
|
||||
<< std::setw(8) << std::setprecision(2) << volume << std::endl;
|
||||
}
|
||||
|
||||
std::cout << "----------- ------ ----- ------ ------" << std::endl;
|
||||
std::cout << std::setw(5) << item_count << " items" << std::setw(6) << number_sum << std::setw(8) << best_value
|
||||
<< std::setw(8) << weight_sum << std::setw(8) << volume_sum << std::endl;
|
||||
knapsack(0, 0, MAX_WEIGHT, MAX_VOLUME);
|
||||
std::cout << "Item Chosen Number Value Weight Volume" << std::endl;
|
||||
std::cout << "----------- ------ ----- ------ ------" << std::endl;
|
||||
int32_t item_count = 0;
|
||||
int32_t number_sum = 0;
|
||||
double weight_sum = 0.0;
|
||||
double volume_sum = 0.0;
|
||||
|
||||
for ( uint64_t i = 0; i < items.size(); ++i ) {
|
||||
if ( best[i] == 0 ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
item_count++;
|
||||
std::string name = items[i].name;
|
||||
int32_t number = best[i];
|
||||
int32_t value = items[i].value * number;
|
||||
double weight = items[i].weight * number;
|
||||
double volume = items[i].volume * number;
|
||||
number_sum += number;
|
||||
weight_sum += weight;
|
||||
volume_sum += volume;
|
||||
|
||||
std::cout << std::setw(11) << name << std::setw(6) << number << std::setw(8) << value << std::fixed
|
||||
<< std::setw(8) << std::setprecision(2) << weight
|
||||
<< std::setw(8) << std::setprecision(2) << volume << std::endl;
|
||||
}
|
||||
|
||||
std::cout << "----------- ------ ----- ------ ------" << std::endl;
|
||||
std::cout << std::setw(5) << item_count << " items" << std::setw(6) << number_sum << std::setw(8) << best_value
|
||||
<< std::setw(8) << weight_sum << std::setw(8) << volume_sum << std::endl;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,35 +31,35 @@
|
|||
|
||||
;; compute best quantity.score (i), assuming best (i-1 p v) is known
|
||||
(define (score-qty i p v (q) (score)(smax)(qmax))
|
||||
(or
|
||||
(t-get i p v) ;; already known
|
||||
(begin
|
||||
(set! q (min (quotient p (poids i)) (quotient v (volume i)))) ;; max possible q
|
||||
(set! smax -Infinity)
|
||||
( for ((k (1+ q))) ;; try all legal quantities
|
||||
(set! score (+
|
||||
(first (score-qty (1- i) (- p (* k (poids i))) (- v (* k (volume i)))))
|
||||
(* k (valeur i))))
|
||||
#:continue (< score smax)
|
||||
(set! smax score)
|
||||
(set! qmax k))
|
||||
(hash-set H (t-key i p v) (cons smax qmax)))))
|
||||
|
||||
|
||||
(or
|
||||
(t-get i p v) ;; already known
|
||||
(begin
|
||||
(set! q (min (quotient p (poids i)) (quotient v (volume i)))) ;; max possible q
|
||||
(set! smax -Infinity)
|
||||
( for ((k (1+ q))) ;; try all legal quantities
|
||||
(set! score (+
|
||||
(first (score-qty (1- i) (- p (* k (poids i))) (- v (* k (volume i)))))
|
||||
(* k (valeur i))))
|
||||
#:continue (< score smax)
|
||||
(set! smax score)
|
||||
(set! qmax k))
|
||||
(hash-set H (t-key i p v) (cons smax qmax)))))
|
||||
|
||||
|
||||
;; compute best scores, starting from last item
|
||||
(define (task P V)
|
||||
(define N (1- (table-count T)))
|
||||
(define qty 0)
|
||||
(set! H (make-hash))
|
||||
(writeln 'total-value (first (score-qty N P V)))
|
||||
|
||||
(for/list ((i (in-range N -1 -1)))
|
||||
(set! qty (rest (t-get i P V)))
|
||||
#:continue (= qty 0)
|
||||
(begin0
|
||||
(cons (name i) (t-get i P V))
|
||||
(set! P (- P (* (poids i) qty)))
|
||||
(set! V (- V (* (volume i) qty))))))
|
||||
(writeln 'total-value (first (score-qty N P V)))
|
||||
|
||||
(for/list ((i (in-range N -1 -1)))
|
||||
(set! qty (rest (t-get i P V)))
|
||||
#:continue (= qty 0)
|
||||
(begin0
|
||||
(cons (name i) (t-get i P V))
|
||||
(set! P (- P (* (poids i) qty)))
|
||||
(set! V (- V (* (volume i) qty))))))
|
||||
|
||||
;; output
|
||||
(task 25000 250)
|
||||
|
|
|
|||
|
|
@ -1,82 +1,82 @@
|
|||
class
|
||||
KNAPSACK
|
||||
KNAPSACK
|
||||
|
||||
create
|
||||
make
|
||||
make
|
||||
|
||||
feature
|
||||
|
||||
make
|
||||
do
|
||||
create panacea;
|
||||
panacea := [3000, 0.3, 0.025]
|
||||
create ichor;
|
||||
ichor := [1800, 0.2, 0.015]
|
||||
create gold;
|
||||
gold := [2500, 2.0, 0.002]
|
||||
create sack;
|
||||
sack := [0, 25.0, 0.25]
|
||||
find_solution
|
||||
end
|
||||
make
|
||||
do
|
||||
create panacea;
|
||||
panacea := [3000, 0.3, 0.025]
|
||||
create ichor;
|
||||
ichor := [1800, 0.2, 0.015]
|
||||
create gold;
|
||||
gold := [2500, 2.0, 0.002]
|
||||
create sack;
|
||||
sack := [0, 25.0, 0.25]
|
||||
find_solution
|
||||
end
|
||||
|
||||
feature {NONE}
|
||||
|
||||
panacea: TUPLE [value: INTEGER; weight: REAL_64; volume: REAL_64]
|
||||
panacea: TUPLE [value: INTEGER; weight: REAL_64; volume: REAL_64]
|
||||
|
||||
ichor: TUPLE [value: INTEGER; weight: REAL_64; volume: REAL_64]
|
||||
ichor: TUPLE [value: INTEGER; weight: REAL_64; volume: REAL_64]
|
||||
|
||||
gold: TUPLE [value: INTEGER; weight: REAL_64; volume: REAL_64]
|
||||
gold: TUPLE [value: INTEGER; weight: REAL_64; volume: REAL_64]
|
||||
|
||||
sack: TUPLE [value: INTEGER; weight: REAL_64; volume: REAL_64]
|
||||
sack: TUPLE [value: INTEGER; weight: REAL_64; volume: REAL_64]
|
||||
|
||||
find_solution
|
||||
-- Solution for unbounded Knapsack Problem.
|
||||
local
|
||||
totalweight, totalvolume: REAL_64
|
||||
maxpanacea, maxichor, maxvalue, maxgold: INTEGER
|
||||
n: ARRAY [INTEGER]
|
||||
r: TUPLE [value: INTEGER; weight: REAL_64; volume: REAL_64]
|
||||
do
|
||||
maxpanacea := minimum (sack.weight / panacea.weight, sack.volume / panacea.volume).rounded
|
||||
maxichor := minimum (sack.weight / ichor.weight, sack.volume / ichor.volume).rounded
|
||||
maxgold := minimum (sack.weight / gold.weight, sack.volume / gold.volume).rounded
|
||||
create n.make_filled (0, 1, 3)
|
||||
create r
|
||||
across
|
||||
0 |..| maxpanacea as p
|
||||
loop
|
||||
across
|
||||
0 |..| maxichor as i
|
||||
loop
|
||||
across
|
||||
0 |..| maxgold as g
|
||||
loop
|
||||
r.value := g.item * gold.value + i.item * ichor.value + p.item * panacea.value
|
||||
r.weight := g.item * gold.weight + i.item * ichor.weight + p.item * panacea.weight
|
||||
r.volume := g.item * gold.volume + i.item * ichor.volume + p.item * panacea.volume
|
||||
if r.value > maxvalue and r.weight <= sack.weight and r.volume <= sack.volume then
|
||||
maxvalue := r.value
|
||||
totalweight := r.weight
|
||||
totalvolume := r.volume
|
||||
n [1] := p.item
|
||||
n [2] := i.item
|
||||
n [3] := g.item
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
io.put_string ("Maximum value achievable is " + maxValue.out + ".%N")
|
||||
io.put_string ("This is achieved by carrying " + n [1].out + " panacea, " + n [2].out + " ichor and " + n [3].out + " gold.%N")
|
||||
io.put_string ("The weight is " + totalweight.out + " and the volume is " + totalvolume.truncated_to_real.out + ".")
|
||||
end
|
||||
find_solution
|
||||
-- Solution for unbounded Knapsack Problem.
|
||||
local
|
||||
totalweight, totalvolume: REAL_64
|
||||
maxpanacea, maxichor, maxvalue, maxgold: INTEGER
|
||||
n: ARRAY [INTEGER]
|
||||
r: TUPLE [value: INTEGER; weight: REAL_64; volume: REAL_64]
|
||||
do
|
||||
maxpanacea := minimum (sack.weight / panacea.weight, sack.volume / panacea.volume).rounded
|
||||
maxichor := minimum (sack.weight / ichor.weight, sack.volume / ichor.volume).rounded
|
||||
maxgold := minimum (sack.weight / gold.weight, sack.volume / gold.volume).rounded
|
||||
create n.make_filled (0, 1, 3)
|
||||
create r
|
||||
across
|
||||
0 |..| maxpanacea as p
|
||||
loop
|
||||
across
|
||||
0 |..| maxichor as i
|
||||
loop
|
||||
across
|
||||
0 |..| maxgold as g
|
||||
loop
|
||||
r.value := g.item * gold.value + i.item * ichor.value + p.item * panacea.value
|
||||
r.weight := g.item * gold.weight + i.item * ichor.weight + p.item * panacea.weight
|
||||
r.volume := g.item * gold.volume + i.item * ichor.volume + p.item * panacea.volume
|
||||
if r.value > maxvalue and r.weight <= sack.weight and r.volume <= sack.volume then
|
||||
maxvalue := r.value
|
||||
totalweight := r.weight
|
||||
totalvolume := r.volume
|
||||
n [1] := p.item
|
||||
n [2] := i.item
|
||||
n [3] := g.item
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
io.put_string ("Maximum value achievable is " + maxValue.out + ".%N")
|
||||
io.put_string ("This is achieved by carrying " + n [1].out + " panacea, " + n [2].out + " ichor and " + n [3].out + " gold.%N")
|
||||
io.put_string ("The weight is " + totalweight.out + " and the volume is " + totalvolume.truncated_to_real.out + ".")
|
||||
end
|
||||
|
||||
minimum (a, b: REAL_64): REAL_64
|
||||
-- Smaller of 'a' and 'b'.
|
||||
do
|
||||
Result := a
|
||||
if a > b then
|
||||
Result := b
|
||||
end
|
||||
end
|
||||
minimum (a, b: REAL_64): REAL_64
|
||||
-- Smaller of 'a' and 'b'.
|
||||
do
|
||||
Result := a
|
||||
if a > b then
|
||||
Result := b
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,34 +1,34 @@
|
|||
0 VALUE vials
|
||||
0 VALUE ampules
|
||||
0 VALUE bars
|
||||
0 VALUE bag
|
||||
0 VALUE bag
|
||||
|
||||
#250 3 / #250 #25 / MIN 1+ CONSTANT maxvials
|
||||
#250 3 / #250 #25 / MIN 1+ CONSTANT maxvials
|
||||
#250 2/ #250 #15 / MIN 1+ CONSTANT maxampules
|
||||
#250 #20 / #250 2/ MIN 1+ CONSTANT maxbars
|
||||
#250 #20 / #250 2/ MIN 1+ CONSTANT maxbars
|
||||
|
||||
: RESULTS ( v a b -- k )
|
||||
3DUP #20 * SWAP 2* + SWAP 3 * + #250 > IF 3DROP -1 EXIT ENDIF
|
||||
3DUP 2* SWAP #15 * + SWAP #25 * + #250 > IF 3DROP -1 EXIT ENDIF
|
||||
#2500 * SWAP #1800 * + SWAP #3000 * + ;
|
||||
3DUP #20 * SWAP 2* + SWAP 3 * + #250 > IF 3DROP -1 EXIT ENDIF
|
||||
3DUP 2* SWAP #15 * + SWAP #25 * + #250 > IF 3DROP -1 EXIT ENDIF
|
||||
#2500 * SWAP #1800 * + SWAP #3000 * + ;
|
||||
|
||||
: .SOLUTION ( -- )
|
||||
CR ." The traveller's knapsack contains "
|
||||
vials DEC. ." vials of panacea, "
|
||||
ampules DEC. ." ampules of ichor, "
|
||||
CR bars DEC. ." bars of gold, a total value of "
|
||||
vials ampules bars RESULTS 0DEC.R ." ." ;
|
||||
CR ." The traveller's knapsack contains "
|
||||
vials DEC. ." vials of panacea, "
|
||||
ampules DEC. ." ampules of ichor, "
|
||||
CR bars DEC. ." bars of gold, a total value of "
|
||||
vials ampules bars RESULTS 0DEC.R ." ." ;
|
||||
|
||||
: KNAPSACK ( -- )
|
||||
-1 TO bag
|
||||
maxvials 0 ?DO
|
||||
maxampules 0 ?DO
|
||||
maxbars 0 ?DO
|
||||
-1 TO bag
|
||||
maxvials 0 ?DO
|
||||
maxampules 0 ?DO
|
||||
maxbars 0 ?DO
|
||||
K J I RESULTS DUP
|
||||
bag > IF TO bag K TO vials J TO ampules I TO bars
|
||||
ELSE DROP
|
||||
ENDIF
|
||||
LOOP
|
||||
LOOP
|
||||
LOOP
|
||||
.SOLUTION ;
|
||||
bag > IF TO bag K TO vials J TO ampules I TO bars
|
||||
ELSE DROP
|
||||
ENDIF
|
||||
LOOP
|
||||
LOOP
|
||||
LOOP
|
||||
.SOLUTION ;
|
||||
|
|
|
|||
|
|
@ -3,64 +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, 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
|
||||
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{
|
||||
{"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
|
||||
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, 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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ def knapsack($i; $value; $weight; $volume):
|
|||
then .bestValue = $value
|
||||
| reduce range(0; $n) as $j (.; .best[$j] = .count[$j])
|
||||
else .
|
||||
end
|
||||
end
|
||||
else (($weight / items[$i].weight)|floor) as $m1
|
||||
| (($volume / items[$i].volume)|floor) as $m2
|
||||
| .count[$i] = ([$m1, $m2] | min)
|
||||
|
|
@ -69,7 +69,7 @@ def solve($maxWeight; $maxVolume):
|
|||
| .sumNumber += .number
|
||||
| .sumWeight += .weight
|
||||
| .sumVolume += .volume
|
||||
| .emit += [ f(.name; .number; .value; .weight; .volume) ]
|
||||
| .emit += [ f(.name; .number; .value; .weight; .volume) ]
|
||||
else .
|
||||
end)
|
||||
| .emit[],
|
||||
|
|
|
|||
|
|
@ -22,8 +22,8 @@ data;
|
|||
|
||||
param : Items : weight value volume :=
|
||||
panacea 0.3 3000 0.025
|
||||
ichor 0.2 1800 0.015
|
||||
gold 2.0 2500 0.002
|
||||
ichor 0.2 1800 0.015
|
||||
gold 2.0 2500 0.002
|
||||
;
|
||||
|
||||
end;
|
||||
|
|
|
|||
|
|
@ -36,15 +36,15 @@ begin
|
|||
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.weight <= sack.weight) and
|
||||
(current.volume <= sack.volume) then
|
||||
begin
|
||||
begin
|
||||
maxvalue := current.value;
|
||||
totalweight := current.weight;
|
||||
totalvolume := current.volume;
|
||||
n[1] := i;
|
||||
n[2] := j;
|
||||
n[3] := k;
|
||||
n[2] := j;
|
||||
n[3] := k;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,68 @@
|
|||
require "table2"
|
||||
local fmt = require "fmt"
|
||||
|
||||
class item
|
||||
function __construct(public name, public value, public weight, public volume)
|
||||
end
|
||||
end
|
||||
|
||||
local items = {
|
||||
new item("panacea", 3000, 0.3, 0.025),
|
||||
new item("ichor", 1800, 0.2, 0.015),
|
||||
new item("gold", 2500, 2, 0.002)
|
||||
}
|
||||
|
||||
local n = #items
|
||||
local count = table.rep(n, 0)
|
||||
local best = table.rep(n, 0)
|
||||
local best_value = 0
|
||||
local max_weight = 25
|
||||
local max_volume = 0.25
|
||||
|
||||
local function knapsack(i, value, weight, volume)
|
||||
if i == n + 1 then
|
||||
if value > best_value then
|
||||
best_value = value
|
||||
for j = 1, n do best[j] = count[j] end
|
||||
end
|
||||
return
|
||||
end
|
||||
local m1 = weight // items[i].weight
|
||||
local m2 = volume // items[i].volume
|
||||
count[i] = math.min(m1, m2)
|
||||
while count[i] >= 0 do
|
||||
knapsack(
|
||||
i + 1,
|
||||
value + count[i] * items[i].value,
|
||||
weight - count[i] * items[i].weight,
|
||||
volume - count[i] * items[i].volume
|
||||
)
|
||||
count[i] -= 1
|
||||
end
|
||||
end
|
||||
|
||||
knapsack(1, 0, max_weight, max_volume)
|
||||
print("Item Chosen Number Value Weight Volume")
|
||||
print("----------- ------ ----- ------ ------")
|
||||
local item_count = 0
|
||||
local sum_number = 0
|
||||
local sum_weight = 0
|
||||
local sum_volume = 0
|
||||
for i = 1, n do
|
||||
if best[i] != 0 then
|
||||
item_count += 1
|
||||
local name = items[i].name
|
||||
local number = best[i]
|
||||
local value = items[i].value * number
|
||||
local weight = items[i].weight * number
|
||||
local volume = items[i].volume * number
|
||||
sum_number += number
|
||||
sum_weight += weight
|
||||
sum_volume += volume
|
||||
local f = "%-11s %2d %5.0f %4.1f %4.2f"
|
||||
fmt.print(f, name, number, value, weight, volume)
|
||||
end
|
||||
end
|
||||
print("----------- ------ ----- ------ ------")
|
||||
local f = "%d items %2d %5.0f %4.1f %4.2f"
|
||||
fmt.print(f, item_count, sum_number, best_value, sum_weight, sum_volume)
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
# Define the items to pack
|
||||
$Item = @(
|
||||
[pscustomobject]@{ Name = 'panacea'; Unit = 'vials' ; value = 3000; Weight = 0.3; Volume = 0.025 }
|
||||
[pscustomobject]@{ Name = 'ichor' ; Unit = 'ampules'; value = 1800; Weight = 0.2; Volume = 0.015 }
|
||||
[pscustomobject]@{ Name = 'gold' ; Unit = 'bars' ; value = 2500; Weight = 2.0; Volume = 0.002 }
|
||||
)
|
||||
|
||||
# Define our maximums
|
||||
$MaxWeight = 25
|
||||
$MaxVolume = 0.25
|
||||
|
||||
# Set our default value to beat
|
||||
$OptimalValue = 0
|
||||
|
||||
# Iterate through the possible quantities of item 0, without going over the weight or volume limit
|
||||
ForEach ( $Qty0 in 0..( [math]::Min( [math]::Truncate( $MaxWeight / $Item[0].Weight ), [math]::Truncate( $MaxVolume / $Item[0].Volume ) ) ) )
|
||||
{
|
||||
# Calculate the remaining space
|
||||
$RemainingWeight = $MaxWeight - $Qty0 * $Item[0].Weight
|
||||
$RemainingVolume = $MaxVolume - $Qty0 * $Item[0].Volume
|
||||
|
||||
# Iterate through the possible quantities of item 1, without going over the weight or volume limit
|
||||
ForEach ( $Qty1 in 0..( [math]::Min( [math]::Truncate( $RemainingWeight / $Item[1].Weight ), [math]::Truncate( $RemainingVolume / $Item[1].Volume ) ) ) )
|
||||
{
|
||||
# Calculate the remaining space
|
||||
$RemainingWeight2 = $RemainingWeight - $Qty1 * $Item[1].Weight
|
||||
$RemainingVolume2 = $RemainingVolume - $Qty1 * $Item[1].Volume
|
||||
|
||||
# Calculate the maximum quantity of item 2 for the remaining space, without going over the weight or volume limit
|
||||
$Qty2 = [math]::Min( [math]::Truncate( $RemainingWeight2 / $Item[2].Weight ), [math]::Truncate( $RemainingVolume2 / $Item[2].Volume ) )
|
||||
|
||||
# Calculate the total value of the items packed
|
||||
$TrialValue = $Qty0 * $Item[0].Value +
|
||||
$Qty1 * $Item[1].Value +
|
||||
$Qty2 * $Item[2].Value
|
||||
|
||||
# Describe the trial solution
|
||||
$Solution = "$Qty0 $($Item[0].Unit) of $($Item[0].Name), "
|
||||
$Solution += "$Qty1 $($Item[1].Unit) of $($Item[1].Name), and "
|
||||
$Solution += "$Qty2 $($Item[2].Unit) of $($Item[2].Name) worth a total of $TrialValue."
|
||||
|
||||
# If the trial value is higher than previous most valuable trial...
|
||||
If ( $TrialValue -gt $OptimalValue )
|
||||
{
|
||||
# Set the new number to beat
|
||||
$OptimalValue = $TrialValue
|
||||
|
||||
# Overwrite the previous optimal solution(s) with the trial solution
|
||||
$Solutions = @( $Solution )
|
||||
}
|
||||
|
||||
# Else if the trial value matches the previous most valuable trial...
|
||||
ElseIf ( $TrialValue -eq $OptimalValue )
|
||||
{
|
||||
# Add the trial solution to the list of optimal solutions
|
||||
$Solutions += @( $Solution )
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Show the results
|
||||
$Solutions
|
||||
|
|
@ -2,85 +2,85 @@
|
|||
|
||||
% tuples (name, Explantion, Value, weights, volume).
|
||||
knapsack :-
|
||||
L =[( panacea, 'Incredible healing properties', 3000, 0.3, 0.025),
|
||||
( ichor, 'Vampires blood', 1800, 0.2, 0.015),
|
||||
( gold , 'Shiney shiney', 2500, 2.0, 0.002)],
|
||||
L =[( panacea, 'Incredible healing properties', 3000, 0.3, 0.025),
|
||||
( ichor, 'Vampires blood', 1800, 0.2, 0.015),
|
||||
( gold , 'Shiney shiney', 2500, 2.0, 0.002)],
|
||||
|
||||
gen_state(S0),
|
||||
length(L, N),
|
||||
numlist(1, N, LN),
|
||||
gen_state(S0),
|
||||
length(L, N),
|
||||
numlist(1, N, LN),
|
||||
|
||||
% to get statistics
|
||||
time((create_constraint_N(LN, L, S0, S1, [], LVa, [], LW, [], LVo),
|
||||
constraint(LW =< 25.0, S1, S2),
|
||||
constraint(LVo =< 0.25, S2, S3),
|
||||
maximize(LVa, S3, S4)
|
||||
)),
|
||||
% to get statistics
|
||||
time((create_constraint_N(LN, L, S0, S1, [], LVa, [], LW, [], LVo),
|
||||
constraint(LW =< 25.0, S1, S2),
|
||||
constraint(LVo =< 0.25, S2, S3),
|
||||
maximize(LVa, S3, S4)
|
||||
)),
|
||||
|
||||
% we display the results
|
||||
compute_lenword(L, 0, Len),
|
||||
sformat(A0, '~~w~~t~~~w|', [3]),
|
||||
sformat(A1, '~~w~~t~~~w|', [Len]),
|
||||
sformat(A2, '~~t~~w~~~w|', [10]),
|
||||
sformat(A3, '~~t~~2f~~~w|', [10]),
|
||||
sformat(A4, '~~t~~3f~~~w|', [10]),
|
||||
sformat(A33, '~~t~~w~~~w|', [10]),
|
||||
sformat(A44, '~~t~~w~~~w|', [10]),
|
||||
% we display the results
|
||||
compute_lenword(L, 0, Len),
|
||||
sformat(A0, '~~w~~t~~~w|', [3]),
|
||||
sformat(A1, '~~w~~t~~~w|', [Len]),
|
||||
sformat(A2, '~~t~~w~~~w|', [10]),
|
||||
sformat(A3, '~~t~~2f~~~w|', [10]),
|
||||
sformat(A4, '~~t~~3f~~~w|', [10]),
|
||||
sformat(A33, '~~t~~w~~~w|', [10]),
|
||||
sformat(A44, '~~t~~w~~~w|', [10]),
|
||||
|
||||
sformat(W0, A0, ['Nb']),
|
||||
sformat(W1, A1, ['Items']),
|
||||
sformat(W2, A2, ['Value']),
|
||||
sformat(W3, A33, ['Weigth']),
|
||||
sformat(W4, A44, ['Volume']),
|
||||
format('~w~w~w~w~w~n', [W0, W1,W2,W3,W4]),
|
||||
sformat(W0, A0, ['Nb']),
|
||||
sformat(W1, A1, ['Items']),
|
||||
sformat(W2, A2, ['Value']),
|
||||
sformat(W3, A33, ['Weigth']),
|
||||
sformat(W4, A44, ['Volume']),
|
||||
format('~w~w~w~w~w~n', [W0, W1,W2,W3,W4]),
|
||||
|
||||
print_results(S4, A0, A1, A2, A3, A4, L, LN, 0, 0, 0).
|
||||
print_results(S4, A0, A1, A2, A3, A4, L, LN, 0, 0, 0).
|
||||
|
||||
|
||||
create_constraint_N([], [], S, S, LVa, LVa, LW, LW, LVo, LVo).
|
||||
|
||||
create_constraint_N([HN|TN], [(_, _,Va, W, Vo) | TL], S1, SF, LVa, LVaF, LW, LWF, LVo, LVoF) :-
|
||||
constraint(integral(x(HN)), S1, S2),
|
||||
constraint([x(HN)] >= 0, S2, S3),
|
||||
create_constraint_N(TN, TL, S3, SF,
|
||||
[Va * x(HN) | LVa], LVaF,
|
||||
[W * x(HN) | LW], LWF,
|
||||
[Vo * x(HN) | LVo], LVoF).
|
||||
constraint(integral(x(HN)), S1, S2),
|
||||
constraint([x(HN)] >= 0, S2, S3),
|
||||
create_constraint_N(TN, TL, S3, SF,
|
||||
[Va * x(HN) | LVa], LVaF,
|
||||
[W * x(HN) | LW], LWF,
|
||||
[Vo * x(HN) | LVo], LVoF).
|
||||
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%
|
||||
compute_lenword([], N, N).
|
||||
compute_lenword([(Name, _, _, _, _)|T], N, NF):-
|
||||
atom_length(Name, L),
|
||||
( L > N -> N1 = L; N1 = N),
|
||||
compute_lenword(T, N1, NF).
|
||||
atom_length(Name, L),
|
||||
( L > N -> N1 = L; N1 = N),
|
||||
compute_lenword(T, N1, NF).
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%
|
||||
print_results(_S, A0, A1, A2, A3, A4, [], [], VaM, WM, VoM) :-
|
||||
sformat(W0, A0, [' ']),
|
||||
sformat(W1, A1, [' ']),
|
||||
sformat(W2, A2, [VaM]),
|
||||
sformat(W3, A3, [WM]),
|
||||
sformat(W4, A4, [VoM]),
|
||||
format('~w~w~w~w~w~n', [W0, W1,W2,W3,W4]).
|
||||
sformat(W0, A0, [' ']),
|
||||
sformat(W1, A1, [' ']),
|
||||
sformat(W2, A2, [VaM]),
|
||||
sformat(W3, A3, [WM]),
|
||||
sformat(W4, A4, [VoM]),
|
||||
format('~w~w~w~w~w~n', [W0, W1,W2,W3,W4]).
|
||||
|
||||
|
||||
print_results(S, A0, A1, A2, A3, A4, [(Name, _, Va, W, Vo)|T], [N|TN], Va1, W1, Vo1) :-
|
||||
variable_value(S, x(N), X),
|
||||
( X = 0 -> Va1 = Va2, W1 = W2, Vo1 = Vo2
|
||||
;
|
||||
sformat(S0, A0, [X]),
|
||||
sformat(S1, A1, [Name]),
|
||||
Vatemp is X * Va,
|
||||
Wtemp is X * W,
|
||||
Votemp is X * Vo,
|
||||
sformat(S2, A2, [Vatemp]),
|
||||
sformat(S3, A3, [Wtemp]),
|
||||
sformat(S4, A4, [Votemp]),
|
||||
format('~w~w~w~w~w~n', [S0,S1,S2,S3,S4]),
|
||||
Va2 is Va1 + Vatemp,
|
||||
W2 is W1 + Wtemp,
|
||||
Vo2 is Vo1 + Votemp ),
|
||||
print_results(S, A0, A1, A2, A3, A4, T, TN, Va2, W2, Vo2).
|
||||
variable_value(S, x(N), X),
|
||||
( X = 0 -> Va1 = Va2, W1 = W2, Vo1 = Vo2
|
||||
;
|
||||
sformat(S0, A0, [X]),
|
||||
sformat(S1, A1, [Name]),
|
||||
Vatemp is X * Va,
|
||||
Wtemp is X * W,
|
||||
Votemp is X * Vo,
|
||||
sformat(S2, A2, [Vatemp]),
|
||||
sformat(S3, A3, [Wtemp]),
|
||||
sformat(S4, A4, [Votemp]),
|
||||
format('~w~w~w~w~w~n', [S0,S1,S2,S3,S4]),
|
||||
Va2 is Va1 + Vatemp,
|
||||
W2 is W1 + Wtemp,
|
||||
Vo2 is Vo1 + Votemp ),
|
||||
print_results(S, A0, A1, A2, A3, A4, T, TN, Va2, W2, Vo2).
|
||||
|
|
|
|||
|
|
@ -5,84 +5,84 @@ Data_<-structure(list(item = c("Panacea", "Ichor", "Gold"), value = c(3000,
|
|||
knapsack_volume<-function(Data, W, Volume, full_K)
|
||||
{
|
||||
|
||||
# Data must have the colums with names: item, value, weight and volume.
|
||||
K<-list() # hightest values
|
||||
K_item<-list() # itens that reach the hightest value
|
||||
K<-rep(0,W+1) # The position '0'
|
||||
K_item<-rep('',W+1) # The position '0'
|
||||
for(w in 1:W)
|
||||
{
|
||||
temp_w<-0
|
||||
temp_item<-''
|
||||
temp_value<-0
|
||||
for(i in 1:dim(Data)[1]) # each row
|
||||
{
|
||||
wi<-Data$weight[i] # item i
|
||||
vi<- Data$value[i]
|
||||
item<-Data$item[i]
|
||||
volume_i<-Data$volume[i]
|
||||
if(wi<=w & volume_i <= Volume)
|
||||
{
|
||||
back<- full_K[[Volume-volume_i+1]][w-wi+1]
|
||||
temp_wi<-vi + back
|
||||
# Data must have the colums with names: item, value, weight and volume.
|
||||
K<-list() # hightest values
|
||||
K_item<-list() # itens that reach the hightest value
|
||||
K<-rep(0,W+1) # The position '0'
|
||||
K_item<-rep('',W+1) # The position '0'
|
||||
for(w in 1:W)
|
||||
{
|
||||
temp_w<-0
|
||||
temp_item<-''
|
||||
temp_value<-0
|
||||
for(i in 1:dim(Data)[1]) # each row
|
||||
{
|
||||
wi<-Data$weight[i] # item i
|
||||
vi<- Data$value[i]
|
||||
item<-Data$item[i]
|
||||
volume_i<-Data$volume[i]
|
||||
if(wi<=w & volume_i <= Volume)
|
||||
{
|
||||
back<- full_K[[Volume-volume_i+1]][w-wi+1]
|
||||
temp_wi<-vi + back
|
||||
|
||||
if(temp_w < temp_wi)
|
||||
{
|
||||
temp_value<-temp_wi
|
||||
temp_w<-temp_wi
|
||||
temp_item <- item
|
||||
}
|
||||
}
|
||||
}
|
||||
K[[w+1]]<-temp_value
|
||||
K_item[[w+1]]<-temp_item
|
||||
}
|
||||
if(temp_w < temp_wi)
|
||||
{
|
||||
temp_value<-temp_wi
|
||||
temp_w<-temp_wi
|
||||
temp_item <- item
|
||||
}
|
||||
}
|
||||
}
|
||||
K[[w+1]]<-temp_value
|
||||
K_item[[w+1]]<-temp_item
|
||||
}
|
||||
return(list(K=K,Item=K_item))
|
||||
}
|
||||
|
||||
|
||||
Un_knapsack<-function(Data,W,V)
|
||||
{
|
||||
K<-list();K_item<-list()
|
||||
K[[1]]<-rep(0,W+1) #the line 0
|
||||
K_item[[1]]<-rep('', W+1) #the line 0
|
||||
for(v in 1:V)
|
||||
{
|
||||
best_volum_v<-knapsack_volume(Data, W, v, K)
|
||||
K[[v+1]]<-best_volum_v$K
|
||||
K_item[[v+1]]<-best_volum_v$Item
|
||||
}
|
||||
K<-list();K_item<-list()
|
||||
K[[1]]<-rep(0,W+1) #the line 0
|
||||
K_item[[1]]<-rep('', W+1) #the line 0
|
||||
for(v in 1:V)
|
||||
{
|
||||
best_volum_v<-knapsack_volume(Data, W, v, K)
|
||||
K[[v+1]]<-best_volum_v$K
|
||||
K_item[[v+1]]<-best_volum_v$Item
|
||||
}
|
||||
|
||||
return(list(K=data.frame(K),Item=data.frame(K_item,stringsAsFactors=F)))
|
||||
}
|
||||
|
||||
retrieve_info<-function(knapsack, Data)
|
||||
{
|
||||
W<-dim(knapsack$K)[1]
|
||||
itens<-c()
|
||||
col<-dim(knapsack$K)[2]
|
||||
selected_item<-knapsack$Item[W,col]
|
||||
while(selected_item!='')
|
||||
{
|
||||
selected_item<-knapsack$Item[W,col]
|
||||
if(selected_item!='')
|
||||
{
|
||||
selected_item_value<-Data[Data$item == selected_item,]
|
||||
W <- W - selected_item_value$weight
|
||||
itens<-c(itens,selected_item)
|
||||
col <- col - selected_item_value$volume
|
||||
}
|
||||
}
|
||||
W<-dim(knapsack$K)[1]
|
||||
itens<-c()
|
||||
col<-dim(knapsack$K)[2]
|
||||
selected_item<-knapsack$Item[W,col]
|
||||
while(selected_item!='')
|
||||
{
|
||||
selected_item<-knapsack$Item[W,col]
|
||||
if(selected_item!='')
|
||||
{
|
||||
selected_item_value<-Data[Data$item == selected_item,]
|
||||
W <- W - selected_item_value$weight
|
||||
itens<-c(itens,selected_item)
|
||||
col <- col - selected_item_value$volume
|
||||
}
|
||||
}
|
||||
return(itens)
|
||||
}
|
||||
|
||||
main_knapsack<-function(Data, W, Volume)
|
||||
{
|
||||
knapsack_result<-Un_knapsack(Data,W,Volume)
|
||||
items<-table(retrieve_info(knapsack_result, Data))
|
||||
K<-knapsack_result$K[W+1, Volume+1]
|
||||
cat(paste('The Total profit is: ', K, '\n'))
|
||||
cat(paste('You must carry:', names(items), '(x',items, ') \n'))
|
||||
knapsack_result<-Un_knapsack(Data,W,Volume)
|
||||
items<-table(retrieve_info(knapsack_result, Data))
|
||||
K<-knapsack_result$K[W+1, Volume+1]
|
||||
cat(paste('The Total profit is: ', K, '\n'))
|
||||
cat(paste('You must carry:', names(items), '(x',items, ') \n'))
|
||||
}
|
||||
|
||||
main_knapsack(Data_, 250, 250)
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ my %max_items;
|
|||
for $panacea, $ichor, $gold -> $item {
|
||||
%max_items{$item.name} = floor min
|
||||
$maximum.volume / $item.volume,
|
||||
$maximum.weight / $item.weight;
|
||||
$maximum.weight / $item.weight;
|
||||
}
|
||||
|
||||
for 0..%max_items<panacea>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,72 @@
|
|||
Rebol [
|
||||
title: "Rosetta code: Knapsack problem/Unbounded"
|
||||
file: %Knapsack_problem-Unbounded.r3
|
||||
url: https://rosettacode.org/wiki/Knapsack_problem/Unbounded
|
||||
]
|
||||
|
||||
items: [
|
||||
[Panacea 3000 0.3 0.025]
|
||||
[Ichor 1800 0.2 0.015]
|
||||
[Gold 2500 2.0 0.002]
|
||||
]
|
||||
|
||||
item-name: func [item] [item/1]
|
||||
item-value: func [item] [item/2]
|
||||
item-weight: func [item] [item/3]
|
||||
item-volume: func [item] [item/4]
|
||||
|
||||
knapsack: function [
|
||||
{Solves the bounded knapsack problem with both weight and volume
|
||||
constraints, using brute-force recursion over item counts.}
|
||||
items [block!]
|
||||
weight [number!] ; remaining weight capacity
|
||||
volume [number!] ; remaining volume capacity
|
||||
][
|
||||
if empty? items [ return reduce [copy [] 0] ]
|
||||
|
||||
n: last-item: last items
|
||||
rest: copy/part items (length? items) - 1
|
||||
|
||||
max-count: min weight / item-weight n
|
||||
volume / item-volume n
|
||||
best-value: 0
|
||||
best-counts: copy []
|
||||
|
||||
count: 0
|
||||
while [count <= max-count] [
|
||||
sub: knapsack rest
|
||||
weight - (count * item-weight n)
|
||||
volume - (count * item-volume n)
|
||||
sub-counts: sub/1
|
||||
sub-value: sub/2 + (count * item-value n)
|
||||
|
||||
if sub-value > best-value [
|
||||
best-value: sub-value
|
||||
best-counts: append copy sub-counts count
|
||||
]
|
||||
++ count
|
||||
]
|
||||
|
||||
reduce [best-counts best-value]
|
||||
]
|
||||
|
||||
result: knapsack items 25 0.25
|
||||
counts: result/1
|
||||
sum-count: sum-value: sum-weight: sum-volume: 0
|
||||
|
||||
print "ITEM COUNT WEIGHT VOLUME VALUE"
|
||||
print "--------------------------------------"
|
||||
repeat i length? counts [
|
||||
item: items/:i
|
||||
n: counts/:i
|
||||
w: n * item-weight item
|
||||
v: n * item-volume item
|
||||
val: n * item-value item
|
||||
sum-count: sum-count + n
|
||||
sum-value: sum-value + val
|
||||
sum-weight: sum-weight + w
|
||||
sum-volume: sum-volume + v
|
||||
printf [10 7 8 8 8] reduce [item-name item n w v val]
|
||||
]
|
||||
print "--------------------------------------"
|
||||
printf [10 7 8 8 8] reduce ["TOTAL" sum-count sum-weight sum-volume sum-value]
|
||||
Loading…
Add table
Add a link
Reference in a new issue