Files
C-Plus-Plus/dynamic_programming/0_1_knapsack.cpp
Piotr Idzik 34fdc8edc2 chore: synchronize with master (#2)
* chore: fix Markdown formatting in `dynamic_programming/kadane2.cpp` (#2276)

* docs: fix grammatical errors and typos (#2201)

* docs: fix grammatical errors and typos

* compilation error fixed

* Revert "compilation error fixed"

This reverts commit 0083cbfd1a.

* feat: added physics directory and ground to ground projectile motion algorithm (#2279)

* feat: added physics folder, ground to ground projectile motion calculations

* feat: added max height function

* fix: bug in angle calculations

* test: added test cases

* docs: added comments to test case variables

* docs: added comments to calculations

* fix: changed floats to doubles

* updating DIRECTORY.md

* Update physics/ground_to_ground_projectile_motion.cpp

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

* chore: add missing namespace

* rerun checks

Co-authored-by: David <Panquesito7@users.noreply.github.com>
Co-authored-by: David Leal <halfpacho@gmail.com>

* docs: updated a logically wrong doc comment (#2329)

* feat: add CMakeLists to the `divide_and_conquer` directory (#2072)

* fix: stairs pattern not printing slash (#2111)

when we propose 2 backslash then it doesn't take it as a comment and gets printed

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

* fix: use FreeGlut newest GitHub link (#2397)

* updating DIRECTORY.md

* fix: use FreeGlut newest GitHub link

* chore(fix): `data_strcutres` -> `data_structures` (#2399)

* feat: add Find non repeating number implementation (#2061)

* add find_single_number

* add fix issues

* remove .vscode

* add .vscode

* Update .vscode/settings.json

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

* chore(fix): minor issues

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

* [feat/docs]: improve the `quick_sort.cpp` algorithm (#2396)

* [feat/docs]: improve the `quick_sort.cpp`...

...algorithm implementation.

* clang-format and clang-tidy fixes for 40c858ba

* chore(fix): add original author

* updating DIRECTORY.md

* chore: update Discord links (#2407)

* docs: remove unneeded Markdown header

* feat: improve the Awesome Workflow (#2408)

* fix: Awesome Workflow issues

Thanks to @tjgurwara99 for the original fix: TheAlgorithms/C#1176

* chore: apply suggestions from code review

Co-authored-by: Taj <tjgurwara99@users.noreply.github.com>

* feat: various improvements

* chore: apply suggestions from code review

Co-authored-by: Taj <tjgurwara99@users.noreply.github.com>

* chore: remove LGTM and fix...

...CodeQL badges.

* docs: add guide on integrating CMake (#2410)

Taken from TheAlgorithms/C#1163

* updating DIRECTORY.md

Co-authored-by: Daemon <90456722+Daemon19@users.noreply.github.com>
Co-authored-by: aadarshkt <72285744+aadarshkt@users.noreply.github.com>
Co-authored-by: Focus <65309793+Focusucof@users.noreply.github.com>
Co-authored-by: David <Panquesito7@users.noreply.github.com>
Co-authored-by: David Leal <halfpacho@gmail.com>
Co-authored-by: Arjit Malik <arjitmalik2001@gmail.com>
Co-authored-by: Harsh Singh <94822101+harshsingh510@users.noreply.github.com>
Co-authored-by: Ravi Dev Pandey <62198564+literalEval@users.noreply.github.com>
Co-authored-by: Mehmet <110852769+walterwhite351@users.noreply.github.com>
Co-authored-by: Taj <tjgurwara99@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions@users.noreply.github.com>
2022-12-28 21:41:05 +01:00

131 lines
5.0 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
* the given capacity and calculating the 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 the weight of items
* @param value array representing the value of items
* @return maximum value obtainable with a 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 the capacity of the 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 the 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 the current item
int profit1 = value[i - 1] + maxValue[i - 1][j - weight[i - 1]];
// not picking the current item
int profit2 = maxValue[i - 1][j];
maxValue[i][j] = std::max(profit1, profit2);
} else {
// as the weight of the current item is greater than the allowed weight, so
// maxProfit will be profit obtained by excluding the 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 the 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;
}