Recursion: Understanding (subset-sum) inclusion/exclusion pattern - c++

I need to understand how this recursion work, I understand simple recursion examples but more advanced ones is hard. Even thought there are just two lines of code I got problem with... the return statement itself. I just draw a blank on how this works, especially the and/or operator. Any insight is very welcome.
bool subsetSumExists(Set<int> & set, int target) {
if (set.isEmpty()) {
return target == 0;
} else {
int element = set.first();
Set<int> rest = set - element;
return subsetSumExists(rest, target)
|| subsetSumExists(rest, target - element);
}
}

Recursive code is normally coupled with the concept of reduction. In general, reduction is a means to reduce an unknown problem to a known one via some transformation.
Let's take a look at your code. You need to find whether a given target sum can be constructed from an elements of the input data set.
If the data set is empty, there is nothing to do besides comparing the target sum to 0.
Otherwise, let's apply the reduction. If we choose a number from the set, there can actually be 2 possibilities - the chosen number participates in the sum you're seeking or it doesn't. No other possibilities here (it's very important to cover the full spectrum of possibilities!). In fact, it doesn't really matter which data element is chosen as long as you can cover all the possibilities for the remaining data.
First case: the number doesn't participate in the sum. We can reduce the problem to a smaller one, with data set without the inspected element and the same target sum.
Second case: the number participates in the sum. We can reduce the problem to a smaller one, with data set without the inspected element and the requested sum decreased by the value of the number.
Note, you don't know at this point whether any of these cases is true. You just continue reducing them until you get to the trivial empty case where you can know for sure the answer.
The answer to the original question would be true if it's true for any of these 2 cases. That's exactly what operator || does - it will yield true if any of its operands (the outcome of the 2 cases) are true.

|| is logical OR. It's evaluated left-to-right and short-circuited.
This means that in an expression A || B, A is evaluated first. If it's true, the entire expression is true and no further evaluation is done. If A is false, B is evaluated and the expression gets the value of B.
In your example, A is "try getting the same sum without using the 1st element from the set". B is "use the 1st element from the set, which decreases the total left to sum, and try to get that with the rest of the element."

Lets first look at algorithm..
The base case(i.e the case in which recursion terminates) is when the set is empty.
Otherwise the program takes the first elements subtracts it from the set.
Now it will call subsetSumExists(rest, target) and check if its true,
if it is it will return true otherwise it will call
subsetSumExists(rest, target - element) and return whatever it
returns.
In simple terms, it will this call subsetSumExists(rest, target - element) only if first one subsetSumExists(rest, target) returns false.
Now lets try to dry run this code with a small sample set of {3,5} and a sum of 8. I'll call the function sSE from now on
sSE({3,5}, 8) => "sSE({5}, 8) || sSE({5},(8-3))"
sSE({5}, 8) => sSE({}, 8) || sSE({}, (8-5))
sSE({}, 8) => false.. now will call sSE({}, (8-5))
sSE({}, 3) => false.. now will call sSE({5}, (8-3))
sSE({5}, 5) => sSE({}, 5} || sSE({}, (5-5))
sSE({}, 5) => false.. now will call sSE({}, (5-5))
sSE({}, 0) => true.. ends here and return true

To understand recursion, you need to understrand recursion.
To do that, you need to think recusively.
In this particular case.
For any: subsetSum(set, target)
If set is empty AND target is 0, then subsetSum exists
Otherwise, remove first element of the set. check if subdetSum(set, target) exists OR subdetSum(set, target - removed_element) exists (using step 0)

The set subtraction looks a strange syntax but I will assume it means pop() on the element.
It "works" through finding every possible combination although it is exponential.
In the || statement, the LHS is the sum including the current element and the RHS is the sum excluding it. So you will get, down the exponential tree, every combination of each element either switched on or off.
Exponential, by the way, means that if you have 30 elements it will produce 2 to the power of 30, i.e. 0x40000000 or close to a billion combinations.
Of course you may well run out of memory.
If it finds the solution it might not run through all 2^N cases. If there is no solution it will always visit them all.

If I speak for myself, difficulty in understanding of the problem stems from || operator. Let's glance at bottom return statement of same code with another way,
if (subsetSumExists(rest, target - element))
return true;
if (subsetSumExists(rest, target))
return true;
return false;

Related

Using nested if statements vs logical operator && in c++

Let us say I have an integer array representing the chess pieces on a board;
int board[8][8];
In my chess game, I am currently coding a generator function that will return an integer vector of all legal moves.
Naturally, I will be using if statements
I am at a point where I need to check a certain element in the board relative to a piece on the board
For example, If I have a pawn piece;
board[row][col] == 'p';
I need to generate [row+1][col], [row+2][col] and in some cases if it can attack a piece, a change in column too.
But if a piece is on any edge of the board, board[row+1][col] will return be index out of range
For that reason I need an extra if statement.
My question is, shall i use:
if (pieceisnotonedge && board[row+1][col] == 0)
or
if (pieceisnotonedge)
{
if (board[row+1][col] == 0)
}
For the first example, if pieceisnotonedge returns false, will it also check the next condition? Because if it does, then I am in trouble.
For the first example, if pieceisnotonedge returns false, will it also
check the next condition?
No, it will not. Because the build-in logical operators do short-circuiting. From cppreference.com:
Builtin operators && and || perform short-circuit evaluation (do not
evaluate the second operand if the result is known after evaluating
the first), but overloaded operators behave like a regular function
calls and always evaluate both operands
Therefore, in
if (pieceisnotonedge && board[row+1][col] == 0)
if the pieceisnotonedge is false, the second will not be evaluated. Therefore, having a nested ifs is redundant, and you can go with the first version.
For the first example, if pieceisnotonedge returns false, will it also check the next condition?
No. It will "short-circuit" because if the first condition is false, checking the conditions after it is unnecessary. Read more here and here.
This is guranteed by the C++ standard:
7.6.14
... && guarantees left-to-right evaluation: the second operand is not evaluated if the first operand is false.
Note that, for || this is opposite, that is, if the first condition is "true", then checking the conditions afterwards is unnecessary
Shall i use; or...
Both are same, if you have a short if statement (with only two conditions), I would suggest using the first approach. In terms of efficiency there is no difference and you can verify this by looking at the generated assembly for both cases on godbolt
For the shown code there is no difference, both board[row+1][col] == 0 are only evaluated if pieceisnotonedge is true.
If you should use one or the other, cannot be said be in general, as it depends on other factors (like semantic, readability, …) too.
If you e.g. want to have an action that it done if either pieceisnotonedge or board[row+1][col] == 0 is false, then you probably would use &&, because then you can write:
if (pieceisnotonedge && board[row+1][col] == 0) {
} else {
// do something else
}
with your other style you would need to write:
if (pieceisnotonedge){
if (board[row+1][col] == 0) {
// do something else
}
} else {
// do something else
}
In general, your first aim should be to have readable code. While pieceisnotonedge && board[row+1][col] == 0 easy to read, more complex expressions might not be. So you would decide that on a case by case basis, if you want to use one expression or multiple if.
For the first example, if pieceisnotonedge returns false, will it also check the next condition?
No. It will stop immediately after pieceisnotonedge is evaluated to false. There is no subsequent check for the remainder condition board[row+1][col] == 0
You can use nested if as the second code as well - no difference. It's just a matter of what code would look clearer.

How to implement binary search on function in C++?

I've got a situation in C++ where I have a costly sub-problem: nearly a minute. Further, this subproblem--bool f(x)--gets longer as x ranges from [1,n].
On the range of [1,n], there is a point 1<j<n, f(j) = true such that f(k), k < j is always false...and f(m), j < m is always true.
I need to find that point.
The way I need to do it is with binary search starting at x=1 (so that it never even touches the time consuming region, where x is close to n).
Right now, I am manually slogging through a binary search implementation where I start at a minimum value for a function (so, f(1), which is false). Then I double the input value until I reach a state where f(x) is happy (true). This part is no big deal. I can do it manually fine.
Next, I want to binary search on the range [x/2,x] for the first value where f(x) = true (noting that f(x/2) must equal false, since f(1) = false...and I need to do it without making any mistakes. And this is where things are getting a little hairy.
So I have a creeping suspicion that C++ has this already implemented, but I am new to C++, and have limited experience with the libraries. I am currently looking at binary search, but I don't see a way to bin search for the actual point at which all values of a function change from false to true.
Rather, it seems to be greedy: it would just grab the first true it finds, rather than the minimum true.
How would I do this in C++?
The inputs of my search function would be as follows:
std::vector<int> range(max);
for (int j = 0; j < max; j++){
range[j] = j;
}
std::some_search_function(range.begin(),range.end(),f(int value))
where f(...) is the boolean function from before...
And it needs to have the properties of what I am describing: start from the first value in the item it is searching, and return the earliest item where f(...) is satisfied...
You can implement a custom iterator that "points" to true or false depending on the index it represents and use std::lower_bound function to find the first true value.

What is the difference between if(x^1!=1) and if(int(x^1)!=1) in C++?

I am trying to find if x's first bit from right is 1, so I check if the value of x^1 is 1. However,
int x=6;
if (x^1!=1)
gives wrong answer, but
if (int(x^1)!=1)
gives the correct answer.
I am not sure why. Could someone clarify this for me?
It's a trap of operator precedence. Operator precedence determines how operations are "grouped" (like how 2*3+4 results in the 2*3 being "grouped" together). Adding parentheses changes how things are "grouped" (for example, 2*(3+4) causes 3+4 to be "grouped" together).
x^1!=1 is equivalent to x^(1!=1), which can be simplified to x^0.
int(x^1)!=1 is equivalent to (x^1)!=1 (because you've manually added parentheses here; the int part isn't very relevant; it's the parentheses that are important).
As you can see, x^(1!=1) and (x^1)!=1 are not the same.
If your goal is to check the first bit, I might suggest using a bitwise-AND (&). You can then just do if (x & 1) (but beware, mixing & and == will result in the same issues as you were having before, so use parentheses if you want to write if ((x & 1) == 1)).
Simply, != (Not equal relational operator) has high precedence than ^ (XOR bitwise operator). Check precedence
int x=6;
case 1: if (x^1!=1)
First, 1!=1 is 0; then 6^0= 6. (110 ^ 000 = 110); Check XOR table
Case 2: if (int (x^1)!=1)
First, x^1= 7; then 7!=1 is 1 (true).
#Cornstalks is right with his answer.
I just had that in mind ( it does'nt in fact answer your problem , but can make it more readable) :
Another approach for solving this problem is simply using the modulo operator:
if(x%2 == 0) // then first bit is 0
else // first bit is 1
In the end your task is simply a check for even or odd values.

My recursive function does not return the correct value

I wrote a recursive function that computes the sum of an array of double. For some reasons, the value returned by my recursive function is not correct. Actually, my recursive sum does not match my iterative sum. I know I made a little mistake somewhere, but I can't see where. Your help will be very appreciated. I only pasted the recursive function. I am using C++ on Visual Studio. Thanks!
double recursive_sum(double array_nbr[], int size_ar)
{ double rec_sum=0.0;
if( size_ar== 0)
return -1;
else if( size_ar> 0)
rec_sum=array_nbr[size_ar-1]+recursive_sum(array_nbr,size_ar-1);
return rec_sum;
}
//#### Output######
The random(s) number generated in the array =
0.697653 | 0.733848 | 0.221564 |
Recursive sum: 0.653066
Iterative sum: 1.65307
Press any key to continue . . .
Well, because sum of no elements is zero, not minus one.
if (size_ar == 0.0)
return 0.0;
Think about it this way: sum(1,2,3) is the same as sum(1,2) + sum(3) just as it is the same as sum(1,2,3)+sum() — in all three cases, you add 1, 2, and 3 together, just in a slighlty different ways. That's also why the product of no elements is one.
Try changing "if( size_ar== 0) return -1;" to return 0.
While this does not account for the large discrepancy in your output, another thing to keep in mind is the ordering of operations once you have fixed the issue with returning a -1 vs. 0 ... IEEE floating point operations are not necessarily commutative, so make sure that when you are doing your recursive vs. iterative methods, you add up the numbers in the exact same order, otherwise your output may still differ by some epsilon value.
For instance, currently in your recursive method you're adding up the values from the last member of the array in reverse to the first member of the array. That may, because of the non-commutative property of floating point math, give you a slightly different value (small epsilon) than if you sum up the values in the array from first to last. This probably won't show on a simple cout where the floating point values are truncated to a specific fixed decimal position, but should you attempt to use the == operation on the two different summations without incorporating some epsilon value, the result may still test false.

Recursive Backtracking Sudoku Solver Problems, c++

It's my first time dealing with recursion as an assignment in a low level course. I've looked around the internet and I can't seem to find anybody using a method similar to the one I've come up with (which probably says something about why this isn't working). The error is a segmentation fault in std::__copy_move... which I'm assuming is something in the c++ STL.
Anywho, my code is as follows:
bool sudoku::valid(int x, int y, int value)
{
if (x < 0) {cerr << "No valid values exist./n";}
if (binary_search(row(x).begin(), row(x).end(), value))
{return false;} //if found in row x, exit, otherwise:
else if (binary_search(col(y).begin(), col(y).end(), value))
{return false;} //if found in col y, exit, otherwise:
else if (binary_search(box((x/3), (y/3)).begin(), box((x/3), (y/3)).end(), value))
{return false;} //if found in box x,y, exit, otherwise:
else
{return true;} //the value is valid at this index
}
int sudoku::setval(int x, int y, int val)
{
if (y < 0 && x > 0) {x--; y = 9;} //if y gets decremented past 0 go to previous row.
if (y > 8) {y %= 9; x++;} //if y get incremented past 8 go to next row.
if (x == 9) {return 0;} //base case, puzzle done.
else {
if (valid(x,y,val)){ //if the input is valid
matrix[x][y] = val; //set the element equal to val
setval(x,y++,val); //go to next element
}
else {
setval(x,y,val++); //otherwise increment val
if(val > 9) {val = value(x,y--); setval(x,y--,val++); }
} //if val gets above 9, set val to prev element,
} //and increment the last element until valid and start over
}
I've been trying to wrap my head around this thing for a while and I can't seem to figure out what's going wrong. Any suggestions are highly appreciated! :)
sudoku::setval is supposed to return an int but there are at least two paths where it returns nothing at all. You should figure out what it needs to return in those other paths because otherwise you'll be getting random undefined behavior.
Without more information, it's impossible to tell. Things like the data
structures involved, and what row and col return, for example.
Still, there are a number of obvious problems:
In sudoku::valid, you check for what is apparently an error
condition (x < 0), but you don't return; you still continue your
tests, using the negative value of x.
Also in sudoku:valid: do row and col really return references to
sorted values? If the values aren't sorted, then binary_search will
have undefined behavior (and if they are, the names are somewhat
misleading). And if they return values (copies of something), rather
than a reference to the same object, then the begin() and end()
functions will refer to different objects—again, undefined
behavior.
Finally, I don't see any backtracking in your algorithm, and I don't
see how it progresses to a solution.
FWIW: when I wrote something similar, I used a simple array of 81
elements for the board, then created static arrays which mapped the
index (0–80) to the appropriate row, column and box. And for each of
the nine rows, columns and boxes, I kept a set of used values (a
bitmap); this made checking for legality very trivial, and it meant that
I could increment to the next square to test just by incrementing the
index. The resulting code was extremely simple.
Independently of the data representation used, you'll need: some
"global" (probably a member of sudoku) means of knowing whether you've
found the solution or not; a loop somewhere trying each of the nine
possible values for a square (stopping when the solution has been
found), and the recursion. If you're not using a simple array for the
board, as I did, I'd suggest a class or a struct for the index, with a
function which takes care of the incrementation once and for all.
All of the following is for Unix not Windows.
std::__copy_move... is STL alright. But STL doesn't do anything by itself, some function call from your code would've invoked it with wrong arguments or in wrong state. You need to figure that out.
If you have a core dump from teh seg-fault then just do a pstack <core file name>, you will see the full call stack of the crash. Then just see which part of your code was involved in it and start debugging (add traces/couts/...) from there.
Usually you'll get this core file with nice readable names, but in case you don't you can use nm or c++filt etc to dismangle the names.
Finally, pstack is just a small cmd line utility, you can always load the binary (that produced the core) and the core file into a debugger like gdb, Sun Studio or debugger built into your IDE and see the same thing along with lots of other info and options.
HTH
It seems like your algorithm is a bit "brute forcy". This is generally not a good tactic with Constraint Satisfaction Problems (CSPs). I wrote a sudoku solver a while back (wish I still had the source code, it was before I discovered github) and the fastest algorithm that I could find was Simulated Annealing:
http://en.wikipedia.org/wiki/Simulated_annealing
It's probabilistic, but it was generally orders of magnitude faster than other methods for this problem IIRC.
HTH!
segmentation fault may (and will) happen if you enter a function recursively too many times.
I noted one scenario which lead to it. But I'm pretty sure there are more.
Tip: write in your words the purpose of any function - if it is too complicated to write - the function should probably be split...