Skip to content
This repository was archived by the owner on Oct 7, 2019. It is now read-only.

Added knapsack in Golang #110

Merged
merged 2 commits into from
Oct 5, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 64 additions & 0 deletions dynamic_programing/knapsack_problem/go/knapsack.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package knapsack

type Packable interface {
Weight() int64
Value() int64
}

func Knapsack(items []Packable, capacity int64) []int64 {

values := make([][]int64, len(items)+1)
for i := range values {
values[i] = make([]int64, capacity+1)
}

keep := make([][]int, len(items)+1)
for i := range keep {
keep[i] = make([]int, capacity+1)
}

for i := int64(0); i < capacity+1; i++ {
values[0][i] = 0
keep[0][i] = 0
}

for i := 0; i < len(items)+1; i++ {
values[i][0] = 0
keep[i][0] = 0
}

for i := 1; i <= len(items); i++ {
for c := int64(1); c <= capacity; c++ {

itemFits := (items[i-1].Weight() <= c)
if !itemFits {
continue
}

maxValueAtThisCapacity := items[i-1].Value() + values[i-1][c-items[i-1].Weight()]
previousValueAtThisCapacity := values[i-1][c]

if itemFits && (maxValueAtThisCapacity > previousValueAtThisCapacity) {
values[i][c] = maxValueAtThisCapacity
keep[i][c] = 1
} else {
values[i][c] = previousValueAtThisCapacity
keep[i][c] = 0
}
}
}

n := len(items)
c := capacity
var indices []int64

for n > 0 {
if keep[n][c] == 1 {
indices = append(indices, int64(n-1))
c -= items[n-1].Weight()
}
n--
}

return indices
}
80 changes: 80 additions & 0 deletions dynamic_programing/knapsack_problem/go/knapsack_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package knapsack

import (
"testing"
)

type TestKnapsackItem struct {
weight int64
value int64
}

func (i TestKnapsackItem) Weight() int64 {
return i.weight
}

func (i TestKnapsackItem) Value() int64 {
return i.value
}

func TestKnapsackEasy(t *testing.T) {
items := []Packable{
TestKnapsackItem{
3, 5,
},
TestKnapsackItem{
2, 3,
},
TestKnapsackItem{
1, 4,
},
}

indices := Knapsack(items, 5)
var value int64
for _, i := range indices {
value += items[i].Value()
}

if value != 9 {
t.Errorf("Expected %d, got %d", 9, value)
}
}

func TestZeroCapacityKnapsack(t *testing.T) {
items := []Packable{
TestKnapsackItem{
3, 5,
},
TestKnapsackItem{
2, 3,
},
TestKnapsackItem{
1, 4,
},
}

indices := Knapsack(items, 0)
var value int64
for _, i := range indices {
value += items[i].Value()
}

if value != 0 {
t.Errorf("Expected %d, got %d", 0, value)
}
}

func TestNoItemsForKnapsack(t *testing.T) {
items := []Packable{}

indices := Knapsack(items, 0)
var value int64
for _, i := range indices {
value += items[i].Value()
}

if value != 0 {
t.Errorf("Expected %d, got %d", 0, value)
}
}