Related
I am solving the following problem from hackerrank
https://www.hackerrank.com/challenges/coin-change/problem
I 'm unable to solve the problem , so I have looked at the editorial and they mentioned
T(i, m) = T(i, m-i)+T(i+1, m)
I'm unable to get big picture of why this solution works on a higher level. (like a proof in CLRS or simple understandable example)
Solution which I have written is as follows
fun(m){
//base cases
count = 0;
for(i..n){
count+= fun(m-i);
}
}
My solution didn't work because there are some duplicates calls. But how editorial works and what is the difference between my solution and editorial on a higher level..
I think in order for this to work you have to clearly define what T is. Namely, let's define T(i,m) to be the number of ways to make change for m units using only coins with index at least i (i.e. we only look at the ith coin, the (i+1)th coin, all the way to the nth coin while neglecting the first i-1 coins). Further, we define an array C such that C[i] is the value of the ith coin (note that in general C[i] is not the same as i). As a result, if there are n coins (i.e. length of C is n) and we want to make change for W units, we are looking for the value T(0, W) as our answer (make sure you can see why this is the case at this point!).
Now, we proceed by constructing a recursive definition of T(i,m). Note that our solution will either contain an additional ith coin or it won't. In the case that it does, our new target will simply be m - C[i] and the number of ways to make change for this is T(i,m - C[i]) (since our new target is now C[i] less than m). In another case, our solution doesn't contain the ith coin. In this case, we keep the target value the same, but only consider coins with index greater than i. Namely, the number of ways to make change in this case is T(i+1,m). Since these cases are disjoint and exhaustive (either you put the ith coin in the solution or you don't!), we have that
T(i,m) = T(i, m-C[i]) + T(i+1,m)
which is very similar to what you had (the C[i] difference is important). Note that if m <= 0 (since we are assuming that coin values are positive), there are 0 ways to make change. You must keep these base cases in mind when computing T(i,m).
Now it remains to compute T(0, W), which you can easily do recursively. However, you likely noticed that a lot of the subproblems are repeated making this a slow solution. The solution is to use something called dynamic programming or memoization. Namely, whenever a solution is computed, add its value to a table (e.g. T[i,m] where T is a n x W size 2D array). Then whenever you recursively compute something check the table first so you don't compute the same thing twice. This is called memoization. Dynamic programming is simple except you use a little foresight to compute things in the order in which they will be needed. For example, I would compute the base cases first i.e. the column T[ . , 0]. And then I would compute all values bordering this row and column based on the recursive definition.
Where m = 2^32+1 = 641*6700417 the mod function is little more than a single subtract on 32-bit processors. I don’t care that the recurrence
Seed = Seed*a%m
is not a good random number generator. I wish to use it in an encryption algorithm as a 32-bit wide sbox. Is there an algorithm that would return true if a trial value of “a” would cause the recurrence to visit all 2^32 values?
Assuming that such an algorithm exits I suspect that if a*b%m = 1 then the recurrence using “b” would run backwards. Is what I suspect true. I would use “b” to implement the inverse sbox.
I can do everything I ask using mod (2^16+1) but that number is prime.
Is there an algorithm that would return true if a trial value of “a” would cause the recurrence to visit all 232 values?
Yes there is:
return false;
The most obvious reason is that the set of all 232 possible values includes the value zero, and there the recurrence gets stuck, so it isn't cyclic. But even if you exclude zero, if you start with a multiple of 641, then you will only ever visit multiples of 641, and the same holds for the other factor.
This kind of “visit all values” property only works if you reduce modulo some prime, and if you exclude zero.
This is not a very simple question. It is easy to answer that in your case the numbers you use are poor. However, the easy answer: use primes is not the correct answer, either.
If we use the recurrence:
r := (r a) mod m
it is easy to see, that this gives the maximal cycle (m-1) if and only if all a^i mod m give different numbers for i = 0 .. m-2. However, this does not automatically happen even if both a and m are primes.
An example of two primes which cannot be used: a = 13, m = 17, because 13^4 mod 17 == 1, and the cycle will be very short (4 steps).
So, we need some other requirements, as well. To make a very long story short, a generator of this type (multiplicative congruential generator) produces the maximal cycle (m-1) if:
m is prime
a is a primitive root of m
Unfortunately, the latter requirement is a bit difficult, as there is no general formula to find primitive roots. (And please note that a does not have to be a prime, for example the combination m=17 and a=10 gives the full cycle.)
So, despite this being a seemingly simple problem, it touches some rather fundamental aspects of number theory.
Does there exist some algorithm that allows for the creation of a mathematical model given an inclusive set?
I'm not sure I'm asking that correctly... Let me try again...
Given some input set...
int Set[] = { 1, 4, 9, 16, 25, 36 };
Does there exist an algorithm that would be able to deduce the pattern evident in the set? In this case being...
Set[x] = x^2
The only way I can think of doing something like this is some GA where the fitness is how closely the generated model matches the input set.
Edit:
I should add that my problem domain implies that the set is inclusive. Meaning, I am finding the closest possible function for the set and not using the function to extrapolate beyond the set...
The problem of curve fitting might be a reasonable place to start looking. I'm not sure if this is exactly what you're looking for - it won't really identify the pattern so much as just produce a function which follows the pattern as closely as possible.
As others have mentioned, for a simple set there can easily be infinitely many such functions, so something like this may be what you want, rather than exactly what you have described in your question.
Wikipedia seems to indicate that the Gauss-Newton algorithm or the Levenberg–Marquardt algorithm might be a good place to begin your research.
A mathematical argument explaining why, in general, this is impossible:
There are only countably many computer programs that can be written at all.
There are uncountably many infinite sequences of integers.
Therefore, there are infinitely many sequences of integers for which no possible computer program can generate those sequences.
Accordingly, this is impossible in the general case. Sorry!
Hope this helps!
If you want to know if the given data fits some polynomial function, you compute successive differences until you reach a constant. The number of differences to reach the constant is the degree of the polynomial.
x | 1 2 3 4
y | 1 4 9 16
y' | 3 5 7
y" | 2 2
Since y" is 2, y' is 2x + C1, and thus y is x2 + C1x + C2. C1 is 0, since 2×1.5 = 3. C2 is 0 because 12 = 1. So, we have y = x2.
So, the algorithm is:
Take successive differences.
If it does not converge to a constant, either resort to curve fitting, or report the data is insufficient to determine a polynomial.
If it does converge to a constant, iteratively integrate polynomial expression and evaluate the trailing constant until the degree is achieved.
Suppose you are given a function of a single variable and arguments a and b and are asked to find the minimum value that the function takes on the interval [a, b]. (You can assume that the argument is a double, though in my application I may need to use an arbitrary-precision library.)
In general this is a hard problem because functions can be weird. A simple version of this problem would be to minimize the function assuming that it is continuous (no gaps or jumps) and single-peaked (there is a unique minimum; to the left of the minimum the function is decreasing and to the right it is increasing). Is there a good way to solve this easier (but perhaps not easy!) problem?
Assume that the function may be difficult to calculate but not particularly expensive to store an answer that you've computed. (Obviously, it's better if you don't have to make giant arrays of key/value pairs.)
Bonus points for good ideas on improving the algorithm in the fortunate case in which it's nice (e.g.: derivative exists, function is smooth/analytic, derivative can be computed in closed form, derivative can be computed at no cost when the function is evaluated).
The version you describe, with a single minimum, is easy to solve.
The idea is this. Suppose that I have 3 points with a < b < c and f(b) < f(a) and f(b) < f(c). Then the true minimum is between a and c. Furthermore if I pick another point d somewhere in the interval, then I can throw away one of a or d and still have an interval with the true minimum in the middle. My approximations will improve exponentially quickly as I do more iterations.
We don't quite start with this. We start with 2 points, a and b, and know that the answer is somewhere in the middle. Take the mid-point. If f there is below the end points, we're into the case I discussed above. Otherwise it must be below one of the end points, and above the other. We can throw away the higher end point and repeat.
If the function is nice, i.e., single-peaked and strictly monotonic (i.e., strictly decreasing to the left of the minimum and strictly increasing to the right), then you can find the minimum with binary search:
Set x = (b-a)/2
test whether x is to the right of the minimum or to the left
if x is left of the minimum:b = x
if x is right of the minimum:a = x
repeat from start until you get bored
the minimum is at x
To test whether x is left/right of the minimum, invent a small value epsilon and check whether f(x - epsilon) < f(x + epsilon). If it is, the minimum is to the left, otherwise it's to the right. By "until you get bored", I mean: invent another small value delta and stop if fabs(f(x - epsilon) - f(x + epsilon)) < delta.
Note that in the general case where you don't know anything about the behavior of a function f, it's not possible to decide a non-trivial property of f. Well, unless you're willing to try all possible inputs. See Rice's Theorem for details.
The Boost project has an implementation of Brent's algorithm that may be useful.
It seems to assume that the function is continuous, and has no maxima (only a minimum) in the input interval.
Not a direct answer but a pointer to more reading:
scipy.optimize: http://docs.scipy.org/doc/scipy/reference/optimize.html
section e04 of naglib: http://www.nag.co.uk/numeric/cl/nagdoc_cl09/html/genint/libconts.html
For the special case where the function is differentiable twice (and the two derivatives can be calculated easily), one can use Newton's method for optimization, i.e. essentially finding the roots of the first derivative (which is a necessary condition for the minimum).
Concerning the general case, note that the extreme case of 'weird' is a function which is continuous nowhere and for which it is very hard if not impossible to find the minimum (in finite time). So I guess you should try to make at least some assumptions about the function you are trying to minimize.
What you want is to optimize an Unimodal function. The correct algorithm is similar to btilly's but you need extra points.
Take 4 points a < b < c < d.
We want to minimize f in [a,d].
If f(b) < f(c) we know the minimum is in [a, c]
If f(b) > f(c) " " " " is in [b, d]
This can give an algorithm by itself, but there is a nice trick involving the golden ratio that allows you to reuse the intermediate values (in a way you only need to compute f once per iteration instead of twice)
If you have an expression for the function, there are global optimization algorithms based on interval analysis.
This question is purely out of curiosity. I am off school for the summer, and was going to implement an algorithm to solve this just for fun. That led to the above question, how hard is this problem?
The problem: you are given a list of positive integers, a set of mathematical operators and the equal sign(=). can you create a valid mathematical expression using the integers (in the same order) and the operators (any number of times)?
An example will should clarify any questions:
given: {2, 3, 5, 25} , {+, -, *, /} , {=}
output: YES
the expression (only one i think) is (2 + 3) * 5 = 25. you only need to output YES/NO.
I believe the problem is in NP. I say this because it is a decision problem (YES/NO answer) and I can find a non-deterministic poly time algorithm that decides it.
a. non-deterministically select a sequence of operators to place between the integers.
b. verify you answer is a valid mathematical expression (this can be done in constant
time).
In this case, the big question is this: Is the problem in P? (i.e. Is there a deterministic poly time algorithm that decides it?) OR Is the problem NP complete? (i.e. Can a known NP Complete problem be reduced to this? or equivalently Is every NP language poly time reducable to this problem?) OR neither? (i.e. problem in NP but not NP Complete)
Note: This problem statement assumes P not equal to NP. Also, although I am new to Stack Overflow, I am familiar with the homework tag. This is indeed just curiosity, not homework :)
An straightforward reduction from the Partition problem (which is NP-Complete) - given a set of N integers S, the input to the "Valid Math" problem would be - the elements of S, N-2 '+' operators and an '=' sign.
There seems to be some sort of confusion about how to check for NP-completeness. An NP-complete problem is at least as hard, in a particular sense, as any other problem in NP. Suppose we were comparing to 3SAT, as some posters are trying to do.
Now, reducing the given problem to 3SAT proves nothing. It is then true that, if 3SAT can be solve efficiently (meaning P=NP), the given problem can be solved efficiently. However, if the given problem can be solved efficiently, then perhaps it corresponds only to easy special cases of 3SAT.
We would have to reduce 3SAT to the given problem. This means that we would have to make up a rule to transform arbitrary 3SAT problems to examples of the given problem, such that the solution of the given problem would tell us how to solve the 3SAT problem. This means that 3SAT couldn't be harder than the given problem. Since 3SAT is the hardest possible, then the given problem must also be the hardest possible.
The reduction from the Partition problem works. That problem works like this: given a multiset S of integers, can we divide this into two disjoint subsets that between them include each member of S, such that the sums of the disjoint subsets are equal?
To do this, we construct a sequence beginning with 0, containing each element of S, and then 0. We use {+, -} as the operation set. This means that each element of S will be either added or subtracted to total to 0, meaning that the sum of the added elements is the same as the sum of the subtracted elements.
Therefore, this problem is at least as hard as the Partition problem, since we can solve a example Partition program if we can solve the given one, and is therefore NP-complete.
OK, first, you specify "set" of integers but a set is by definition unordered, so you mean a "list" of integers.
Also, I am going to make an assumption here which may be wrong, which is that the = sign always appears exactly once, between the second to last and the last integer on your list. If you allow the equals sign in the middle, it becomes more complicated.
Here is an actual proof that "Valid Mathematical Expression" (VME) is NP complete. We can do a reduction from Subset sum. NOTE that Wikipedia's definition of subset sum requires that the subset is non-empty. In fact, it is true that the more general problem of subset sum allowing empty subsets is NP complete, if the desired sum is also part of the input. I won't give that proof unless requested. Given the instance of subset sum {i_1, i_2, ..., i_n} along with desired sum s, create the following instance of VME:
{0, i_1, 0, i_2, 0, ..., i_n, s}, {+, *}, {=}
IF the instance of subset sum is solvable, then there is some subset of the integers that adds to 0. If the integer i1 is part of the sum, add it with its corresponding zero (immediately to the left) and if i1 is not part of the sum, multiply it. Between each zero and the term to the right, insert an addition sign.
Taking the Wikipedia example
{−7, −3, −2, 5, 8}
where { −3, −2, 5} sums to 0, we would encode it as
{0, -7, 0, -3, 0, -2, 0, 5, 0, 8, 0}
and the resulting expression would be
{0*7 + 0 + -3 + 0 + -2 + 0 + 5 + 0*8 = 0}
Now we also need to show that any solution to this instance of VME results in a solution to the instance of subset sum. This is easier than you think. When we look at a resulting expression, we can group the numbers into those which are multiplied with a 0 (including as part of a chain multiplication) and those that are not. Any number that is multiplied with a zero is not included in the final sum. Any number that is not multiplied with a zero must be added into the final sum.
So we have shown that this instance of VME is solvable IF and ONLY IF the corresponding instance of subset sum is solvable, so the reduction is complete.
EDIT: The Partition reduction (with the comment) works as well, and is better because it allows you to put the equals sign anywhere. Neat!
Don't have the time for the full answer right now, but you can describe a reduction from this problem to the Knapsack Problem.
Using dynamic programming you can achieve pseudo-polynomial time solution. Note that this does not conflict with the fact that the problem is indeed NP Complete.
There are two properties that need to be satisfied for it to be NP Complete.
A decision problem C is NP-complete if:
C is in NP, and
Every problem in NP is reducible to C in polynomial time.
We have established 1. 2 results from the fact that every problem in NP is reducible to 3SAT and 3SAT is reducible to the current problem.
Therefore it is NP-complete.
(edit) Answer to the comment below:
I will prove that SAT is reducible to the current problem, and since 3SAT is reducible to SAT, the result follows.
Input formula is the conjunction of the following expressions:
(x1 V x2 V x3 V ... xn V y1)
(x1 V x2 V x3 V ... xn V y2)
(x1 V x2 V x3 V ... xn V y3)
.
.
.
(x1 V x2 V x3 V ... xn V y64)
where each yi is a boolean based on what the order of the operators applied between all the xi's is.
i.e., yi can take a total of 4x4x4x4x1 values (assuming that only +, -, x, / are the operators and = is always the last operator; this can be changed if the operator set is modified to include other operators)
If none of the expressions is true, then the complete expression will evaluate to FALSE, and there is no way to check unless we substitute all possible values, i.e, x1 through xn as the n numbers and y1 through y64 as the various ways in which the operators can be applied (This takes care of order)
This conversion is in POLY-time, and the given boolean formula is satisfiable iff the mathematical expression is valid, etc.
Anyone notice a flaw?
This isn't really an answer to your complexity question, but your problem sounds a bit like the Countdown problem. A quick search turned up this paper: http://www.cs.nott.ac.uk/~gmh/countdown.pdf
I don't have to time to work out a proof at the moment, but a hunch tells me that it may not be in P. you can define a grammar for arithmetic, and then this question amounts to finding if there's a valid parse tree that uses all these terminals. i believe that that problem is in NP but outside of P.