TheAlgorithms/C++ 1.0.0
All the algorithms implemented in C++
Loading...
Searching...
No Matches
unbounded_0_1_knapsack.cpp File Reference

Implementation of the Unbounded 0/1 Knapsack Problem. More...

#include <cassert>
#include <cstdint>
#include <iostream>
#include <vector>
Include dependency graph for unbounded_0_1_knapsack.cpp:

Go to the source code of this file.

Namespaces

namespace  dynamic_programming
 Dynamic Programming algorithms.
 
namespace  Knapsack
 Implementation of 0-1 Knapsack problem.
 

Functions

std::uint16_t dynamic_programming::unbounded_knapsack::KnapSackFilling (std::uint16_t i, std::uint16_t W, const std::vector< std::uint16_t > &val, const std::vector< std::uint16_t > &wt, std::vector< std::vector< int > > &dp)
 Recursive function to calculate the maximum value obtainable using an unbounded knapsack approach.
 
std::uint16_t dynamic_programming::unbounded_knapsack::unboundedKnapsack (std::uint16_t N, std::uint16_t W, const std::vector< std::uint16_t > &val, const std::vector< std::uint16_t > &wt)
 Wrapper function to initiate the unbounded knapsack calculation.
 
static void tests ()
 self test implementation
 
int main ()
 main function
 

Detailed Description

Implementation of the Unbounded 0/1 Knapsack Problem.

The Unbounded 0/1 Knapsack problem allows taking unlimited quantities of each item. The goal is to maximize the total value without exceeding the given knapsack capacity. Unlike the 0/1 knapsack, where each item can be taken only once, in this variation, any item can be picked any number of times as long as the total weight stays within the knapsack's capacity.

Given a set of N items, each with a weight and a value, represented by the arrays wt and val respectively, and a knapsack with a weight limit W, the task is to fill the knapsack to maximize the total value.

Note
weight and value of items is greater than zero

Algorithm

The approach uses dynamic programming to build a solution iteratively. A 2D array is used for memoization to store intermediate results, allowing the function to avoid redundant calculations.

Author
Sanskruti Yeole
See also
dynamic_programming/0_1_knapsack.cpp

Definition in file unbounded_0_1_knapsack.cpp.

Function Documentation

◆ KnapSackFilling()

std::uint16_t dynamic_programming::unbounded_knapsack::KnapSackFilling ( std::uint16_t i,
std::uint16_t W,
const std::vector< std::uint16_t > & val,
const std::vector< std::uint16_t > & wt,
std::vector< std::vector< int > > & dp )

Recursive function to calculate the maximum value obtainable using an unbounded knapsack approach.

Parameters
iCurrent index in the value and weight vectors.
WRemaining capacity of the knapsack.
valVector of values corresponding to the items.
Note
"val" data type can be changed according to the size of the input.
Parameters
wtVector of weights corresponding to the items.
Note
"wt" data type can be changed according to the size of the input.
Parameters
dp2D vector for memoization to avoid redundant calculations.
Returns
The maximum value that can be obtained for the given index and capacity.

Definition at line 58 of file unbounded_0_1_knapsack.cpp.

61 {
62 if (i == 0) {
63 if (wt[0] <= W) {
64 return (W / wt[0]) *
65 val[0]; // Take as many of the first item as possible
66 } else {
67 return 0; // Can't take the first item
68 }
69 }
70 if (dp[i][W] != -1)
71 return dp[i][W]; // Return result if available
72
73 int nottake =
74 KnapSackFilling(i - 1, W, val, wt, dp); // Value without taking item i
75 int take = 0;
76 if (W >= wt[i]) {
77 take = val[i] + KnapSackFilling(i, W - wt[i], val, wt,
78 dp); // Value taking item i
79 }
80 return dp[i][W] =
81 std::max(take, nottake); // Store and return the maximum value
82}
for std::vector
std::uint16_t KnapSackFilling(std::uint16_t i, std::uint16_t W, const std::vector< std::uint16_t > &val, const std::vector< std::uint16_t > &wt, std::vector< std::vector< int > > &dp)
Recursive function to calculate the maximum value obtainable using an unbounded knapsack approach.

◆ main()

int main ( void )

main function

Returns
0 on successful exit

Definition at line 170 of file unbounded_0_1_knapsack.cpp.

170 {
171 tests(); // Run self test implementation
172 return 0;
173}
static void tests()
self test implementation

◆ tests()

static void tests ( )
static

self test implementation

Returns
void

Definition at line 111 of file unbounded_0_1_knapsack.cpp.

111 {
112 // Test Case 1
113 std::uint16_t N1 = 4; // Number of items
114 std::vector<std::uint16_t> wt1 = {1, 3, 4, 5}; // Weights of the items
115 std::vector<std::uint16_t> val1 = {6, 1, 7, 7}; // Values of the items
116 std::uint16_t W1 = 8; // Maximum capacity of the knapsack
117 // Test the function and assert the expected output
118 assert(dynamic_programming::unbounded_knapsack::unboundedKnapsack(
119 N1, W1, val1, wt1) == 48);
120 std::cout << "Maximum Knapsack value "
122 N1, W1, val1, wt1)
123 << std::endl;
124
125 // Test Case 2
126 std::uint16_t N2 = 3; // Number of items
127 std::vector<std::uint16_t> wt2 = {10, 20, 30}; // Weights of the items
128 std::vector<std::uint16_t> val2 = {60, 100, 120}; // Values of the items
129 std::uint16_t W2 = 5; // Maximum capacity of the knapsack
130 // Test the function and assert the expected output
131 assert(dynamic_programming::unbounded_knapsack::unboundedKnapsack(
132 N2, W2, val2, wt2) == 0);
133 std::cout << "Maximum Knapsack value "
135 N2, W2, val2, wt2)
136 << std::endl;
137
138 // Test Case 3
139 std::uint16_t N3 = 3; // Number of items
140 std::vector<std::uint16_t> wt3 = {2, 4, 6}; // Weights of the items
141 std::vector<std::uint16_t> val3 = {5, 11, 13}; // Values of the items
142 std::uint16_t W3 = 27; // Maximum capacity of the knapsack
143 // Test the function and assert the expected output
144 assert(dynamic_programming::unbounded_knapsack::unboundedKnapsack(
145 N3, W3, val3, wt3) == 27);
146 std::cout << "Maximum Knapsack value "
148 N3, W3, val3, wt3)
149 << std::endl;
150
151 // Test Case 4
152 std::uint16_t N4 = 0; // Number of items
153 std::vector<std::uint16_t> wt4 = {}; // Weights of the items
154 std::vector<std::uint16_t> val4 = {}; // Values of the items
155 std::uint16_t W4 = 10; // Maximum capacity of the knapsack
156 assert(dynamic_programming::unbounded_knapsack::unboundedKnapsack(
157 N4, W4, val4, wt4) == 0);
158 std::cout << "Maximum Knapsack value for empty arrays: "
160 N4, W4, val4, wt4)
161 << std::endl;
162
163 std::cout << "All test cases passed!" << std::endl;
164}
std::uint16_t unboundedKnapsack(std::uint16_t N, std::uint16_t W, const std::vector< std::uint16_t > &val, const std::vector< std::uint16_t > &wt)
Wrapper function to initiate the unbounded knapsack calculation.

◆ unboundedKnapsack()

std::uint16_t dynamic_programming::unbounded_knapsack::unboundedKnapsack ( std::uint16_t N,
std::uint16_t W,
const std::vector< std::uint16_t > & val,
const std::vector< std::uint16_t > & wt )

Wrapper function to initiate the unbounded knapsack calculation.

Parameters
NNumber of items.
WMaximum weight capacity of the knapsack.
valVector of values corresponding to the items.
wtVector of weights corresponding to the items.
Returns
The maximum value that can be obtained for the given capacity.

Definition at line 93 of file unbounded_0_1_knapsack.cpp.

95 {
96 if (N == 0)
97 return 0; // Expect 0 since no items
98 std::vector<std::vector<int>> dp(
99 N, std::vector<int>(W + 1, -1)); // Initialize memoization table
100 return KnapSackFilling(N - 1, W, val, wt, dp); // Start the calculation
101}