Tug of War | GeeksforGeeks
Given a set of n integers, divide the set in two subsets of n/2 sizes each such that the difference of the sum of two subsets is as minimum as possible. If n is even, then sizes of two subsets must be strictly n/2 and if n is odd, then size of one subset must be (n-1)/2 and size of other subset must be (n+1)/2.
The following solution tries every possible subset of half size. If one subset of half size is formed, the remaining elements form the other subset. We initialize current set as empty and one by one build it. There are two possibilities for every element, either it is part of current set, or it is part of the remaining elements (other subset). We consider both possibilities for every element. When the size of current set becomes n/2, we check whether this solutions is better than the best solution available so far. If it is, then we update the best solution.
http://codefordummies.blogspot.com/2013/10/backtracking-tug-of-war.html
It's not good to always compute selected size and diff every time.
// 1. in each iteration, either add or remove the current element from the selected array // 2. check if we have already selected the requried number of elements, in that case update solution // 3. check if have already reached the end of the array, in that case, simply return protected static void solve(int currentIndex) { // get size of selected int selectedSize = 0; for (int i = 0; i < n; i++) if (selected[i]) selectedSize++; if (selectedSize == n / 2) { // check if diff < minDiff, update solution int diff = getDiff(); if (diff < minDiff) { minDiff = diff; updateSolution(); } } // check if currentIndex == n and return if (currentIndex >= n) return; // add curindex to selected selected[currentIndex] = true; solve(currentIndex + 1); // remove curindex from selected selected[currentIndex] = false; solve(currentIndex + 1); }
protected static int getDiff() { int leftSum = 0; int rightSum = 0; for (int i = 0; i < n; i++) { if (selected[i]) leftSum += a[i]; else rightSum += a[i]; } return Math.abs(rightSum - leftSum); }
Read full article from Tug of War | GeeksforGeeks
Given a set of n integers, divide the set in two subsets of n/2 sizes each such that the difference of the sum of two subsets is as minimum as possible. If n is even, then sizes of two subsets must be strictly n/2 and if n is odd, then size of one subset must be (n-1)/2 and size of other subset must be (n+1)/2.
The following solution tries every possible subset of half size. If one subset of half size is formed, the remaining elements form the other subset. We initialize current set as empty and one by one build it. There are two possibilities for every element, either it is part of current set, or it is part of the remaining elements (other subset). We consider both possibilities for every element. When the size of current set becomes n/2, we check whether this solutions is better than the best solution available so far. If it is, then we update the best solution.
// function that tries every possible solution by calling itself recursively
void
TOWUtil(
int
* arr,
int
n,
bool
* curr_elements,
int
no_of_selected_elements,
bool
* soln,
int
* min_diff,
int
sum,
int
curr_sum,
int
curr_position)
{
// checks whether the it is going out of bound
if
(curr_position == n)
return
;
// checks that the numbers of elements left are not less than the
// number of elements required to form the solution
if
((n/2 - no_of_selected_elements) > (n - curr_position))
return
;
// consider the cases when current element is not included in the solution
TOWUtil(arr, n, curr_elements, no_of_selected_elements,
soln, min_diff, sum, curr_sum, curr_position+1);
// add the current element to the solution
no_of_selected_elements++;
curr_sum = curr_sum + arr[curr_position];
curr_elements[curr_position] =
true
;
// checks if a solution is formed
if
(no_of_selected_elements == n/2)
{
// checks if the solution formed is better than the best solution so far
if
(
abs
(sum/2 - curr_sum) < *min_diff)
{
*min_diff =
abs
(sum/2 - curr_sum);
for
(
int
i = 0; i<n; i++)
soln[i] = curr_elements[i];
}
}
else
{
// consider the cases where current element is included in the solution
TOWUtil(arr, n, curr_elements, no_of_selected_elements, soln,
min_diff, sum, curr_sum, curr_position+1);
}
// removes current element before returning to the caller of this function
curr_elements[curr_position] =
false
;
}
// main function that generate an arr
void
tugOfWar(
int
*arr,
int
n)
{
// the boolen array that contains the inclusion and exclusion of an element
// in current set. The number excluded automatically form the other set
bool
* curr_elements =
new
bool
[n];
// The inclusion/exclusion array for final solution
bool
* soln =
new
bool
[n];
int
min_diff = INT_MAX;
int
sum = 0;
for
(
int
i=0; i<n; i++)
{
sum += arr[i];
curr_elements[i] = soln[i] =
false
;
}
// Find the solution using recursive function TOWUtil()
TOWUtil(arr, n, curr_elements, 0, soln, &min_diff, sum, 0, 0);
// Print the solution
cout <<
"The first subset is: "
;
for
(
int
i=0; i<n; i++)
{
if
(soln[i] ==
true
)
cout << arr[i] <<
" "
;
}
cout <<
"\nThe second subset is: "
;
for
(
int
i=0; i<n; i++)
{
if
(soln[i] ==
false
)
cout << arr[i] <<
" "
;
}
}
http://codefordummies.blogspot.com/2013/10/backtracking-tug-of-war.html
It's not good to always compute selected size and diff every time.
// 1. in each iteration, either add or remove the current element from the selected array // 2. check if we have already selected the requried number of elements, in that case update solution // 3. check if have already reached the end of the array, in that case, simply return protected static void solve(int currentIndex) { // get size of selected int selectedSize = 0; for (int i = 0; i < n; i++) if (selected[i]) selectedSize++; if (selectedSize == n / 2) { // check if diff < minDiff, update solution int diff = getDiff(); if (diff < minDiff) { minDiff = diff; updateSolution(); } } // check if currentIndex == n and return if (currentIndex >= n) return; // add curindex to selected selected[currentIndex] = true; solve(currentIndex + 1); // remove curindex from selected selected[currentIndex] = false; solve(currentIndex + 1); }
protected static int getDiff() { int leftSum = 0; int rightSum = 0; for (int i = 0; i < n; i++) { if (selected[i]) leftSum += a[i]; else rightSum += a[i]; } return Math.abs(rightSum - leftSum); }
Read full article from Tug of War | GeeksforGeeks