Knapsack problem/Bounded: Difference between revisions

Content added Content deleted
(Add Swift)
Line 4,043: Line 4,043:
1 of socks
1 of socks
Value: 1010; Weight: 396
Value: 1010; Weight: 396
</pre>

=={{header|Swift}}==

{{trans|Python}}

<lang swift>public struct KnapsackItem: Hashable {
public var name: String
public var weight: Int
public var value: Int

public init(name: String, weight: Int, value: Int) {
self.name = name
self.weight = weight
self.value = value
}
}

public func knapsack(items: [KnapsackItem], limit: Int) -> [KnapsackItem] {
var table = Array(repeating: Array(repeating: 0, count: limit + 1), count: items.count + 1)

for j in 1...items.count {
let item = items[j-1]

for w in 1...limit {
if item.weight > w {
table[j][w] = table[j-1][w]
} else {
table[j][w] = max(table[j-1][w], table[j-1][w-item.weight] + item.value)
}
}
}

var result = [KnapsackItem]()
var w = limit

for j in stride(from: items.count, to: 0, by: -1) where table[j][w] != table[j-1][w] {
let item = items[j-1]

result.append(item)

w -= item.weight
}

return result
}

typealias GroupedItem = (name: String, weight: Int, val: Int, n: Int)

let groupedItems: [GroupedItem] = [
("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)
]

let items = groupedItems.flatMap({item in
(0..<item.n).map({_ in KnapsackItem(name: item.name, weight: item.weight, value: item.val) })
})

let bagged = knapsack(items: items, limit: 400)
let (totalVal, totalWeight) = bagged.reduce((0, 0), {cur, item in (cur.0 + item.value, cur.1 + item.weight) })

print("Bagged the following \(bagged.count) items:")

for item in bagged {
print("\t\(item.name)")
}

print("For a total value of \(totalVal) and weight of \(totalWeight)")</lang>

{{out}}

<pre>Bagged the following 14 items:
socks
sunglasses
note-case
waterproof overclothes
suntan cream
cheese
banana
banana
banana
glucose
glucose
water
compass
map
For a total value of 1010 and weight of 396
</pre>
</pre>