I have given a Set A I have to find the sum of Fibonacci Sum of All the Subsets of A.
Fibonacci(X) - Is the Xth Element of Fibonacci Series
For example, for A = {1,2,3}:
Fibonacci(1) + Fibonacci(2) + Fibonacci(3) + Fibonacci(1+2) + Fibonacci(2+3) + Fibonacci(1+3) + Fibonacci(1+2+3)
1 + 1 + 2 + 2 + 5 + 3 + 8 = 22
Is there any way I can find the sum without generating the subset?
Since I find the Sum of all subset easily
i.e. Sum of All Subset - (1+2+3)*(pow(2,length of set-1))
There surely is.
First, let's recall that the nth Fibonacci number equals
φ(n) = [φ^n - (-φ)^(-n)]/√5
where φ = (√5 + 1)/2 (Golden Ratio) and (-φ)^(-1) = (1-√5)/2. But to make this shorter, let me denote φ as A and (-φ)^(-1) as B.
Next, let's notice that a sum of Fibonacci numbers is a sum of powers of A and B:
[φ(n) + φ(m)]*√5 = A^n + A^m - B^n - B^m
Now what is enough to calc (in the {1,2,3} example) is
A^1 + A^2 + A^3 + A^{1+2} + A^{1+3} + A^{2+3} + A^{1+2+3}.
But hey, there's a simpler expression for this:
(A^1 + 1)(A^2 + 1)(A^3 + 1) - 1
Now, it is time to get the whole result.
Let our set be {n1, n2, ..., nk}. Then our sum will be equal to
Sum = 1/√5 * [(A^n1 + 1)(A^n2 + 1)...(A^nk + 1) - (B^n1 + 1)(B^n2 + 1)...(B^nk + 1)]
I think, mathematically, this is the "simplest" form of the answer as there's no relation between n_i. However, there could be some room for computative optimization of this expression. In fact, I'm not sure at all if this (using real numbers) will work faster than the "straightforward" summing, but the question was about avoiding subsets generation, so here's the answer.
I tested the answer from YakovL using Python 2.7. It works very well and is plenty quick. I cannot imagine that summing the sequence values would be quicker. Here's the implementation.
_phi = (5.**0.5 + 1.)/2.
A = lambda n: _phi**n
B = lambda n: (-_phi)**(-n)
prod = lambda it: reduce(lambda x, y: x*y, it)
subset_sum = lambda s: (prod(A(n)+1 for n in s) - prod(B(n)+1 for n in s))/5**0.5
And here are some test results:
print subset_sum({1, 2, 3})
# 22.0
# [Finished in 0.1s]
print subset_sum({1, 2, 4, 8, 16, 32, 64, 128, 256, 512})
# 7.29199318438e+213
# [Finished in 0.1s]
Related
So what I want to do is breaking down numbers that are dozens of thousands big into smaller numbers, preferably 2~9.
The first thing came to my mind was prime factorization, for instance the number 49392 can be expressed as (2 x 2 x 2 x 2 x 3 x 3 x 7 x 7 x 7). But there are prime numbers and numbers such as 25378 = 2 × 12689 that cant be expressed with only multiplication.
So I want to break these numbers down using multiplication and addition, for example, the number 25378 could be expressed as 25346 + 32 = (2 × 19 × 23 × 29) + (2^5). Still, 23 and 29 are too big but I just picked random number just to show what I mean by using addtion and multiplication together to express big numbers, I'm sure there's a better combination of number that express 25378 than 25346 and 32.
Anyways, I thought programming this would involve ton of unnecessary if statement and would be incredibly slow in the big picture. So I was wondering, if there is a mathematical algorithm or function that does this thing? If not, I could just optimize the code myself, but I was just curious, I couldn't find anything on google myself though.
Assuming the problem is to write a number as the simplest expression containing the numbers 1-9, addition and multiplication (simplest = smallest number of operators), then this Python program does this in O(N^2) time.
A number N can be written as the sum or product of two smaller numbers, so if you've precalculated the simplest way of constructing the numbers 1..N-1, then you can find the simplest way of constructing N in O(N) time. Then it's just a matter of avoiding duplicate work -- for example without loss of generality in the expressions A+B and AB, A<=B, and nicely printing out the final expression.
def nice_exp(x, pri):
if isinstance(x, int):
return str(x)
else:
oppri = 1 if x[0] == '*' else 0
if oppri < pri:
bracks = '()'
else:
bracks = ['', '']
return '%s%s %s %s%s' % (bracks[0], nice_exp(x[1], oppri), x[0], nice_exp(x[2], oppri), bracks[1])
def solve(N):
infinity = 1e12
size = [infinity] * (N+1)
expr = [None] * (N+1)
for i in range(N+1):
if i < 10:
size[i] = 1
expr[i] = i
continue
for j in range(2, i):
if j * j > i: break
if i%j == 0 and size[j] + size[i//j] + 1 < size[i]:
size[i] = size[j] + size[i//j] + 1
expr[i] = ('*', expr[j], expr[i//j])
for j in range(1, i):
if j > i-j: break
if size[j] + size[i-j] + 1 < size[i]:
size[i] = size[j] + size[i-j] + 1
expr[i] = ('+', expr[j], expr[i-j])
return nice_exp(expr[N], 0)
print(solve(25378))
Output:
2 * (5 + 4 * 7 * (5 + 7 * 8 * 8))
I am new to FFTs so I am slightly confused on some concepts. So far the FFT examples I've seen for equation multiplication involve equations with consecutive exponents (i.e. A(x) = 1 + 3x + 5x^2 +... and B(x) = 4 + 6x + 9x^2 + ... and C(x) = A(x)*B(x)). However, it is possible to use FFT on two equations that do not have equal exponents? For example, is it possible to use FFT to multiply:
A(x) = 1 + 3x^2 + 9x^8
and
B(x) = 5x + 6 x^3 + 10x^8
in O(nlogn) time?
If not, are there any cases where the runtime will be O(nlogn)? For example, if the number of terms in the product is O(n) instead of O(n^2)?
Even if the runtime is more than O(nlogn), how can we use FFT to minimize the runtime?
yes it is possible to use DFFT on non equal exponent polynomials...
the missing exponents are just multiplied by 0 which is also a number... just rewrite your polynomials:
A(x) = 1 + 3x^2 + 9x^8
B(x) = 5x + 6x^3 + 10x^8
to something like this:
A(x) = 1x^0 + 0x^1 + 3x^2 + 0x^3 + 0x^4+ 0x^5+ 0x^6+ 0x^7 + 9x^8
B(x) = 0x^0 + 5x^1 + 0x^2 + 6x^3 + 0x^4+ 0x^5+ 0x^6+ 0x^7 + 10x^8
so your vectors for DFFT are:
A = (1,0,3,0,0,0,0,0, 9)
B = (0,5,0,6,0,0,0,0,10)
add zero's so the vector is the correct result size (max A exponent +1 + max B exponent +1) and also round up to closest power of 2 for DFFT usage so original sizes are 9,9 -> 9+9 -> 18 -> round up -> 32
A = (1,0,3,0,0,0,0,0, 9,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0)
B = (0,5,0,6,0,0,0,0,10,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0)
// | original | correct result | nearest power of 2 |
and do the DFFT stuff you want ... I assume you want to do something like this:
A' = DFFT(A)
B' = DFFT(B)
C(i)' = A'(i) * B'(i) // i=0..n-1
C= IDFFT(C')
which is O(n*log(n)). Do not forget that if you use DFFT (not DFT) n = 32 and not 18 !!! because n must be power of 2 for fast algorithm of DFT also if you want performance improvements than look at the DFFT weight matrices for DFFT(A),DFFT(B) they are the same so no need to compute them twice ...
I write simple code in Wolfram Mathematica:
x = 2
k = 0
n = 15
total = Sum[((-1^k)*(x^(4*k + 1))) / (((2*k)!) * (4*k + 1)), k, n]
I want print result (the sum all members) and print all(!!!) intermediate results function Sum. How this make?
Try
x=2;k=0;n=15;
Table[((-1^k)*(x^(4*k+1)))/(((2*k)!)*(4*k+1)),{k,n}]
That gives you a list of 15 elements.
Notice that I changed k,n to {k,n}.
Then Total[%] will add those to create a sum.
Your syntax is calculating a multiple indefinite sum, e.g.
Sum[Defer[g + h], g, h]
https://en.wikipedia.org/wiki/Indefinite_sum
If you add brackets around k, n you will obtain the sum Bill's answer shows.
total = Sum[((-1^k)*(x^(4*k + 1)))/(((2*k)!)*(4*k + 1)), {k, n}]
I have a simple algorithmic question:
If I have certain elements that integer values like:
1 1 1 1 1 1 1 1 1 1 1 1 10 12 2
and I have to make the sum 12, the minimum number of elements needed would 1, I would just use 12.
Thus, my question is how would you:
find the minimum number of elements to make some sum, and if you can't output -1.
Please suggest an algorithm I can look into so I can solve this efficiently. I've already tried brute force but it is much to slow for my needs.
The problem is np-complete and can be reduced to subset sum or knapsack problem. There is pseudo polynomial time algorithm that can solve it using dynamic programming. Following is a solution similar to knapsack analogy:-
1. Knapsack capacity = Sum
2. Items have same weight and value
3. Maximize profit
4. if max_profit == Sum then there is a solution
5. else Sum cannot be made from the items given.
6. Evaluate the minimum items needed using matrix alongside the DP.
7. Can also reconstruct all solutions and get the minimum one.
Time Complexity : - O(Sum*Items)
Java Implementation :-
public class SubSetSum {
static int[][] costs;
static int[][] minItems;
public static void calSets(int target,int[] arr) {
costs = new int[arr.length][target+1];
minItems = new int[arr.length][target+1];
for(int j=0;j<=target;j++) {
if(arr[0]<=j) {
costs[0][j] = arr[0];
minItems[0][j] = 1;
}
}
for(int i=1;i<arr.length;i++) {
for(int j=0;j<=target;j++) {
costs[i][j] = costs[i-1][j];
minItems[i][j] = minItems[i-1][j];
if(arr[i]<=j) {
costs[i][j] = Math.max(costs[i][j],costs[i-1][j-arr[i]]+arr[i]);
if(costs[i-1][j]==costs[i-1][j-arr[i]]+arr[i]) {
minItems[i][j] = Math.min(minItems[i][j],minItems[i-1][j-arr[i]]+1);
}
else if(costs[i-1][j]<costs[i-1][j-arr[i]]+arr[i]) {
minItems[i][j] = minItems[i-1][j-arr[i]]+1;
}
}
}
}
// System.out.println(costs[arr.length-1][target]);
if(costs[arr.length-1][target]==target) {
System.out.println("Minimum items need : "+minItems[arr.length-1][target]);
}
else System.out.println("No such Set found");
}
public static void main(String[] args) {
int[] arr = {1,1,1,1, 1 ,1 ,1, 1 ,1, 1 ,1 ,1, 10 ,12, 2};
calSets(12, arr);
}
}
here is a recursive approach that should be rather fast:
1) if your input vector is of length 1, either return 1 if the value is equal the target, or return -1 if it doesn't. similarly, if your target is less than any of your items in your input vector, return -1.
2) otherwise, loop on (unique) values in your input vector (in descending order, for performance):
2a) remove the value for your vector, and substract it from your target.
2b) recursively call this function on the new vector and the new target
note: you can pass down the algorithm a max.step parameter, so that if you have already found a solution with length K, you would stop the recursive calls at that depth, but not beyond. remember to decrease your max.step value in each recursive call.
3) collect all the values from the recursive calls, take the minimum (which is not -1) and add 1 to it and return, or, if all values in the loop are -1, return -1.
Disclaimer: This is an advertisement for nice but relatively simple mathematics which leads to very clever and fast counting formulas and algorithms. I'm aware that you can find a much simpler and efficient solution using usual programming. I just like the fact that using properly a Computer Algebra System you can do it in a one liner: Lets get 19 with this list:
sage: l = [1,1,1,2,5,2,1,3,12,1,3]; goal = 19
sage: prod((1+t*x^i) for i in l).expand().collect(x).coefficient(x,goal).low_degree(t)
3
What about 25:
sage: goal=25
sage: prod((1+t*x^i) for i in l).expand().collect(x).coefficient(x,goal).low_degree(t)
5
36 is not feasible:
sage: goal=36
sage: prod((1+t*x^i) for i in l).expand().collect(x).coefficient(x,goal).low_degree(t)
0
Here are some details: Just expand the product
(1+t*x^l[0]) (1+t*x^l[1]) ... (1+t*x^l[n])
Where your list is l. Then to find the minimum number of element required to get the sum S, collect the coefficients of x^S and return the minimum degree of a term in t.
Here is how it could be done in sage:
sage: var("x t")
(x, t)
sage: l = [1,1,1,2,5,2,1,3,12,1,3]
sage: s = prod((1+t*x^i) for i in l)
sage: s = expand(s).collect(x)
Now
sage: print(s)
t^11*x^32 + 5*t^10*x^31 + 2*(t^10 + 5*t^9)*x^30 + 2*(t^10 + 5*t^9 + 5*t^8)*x^29 + (11*t^9 + 20*t^8 + 5*t^7)*x^28 + (t^10 + 4*t^9 + 25*t^8 + 20*t^7 + t^6)*x^27 + 2*(3*t^9 + 10*t^8 + 15*t^7 + 5*t^6)*x^26 + (2*t^9 + 17*t^8 + 40*t^7 + 20*t^6 + 2*t^5)*x^25 + (2*t^9 + 12*t^8 + 30*t^7 + 40*t^6 + 7*t^5)*x^24 + (11*t^8 + 30*t^7 + 35*t^6 + 20*t^5 + t^4)*x^23 + 2*(2*t^8 + 13*t^7 + 20*t^6 + 13*t^5 + 2*t^4)*x^22 + (t^8 + 20*t^7 + 35*t^6 + 30*t^5 + 11*t^4)*x^21 + (t^10 + 7*t^7 + 40*t^6 + 30*t^5 + 12*t^4 + 2*t^3)*x^20 + (5*t^9 + 2*t^7 + 20*t^6 + 40*t^5 + 17*t^4 + 2*t^3)*x^19 + 2*(t^9 + 5*t^8 + 5*t^6 + 15*t^5 + 10*t^4 + 3*t^3)*x^18 + (2*t^9 + 10*t^8 + 10*t^7 + t^6 + 20*t^5 + 25*t^4 + 4*t^3 + t^2)*x^17 + (11*t^8 + 20*t^7 + 5*t^6 + 5*t^5 + 20*t^4 + 11*t^3)*x^16 + (t^9 + 4*t^8 + 25*t^7 + 20*t^6 + t^5 + 10*t^4 + 10*t^3 + 2*t^2)*x^15 + 2*(3*t^8 + 10*t^7 + 15*t^6 + 5*t^5 + 5*t^3 + t^2)*x^14 + (2*t^8 + 17*t^7 + 40*t^6 + 20*t^5 + 2*t^4 + 5*t^2)*x^13 + (2*t^8 + 12*t^7 + 30*t^6 + 40*t^5 + 7*t^4 + t)*x^12 + (11*t^7 + 30*t^6 + 35*t^5 + 20*t^4 + t^3)*x^11 + 2*(2*t^7 + 13*t^6 + 20*t^5 + 13*t^4 + 2*t^3)*x^10 + (t^7 + 20*t^6 + 35*t^5 + 30*t^4 + 11*t^3)*x^9 + (7*t^6 + 40*t^5 + 30*t^4 + 12*t^3 + 2*t^2)*x^8 + (2*t^6 + 20*t^5 + 40*t^4 + 17*t^3 + 2*t^2)*x^7 + 2*(5*t^5 + 15*t^4 + 10*t^3 + 3*t^2)*x^6 + (t^5 + 20*t^4 + 25*t^3 + 4*t^2 + t)*x^5 + (5*t^4 + 20*t^3 + 11*t^2)*x^4 + 2*(5*t^3 + 5*t^2 + t)*x^3 + 2*(5*t^2 + t)*x^2 + 5*t*x + 1
Ok this is a huge expression. The nice feature here is that If I take the coefficient say of x^17 I get:
sage: s.coefficient(x, 17)
2*t^9 + 10*t^8 + 10*t^7 + t^6 + 20*t^5 + 25*t^4 + 4*t^3 + t^2
which says the following: the term 10*t^7 tells me that there are 10 different way to obtains the sum 17 using 7 number. Another example, there are 25 way to get 17 using 4 number (25*t^4).
Also since this expression ends with t^2 I learn that I only need two number to get 17. Unfortunately this doesn't tells which numbers.
If you want to understand the trick, look at Wikipedia article on generating functions and This Page.
Note 1: this is not the most efficient since I compute much more than what you need. The huge expression actually described and somehow computed all possible choices (that is 2^the length of the list). But it's a one liner:
sage: prod((1+t*x^i) for i in l).expand().collect(x).coefficient(x,17).low_degree(t)
2
And still relatively efficient:
sage: %timeit prod((1+t*x^i) for i in l).expand().collect(x).coefficient(x,17).low_degree(t)
10 loops, best of 3: 42.6 ms per loop
Note 2: After thinking carefully about it I also realized the following: Generating series is just a compact encoding of what you would have written if you tried to implement a dynamic programming solution.
I don't think this solution is optimal, but it's very easy to understand and use, you sort the elements in decreasing order, then you take each element and try to fit it in your number. If you have the sequence [5,6,2,7] and you need to make the 15 number, you'll reorder the sequence [7,6,5,2] and take 7, then you need to extract 8 so you'll take 6, then you'll need 2 more, check 5 but it's too big and you'll skip it and check the last number, 2, which it's perfect and finishes your number. So you'd print out 3. This is the worst case of the algorithm which is O(n). But in your example with 12, it'll be O(1), because you'll pick 12 from the first checkup of the ordered sequence. (running time applies only for the program of choosing items, not sorting)
resolve_sum(ordered_items[], number) {
count = 0;
aux = number;
i = 0;
while (aux - ordered_items[i] <= 0) {
count = count + 1;
aux = aux - ordered_items[i];
i = i + 1;
}
if (aux == 0) return count;
else return -1;
}
I haven't included an algorithm for sorting, you can choose one that you know best or try to learn a new efiecient one. Link with sorting algorithms and their running time. This is just a sample code you can use in C/C++ or Java or what you need. I hope it isn't way too much brute force.
In an interview today, I was given this sequence, which is sort of a modified Fibonacci:
1, 1, 2, 4, 6, 13, 19, 42, 61, 135, ...,
I was asked to write a function to return the number at place n.
So, if n = 4, the function should return 4, n = 6 return 13, etc.
As I'm sure you already noticed, the difference is that even items equal the previous 4 items, while odd items equal the previous 2.
It isn't a problem if you use recursion. That's what I did, but it's not the approach I would have liked.
The Fibonacci calculation goes something like this (in PHP):
$n = 17;
$phi = (1 + sqrt(5)) / 2;
$u = (pow($phi, $n) - pow(1 - $phi, $n)) / sqrt(5);
$u being, in this case, 1597.
However, I have no idea how to solve it with a modified version of a Fibonacci sequence like this one.
If I understand you correctly, you want to compute efficiently [i.e. in O( log(n) )] sequence defined as:
a[2n + 5] = a[2n + 4] + a[2n + 3] + a[2n + 2] + a[2n + 1]
a[2n + 2] = a[2n + 1] + a[2n]
Let's define two new sequences. First one will correspond to the values of a on even positions, the second one to the values on even positions:
b[n] = a[2n]
c[n] = a[2n + 1]
Now we have:
c[n] = b[n] + c[n - 1] + b[n - 1] + c[n - 2]
b[n] = c[n - 1] + b[n - 1]
Subtracting the second equation from the first we get (after some transformation):
b[n] = ( c[n] - c[n-1] ) /2
Next substitute this formula into first equation to get formula for c:
c[n] = 2 c[n-1] + c[n-2]
Notice that this equation involves only elements from c. Therefore now it is possible to compute elements of c, using techniques described here. By transforming equations a little bit further you will be able to compute b efficiently as well.
Like every sequence defined by a linear recurrence with constant coefficients, the Fibonacci numbers have a closed-form solution.
http://en.wikipedia.org/wiki/Fibonacci_number#Closed-form_expression
However, I do not know how to create a closed form expression for this particular sequence.
What I can add is that you can solve Fibonacci or any similar sequence without recursion, e.g.:
http://forum.codecall.net/topic/41540-fibonacci-with-no-recursion-for-fun/
So you can solve the problem using a loop rather than the stack.