TheAlgorithms-C-Plus-Plus/dynamic_programming/0_1_knapsack.cpp
Kaustubh Damania 67e26cfbae
feat: Add ncr mod p code (#1325)
* feat: Add ncr mod p code (#1323)

* Update math/ncr_modulo_p.cpp

Co-authored-by: David Leal <halfpacho@gmail.com>

* Added all functions inside a class + added more asserts

* updating DIRECTORY.md

* clang-format and clang-tidy fixes for f6df24a5

* Replace int64_t to uint64_t + add namespace + detailed documentation

* clang-format and clang-tidy fixes for e09a0579

* Add extra namespace + add const& in function arguments

* clang-format and clang-tidy fixes for 8111f881

* Update ncr_modulo_p.cpp

* clang-format and clang-tidy fixes for 2ad2f721

* Update math/ncr_modulo_p.cpp

Co-authored-by: David Leal <halfpacho@gmail.com>

* Update math/ncr_modulo_p.cpp

Co-authored-by: David Leal <halfpacho@gmail.com>

* Update math/ncr_modulo_p.cpp

Co-authored-by: David Leal <halfpacho@gmail.com>

* clang-format and clang-tidy fixes for 5b69ba5c

* updating DIRECTORY.md

* clang-format and clang-tidy fixes for a8401d4b

Co-authored-by: David Leal <halfpacho@gmail.com>
Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com>
2020-11-22 23:05:01 +05:30

131 lines
4.9 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* @file
* @brief Implementation of [0-1 Knapsack Problem]
* (https://en.wikipedia.org/wiki/Knapsack_problem)
*
* @details
* Given weights and values of n items, put these items in a knapsack of
* capacity `W` to get the maximum total value in the knapsack. In other words,
* given two integer arrays `val[0..n-1]` and `wt[0..n-1]` which represent
* values and weights associated with n items respectively. Also given an
* integer W which represents knapsack capacity, find out the maximum value
* subset of `val[]` such that sum of the weights of this subset is smaller than
* or equal to W. You cannot break an item, either pick the complete item or
* dont pick it (0-1 property)
*
* ### Algorithm
* The idea is to consider all subsets of items and calculate the total weight
* and value of all subsets. Consider the only subsets whose total weight is
* smaller than `W`. From all such subsets, pick the maximum value subset.
*
* @author [Anmol](https://github.com/Anmol3299)
* @author [Pardeep](https://github.com/Pardeep009)
*/
#include <array>
#include <cassert>
#include <iostream>
#include <vector>
/**
* @namespace dynamic_programming
* @brief Dynamic Programming algorithms
*/
namespace dynamic_programming {
/**
* @namespace Knapsack
* @brief Implementation of 0-1 Knapsack problem
*/
namespace knapsack {
/**
* @brief Picking up all those items whose combined weight is below
* given capacity and calculating value of those picked items.Trying all
* possible combinations will yield the maximum knapsack value.
* @tparam n size of the weight and value array
* @param capacity capacity of the carrying bag
* @param weight array representing weight of items
* @param value array representing value of items
* @return maximum value obtainable with given capacity.
*/
template <size_t n>
int maxKnapsackValue(const int capacity, const std::array<int, n> &weight,
const std::array<int, n> &value) {
std::vector<std::vector<int> > maxValue(n + 1,
std::vector<int>(capacity + 1, 0));
// outer loop will select no of items allowed
// inner loop will select capcity of knapsack bag
int items = sizeof(weight) / sizeof(weight[0]);
for (size_t i = 0; i < items + 1; ++i) {
for (size_t j = 0; j < capacity + 1; ++j) {
if (i == 0 || j == 0) {
// if no of items is zero or capacity is zero, then maxValue
// will be zero
maxValue[i][j] = 0;
} else if (weight[i - 1] <= j) {
// if the ith item's weight(in actual array it will be at i-1)
// is less than or equal to the allowed weight i.e. j then we
// can pick that item for our knapsack. maxValue will be the
// obtained either by picking the current item or by not picking
// current item
// picking current item
int profit1 = value[i - 1] + maxValue[i - 1][j - weight[i - 1]];
// not picking current item
int profit2 = maxValue[i - 1][j];
maxValue[i][j] = std::max(profit1, profit2);
} else {
// as weight of current item is greater than allowed weight, so
// maxProfit will be profit obtained by excluding current item.
maxValue[i][j] = maxValue[i - 1][j];
}
}
}
// returning maximum value
return maxValue[items][capacity];
}
} // namespace knapsack
} // namespace dynamic_programming
/**
* @brief Function to test above algorithm
* @returns void
*/
static void test() {
// Test 1
const int n1 = 3; // number of items
std::array<int, n1> weight1 = {10, 20, 30}; // weight of each item
std::array<int, n1> value1 = {60, 100, 120}; // value of each item
const int capacity1 = 50; // capacity of carrying bag
const int max_value1 = dynamic_programming::knapsack::maxKnapsackValue(
capacity1, weight1, value1);
const int expected_max_value1 = 220;
assert(max_value1 == expected_max_value1);
std::cout << "Maximum Knapsack value with " << n1 << " items is "
<< max_value1 << std::endl;
// Test 2
const int n2 = 4; // number of items
std::array<int, n2> weight2 = {24, 10, 10, 7}; // weight of each item
std::array<int, n2> value2 = {24, 18, 18, 10}; // value of each item
const int capacity2 = 25; // capacity of carrying bag
const int max_value2 = dynamic_programming::knapsack::maxKnapsackValue(
capacity2, weight2, value2);
const int expected_max_value2 = 36;
assert(max_value2 == expected_max_value2);
std::cout << "Maximum Knapsack value with " << n2 << " items is "
<< max_value2 << std::endl;
}
/**
* @brief Main function
* @returns 0 on exit
*/
int main() {
// Testing
test();
return 0;
}