Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Enhancement of the knapsack algorithm with memorization and generalisation #9295

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
MaximSmolskiy merged 15 commits into TheAlgorithms:master from Jiang15:wei_knapsack
Aug 26, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
eaf87c6
enhance knapsack problem
Oct 1, 2023
962d71c
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 1, 2023
c542f2b
wei/refactor code
Oct 1, 2023
4714f9b
refactor code
Oct 1, 2023
0a34531
Merge branch 'master' into wei_knapsack
MaximSmolskiy Aug 26, 2025
b10a7fc
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Aug 26, 2025
b6b2e18
Update test_knapsack.py
MaximSmolskiy Aug 26, 2025
bd5b301
Update knapsack.py
MaximSmolskiy Aug 26, 2025
e89dbd9
Update test_knapsack.py
MaximSmolskiy Aug 26, 2025
0ff866e
Update knapsack.py
MaximSmolskiy Aug 26, 2025
5428da7
Update knapsack.py
MaximSmolskiy Aug 26, 2025
72b3adf
Update knapsack.py
MaximSmolskiy Aug 26, 2025
eded73c
Update knapsack.py
MaximSmolskiy Aug 26, 2025
ed5483f
Update knapsack.py
MaximSmolskiy Aug 26, 2025
393cacf
Update test_knapsack.py
MaximSmolskiy Aug 26, 2025
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
2 changes: 1 addition & 1 deletion knapsack/README.md
View file Open in desktop
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# A naive recursive implementation of 0-1 Knapsack Problem
# A recursive implementation of 0-N Knapsack Problem

This overview is taken from:

Expand Down
65 changes: 43 additions & 22 deletions knapsack/knapsack.py
View file Open in desktop
Original file line number Diff line number Diff line change
@@ -1,14 +1,23 @@
"""A naive recursive implementation of 0-1 Knapsack Problem
"""A recursive implementation of 0-N Knapsack Problem
https://en.wikipedia.org/wiki/Knapsack_problem
"""

from __future__ import annotations

from functools import lru_cache

def knapsack(capacity: int, weights: list[int], values: list[int], counter: int) -> int:

def knapsack(
capacity: int,
weights: list[int],
values: list[int],
counter: int,
allow_repetition=False,
) -> int:
"""
Returns the maximum value that can be put in a knapsack of a capacity cap,
whereby each weight w has a specific value val.
whereby each weight w has a specific value val
with option to allow repetitive selection of items

>>> cap = 50
>>> val = [60, 100, 120]
Expand All @@ -17,28 +26,40 @@ def knapsack(capacity: int, weights: list[int], values: list[int], counter: int)
>>> knapsack(cap, w, val, c)
220

The result is 220 cause the values of 100 and 120 got the weight of 50
Given the repetition is NOT allowed,
the result is 220 cause the values of 100 and 120 got the weight of 50
which is the limit of the capacity.
>>> knapsack(cap, w, val, c, True)
300

Given the repetition is allowed,
the result is 300 cause the values of 60*5 (pick 5 times)
Copy link
Contributor

@jeffreyyancey jeffreyyancey Oct 8, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The algorithm has been updated to allow repetition. An example/testcase where repetition is used would be appropriate.

got the weight of 10*5 which is the limit of the capacity.
"""

Copy link
Contributor

@jeffreyyancey jeffreyyancey Oct 8, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You might want to consider a few things before getting into the algorithm:

  1. Handle any input constraints. Ensure the inputs make sense and raise an exception for the user if they don't
  • non-positive numbers
  • a capacity lower than the weight of any single object
  • etc
  1. Before getting into the main algorithm, you can go ahead and remove any items that have a weight above the capacity of the knapsack.

# Base Case
if counter == 0 or capacity == 0:
return 0

# If weight of the nth item is more than Knapsack of capacity,
# then this item cannot be included in the optimal solution,
# else return the maximum of two cases:
# (1) nth item included
# (2) not included
if weights[counter - 1] > capacity:
return knapsack(capacity, weights, values, counter - 1)
else:
left_capacity = capacity - weights[counter - 1]
new_value_included = values[counter - 1] + knapsack(
left_capacity, weights, values, counter - 1
)
without_new_value = knapsack(capacity, weights, values, counter - 1)
return max(new_value_included, without_new_value)
@lru_cache
def knapsack_recur(capacity: int, counter: int) -> int:
# Base Case
if counter == 0 or capacity == 0:
return 0

# If weight of the nth item is more than Knapsack of capacity,
# then this item cannot be included in the optimal solution,
# else return the maximum of two cases:
# (1) nth item included only once (0-1), if allow_repetition is False
# nth item included one or more times (0-N), if allow_repetition is True
# (2) not included
if weights[counter - 1] > capacity:
return knapsack_recur(capacity, counter - 1)
else:
left_capacity = capacity - weights[counter - 1]
new_value_included = values[counter - 1] + knapsack_recur(
left_capacity, counter - 1 if not allow_repetition else counter
)
without_new_value = knapsack_recur(capacity, counter - 1)
return max(new_value_included, without_new_value)

return knapsack_recur(capacity, counter)


if __name__ == "__main__":
Expand Down
12 changes: 11 additions & 1 deletion knapsack/tests/test_knapsack.py
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def test_base_case(self):

def test_easy_case(self):
"""
test for the base case
test for the easy case
"""
cap = 3
val = [1, 2, 3]
Expand All @@ -48,6 +48,16 @@ def test_knapsack(self):
c = len(val)
assert k.knapsack(cap, w, val, c) == 220

def test_knapsack_repetition(self):
"""
test for the knapsack repetition
"""
cap = 50
val = [60, 100, 120]
w = [10, 20, 30]
c = len(val)
assert k.knapsack(cap, w, val, c, True) == 300


if __name__ == "__main__":
unittest.main()

AltStyle によって変換されたページ (->オリジナル) /