TheAlgorithms-C-Plus-Plus/dynamic_programming/partition_problem.cpp
Lajat5 5147306db3
feat: Added Solution of Partition Problem (#1842)
* Create partition_problem.cpp

* Fix #1

* Fix #2

* updating DIRECTORY.md

* clang-format and clang-tidy fixes for 3b8dbf00

* Update dynamic_programming/partition_problem.cpp

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

* Update dynamic_programming/partition_problem.cpp

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

* clang-format and clang-tidy fixes for a152bf75

* Update dynamic_programming/partition_problem.cpp

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

* Update dynamic_programming/partition_problem.cpp

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

* Update dynamic_programming/partition_problem.cpp

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

* clang-format and clang-tidy fixes for 1c057113

* Update dynamic_programming/partition_problem.cpp

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

* Update dynamic_programming/partition_problem.cpp

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

* clang-format and clang-tidy fixes for baf20a6f

* Update dynamic_programming/partition_problem.cpp

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

* clang-format and clang-tidy fixes for 749d9337

Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com>
Co-authored-by: David Leal <halfpacho@gmail.com>
2021-11-14 10:55:54 -06:00

107 lines
4.2 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 the [Partition
* Problem](https://en.wikipedia.org/wiki/Partition_problem )
* @details
* The partition problem, or number partitioning, is the task of deciding
* whether a given multiset S of positive integers can be partitioned into two
* subsets S1 and S2 such that the sum of the numbers in S1 equals the sum of
* the numbers in S2. Although the partition problem is NP-complete, there is a
* pseudo-polynomial time dynamic programming solution, and there are heuristics
* that solve the problem in many instances, either optimally or approximately.
* For this reason, it has been called "the easiest hard problem".
*
* The worst case time complexity of Jarviss Algorithm is O(n^2). Using
* Grahams scan algorithm, we can find Convex Hull in O(nLogn) time.
*
* ### Implementation
*
* Step 1
* Calculate sum of the array. If sum is odd, there can not be two subsets with
* equal sum, so return false.
*
* Step 2
* If sum of array elements is even, calculate sum/2 and find a subset of array
* with sum equal to sum/2.
*
* @author [Lajat Manekar](https://github.com/Lazeeez)
*
*******************************************************************************/
#include <cassert> /// for assert
#include <iostream> /// for IO Operations
#include <numeric> /// for std::accumulate
#include <vector> /// for std::vector
/******************************************************************************
* @namespace dp
* @brief Dynamic programming algorithms
*******************************************************************************/
namespace dp {
/******************************************************************************
* @namespace partitionProblem
* @brief Partition problem algorithm
*******************************************************************************/
namespace partitionProblem {
/******************************************************************************
* @brief Returns true if arr can be partitioned in two subsets of equal sum,
* otherwise false
* @param arr vector containing elements
* @param size Size of the vector.
* @returns @param bool whether the vector can be partitioned or not.
*******************************************************************************/
bool findPartiion(const std::vector<uint64_t> &arr, uint64_t size) {
uint64_t sum = std::accumulate(arr.begin(), arr.end(),
0); // Calculate sum of all elements
if (sum % 2 != 0) {
return false; // if sum is odd, it cannot be divided into two equal sum
}
std::vector<bool> part;
// bool part[sum / 2 + 1];
// Initialize the part array as 0
for (uint64_t it = 0; it <= sum / 2; ++it) {
part.push_back(false);
}
// Fill the partition table in bottom up manner
for (uint64_t it = 0; it < size; ++it) {
// The element to be included in the sum cannot be greater than the sum
for (uint64_t it2 = sum / 2; it2 >= arr[it];
--it2) { // Check if sum - arr[i]
// ould be formed from a subset using elements before index i
if (part[it2 - arr[it]] == 1 || it2 == arr[it]) {
part[it2] = true;
}
}
}
return part[sum / 2];
}
} // namespace partitionProblem
} // namespace dp
/*******************************************************************************
* @brief Self-test implementations
* @returns void
*******************************************************************************/
static void test() {
std::vector<uint64_t> arr = {{1, 3, 3, 2, 3, 2}};
uint64_t n = arr.size();
bool expected_result = true;
bool derived_result = dp::partitionProblem::findPartiion(arr, n);
std::cout << "1st test: ";
assert(expected_result == derived_result);
std::cout << "Passed!" << std::endl;
}
/*******************************************************************************
* @brief Main function
* @returns 0 on exit
*******************************************************************************/
int main() {
test(); // run self-test implementations
return 0;
}