Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
108
Task/Knapsack-problem-Bounded/Nim/knapsack-problem-bounded.nim
Normal file
108
Task/Knapsack-problem-Bounded/Nim/knapsack-problem-bounded.nim
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
# Knapsack. Recursive solution.
|
||||
|
||||
import strformat
|
||||
import tables
|
||||
|
||||
# Description of an item.
|
||||
type Item = tuple[name: string; weight, value, pieces: int]
|
||||
|
||||
# List of available items.
|
||||
const Items: seq[Item] = @[("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)
|
||||
]
|
||||
|
||||
type
|
||||
|
||||
# Item numbers (used rather than items themselves).
|
||||
Number = range[0..Items.high]
|
||||
|
||||
# Description of an expanded item.
|
||||
ExpandedItem = tuple[num: Number; weight, value: int]
|
||||
|
||||
|
||||
# Expanded items management.
|
||||
|
||||
proc expandedItems(items: seq[Item]): seq[ExpandedItem] =
|
||||
## Expand the list of items.
|
||||
for idx, item in Items:
|
||||
for _ in 1..item.pieces:
|
||||
result.add((idx.Number, item.weight, item.value))
|
||||
|
||||
const ItemList = expandedItems(Items)
|
||||
|
||||
type
|
||||
|
||||
# Index in the expanded list.
|
||||
ExpandedIndex = 0..ItemList.high
|
||||
|
||||
# Chosen items and their total value.
|
||||
Choice = tuple[indexes: set[ExpandedIndex]; weight, value: int]
|
||||
|
||||
# Cache used to speed up the search.
|
||||
var cache: Table[tuple[index, weight: int], Choice]
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------------------------------
|
||||
|
||||
proc select(idx, weightLimit: int): Choice =
|
||||
## Find the best choice starting from item at index "idx".
|
||||
|
||||
if idx < 0 or weightLimit == 0:
|
||||
return
|
||||
|
||||
if (idx, weightLimit) in cache:
|
||||
return cache[(idx, weightLimit)]
|
||||
|
||||
let weight = ItemList[idx].weight
|
||||
if weight > weightLimit:
|
||||
return select(idx - 1, weightLimit)
|
||||
|
||||
# Try by leaving this item and selecting among remaining items.
|
||||
result = select(idx - 1, weightLimit)
|
||||
|
||||
# Try by taking this item and completing with some remaining items.
|
||||
var result1 = select(idx - 1, weightLimit - weight)
|
||||
inc result1.value, ItemList[idx].value
|
||||
|
||||
# Select the best choice (giving the greater value).
|
||||
if result1.value > result.value:
|
||||
result = (result1.indexes + {idx.ExpandedIndex}, result1.weight + weight, result1.value)
|
||||
|
||||
cache[(idx, weightLimit)] = result
|
||||
|
||||
#---------------------------------------------------------------------------------------------------
|
||||
|
||||
let (indexes, weight, value) = select(ItemList.high, 400)
|
||||
|
||||
# Count the number of pieces for each item.
|
||||
var pieces = newSeq[int](Items.len)
|
||||
for idx in indexes:
|
||||
inc pieces[ItemList[idx].num]
|
||||
|
||||
echo "List of items:"
|
||||
for num in 0..Items.high:
|
||||
if pieces[num] > 0:
|
||||
echo fmt"– {pieces[num]} of {Items[num].pieces} {Items[num].name}"
|
||||
echo ""
|
||||
echo "Total weight: ", weight
|
||||
echo "Total value: ", value
|
||||
Loading…
Add table
Add a link
Reference in a new issue