Design an algorithm that, given a set S of n integers and another
integer x, determines whether or not there exist k (n>k>2) elements in
S whose sum is exactly x. Please give the running time of your
algorithm
I have been preparing for an interview, and i have come across this algorithm. I have solved problems where k has been specified in the problem. like 2 or 3. But i cannot find an answer where i might solve for any k that might exist. I have tried solving it using dynamic programming but didn't get results. Can anyone help me on this.
You can make an int array cnt of size x, then go through the set, and mark reachable points. All elements of cnt are set to -1 initially except element zero, which is set to zero.
Repeat the same process for each element si of S: for each element of cnt at position i that is non-negative, check element cnt[i+si] (if it's within the bounds of the array). If it is, set it to cnt[si+i] = max(cnt[i]+1, cnt[si+i]).
Once you go through all elements of S, check cnt[x]. If it is set to two or more, then there exists a combination of two or more elements in S adding up to x.
This algorithm is pseudo-polynomial, with running time O(x*|S|)
Related
I have a set of (value,cost) tuples which is (2000000,200) , (500000,75) , (100000,20)
Suppose X is any positive number.
Is there an algorithm to find the combination of tuple that have the least cost for the sum of value that can store X.
The sum of tuple values can be equal or greater than the given X
ex.
giving x = 800000 the answer should be (500000,75) , (100000,20) , (100000,20) , (100000,20)
giving x = 900000 the answer should be (500000,75) , (500000,75)
giving x = 1500000 the answer should be (2000000,200)
I can hardcode this but the set and the tuple are subject to change so if this can be substitute with well-known algorithm it would be great.
This can be solved with dinamic programming, as you have no limit on number of tuples and can afford higher sums that provided number.
First, you can optimize tuples. If one big tuple can be replaced by number of smaller ones with equal or lower cost and equal or higher value, you can remove bigger tuple at all.
Also, it's fruitful for future use to order tuples in optimized set by value/cost in descending order. Tuple is better if value/cost is bigger.
Time complexity O(N*T), where N is number divided by common factor (F) of optimized tuple values, and T is number of tuples in optimized tuple set.
Memory complexity O(N).
Set up array a of size N that will contain:
in a[i].cost best cost for solution for i*F, 0 for special case "no solution yet"
in a[i].tuple the tuple that led to best solution
Recursion scheme:
function gets n as a single parameter - it's provided number/F for start, leftover of needed value/F sums for recusion calls
if array a for n is filled, return a[n].cost
otherwise set current_cost to MAXINT
for each tuple from best to worst try to add it to solution:
if value/F >= n, we've got some solution, compare tuple cost to current_cost and if it's better, update a[n].cost and a[n].tuple
if value/F < n, call recursively for n-value/F and compare cost with current solution, update current solution and a[n].cost, a[n].tuple if needed
after all, return a[n].cost or throw exception is no solution exists
Tuple list can be retrieved from a but traverse through .tuple on each step.
It's possible to reduce overall array size down to max(tuple.value/F), but you'll have to save more or less complete solution instead of one best .tuple for each element, and you'll have to make "sliding window" carefully.
It's possible to turn recursion into cycle from 0 to n, as with many other dynamic programming algorithms.
I have a simple algorithmic problem.
I have a set of positive integers S and a positive maximum integer i.
Let's say the sum of S (or a subset of S) is the sum of its elements.
I need to find a subset s of S whose sum does not exceed i and is "maximally summing" - meaning no other subset of S has a greater sum than s without exceeding i.
The trivial solution I came up with is to go over each set of the power set of S and sum the integers, keeping track of the set with the properties I seek, but this algorithm is obviously exponential.
There must be a well-known name for this problem, as I don't think I am the first to come across this need. Could someone help me out?
Solve subset sum problem for your set using dynamic programming.
Then scan filled table from i-th entry to smaller values until you find non-zero entry (i.e. such sum exists). This is the largest sum of subsets that not exceeding given value.
I am having trouble starting off this particular homework problem. Here is the problem:
Suppose that you are given an algorithm as a black box – you cannot see how it is designed – it has the following properties: if you input any sequence of real numbers and an integer k, the algorithm will answer YES or NO indicating whether there is a subset of numbers whose sum is exactly k. Show how to use this black box to find the subset of a given sequence X1, …., Xn whose sum is k. You can use the black box O(n) times.
I figure that the sequence should be sorted first, and anything < k should only be considered. Any help to get started would be greatly appreciated. Thanks.
Sorting is the wrong approach. Think about it this way: how can you use the oracle to determine whether a particular item in the set is part of the sum? Once you know whether that item is part of the sum, how can you use the oracle to figure out whether some other item is part of the sum?
The blackbox is something like this, in C# (ignore that I used int instead of real for the sequence, it's inconsequential to the problem).
bool blackbox(List<int> subSequence, int k)
{
// unknown
}
You are tasked with passing in a subset of the sequence and finding what part of the sequence equals k.
Start with the whole sequence, just to see if k is in it at all.
Then, if it contains k, try a subsequence to see if that subsequence contains k.
Repeat until you have the subsequence that contains k.
I need to find the optimal subsets after solving the partition problem using the Dynamic Programming pseudo polynomial time algorithm.
More specifically, I'm not able to make sense of this answer: https://stackoverflow.com/a/890243/1317826
I'm not able to understand how to construct the optimal subsets from the boolean table.
The Wikipedia article on the partition problem has it too: http://en.wikipedia.org/wiki/Partition_problem
Can someone please shed some light on it?
Everything you need is in the answer you posted.
First of all, when you create table using pseudo-polynomial time algorithm you don't store boolean values (True if it's reachable, False otherwise), but value of the element that you added to the subset. Than you should be able to construct subset by simply substracting it from the sum you obtained.
So the algorithm is:
For every number x_i in your set:
Set p(1, x_i) = x_i
For every other field p(row, sum) set it to x_i if p(row-1, sum-x_i) != 0
So now p(row, sum) = x means that we can get sum by taking some row elements of our set and last one of them is x.
Once p(some_row, N/2) != 0 you can construct the subset by taking it's value x, and moving to p(some_row - 1, N/2 - x) and so forth.
Hope this makes it clear.
BTW. Is there a way to write latex in the answers?
I have a fixed array of constant integer values about 300 items long (Set A). The goal of the algorithm is to pick two numbers (X and Y) from this array that fit several criteria based on input R.
Formal requirement:
Pick values X and Y from set A such that the expression X*Y/(X+Y) is as close as possible to R.
That's all there is to it. I need a simple algorithm that will do that.
Additional info:
The Set A can be ordered or stored in any way, it will be hard coded eventually. Also, with a little bit of math, it can be shown that the best Y for a given X is the closest value in Set A to the expression X*R/(X-R). Also, X and Y will always be greater than R
From this, I get a simple iterative algorithm that works ok:
int minX = 100000000;
int minY = 100000000;
foreach X in A
if(X<=R)
continue;
else
Y=X*R/(X-R)
Y=FindNearestIn(A, Y);//do search to find closest useable Y value in A
if( X*Y/(X+Y) < minX*minY/(minX+minY) )
then
minX = X;
minY = Y;
end
end
end
I'm looking for a slightly more elegant approach than this brute force method. Suggestions?
For a possibly 'more elegant' solution see Solution 2.
Solution 1)
Why don't you create all the possible 300*300/2 or (300*299/2) possible exact values of R, sort them into an array B say, and then given an R, find the closest value to R in B using binary search and then pick the corresponding X and Y.
I presume that having array B (with the X&Y info) won't be a big memory hog and can easily be hardcoded (using code to write code! :-)).
This will be reasonably fast: worst case ~ 17 comparisons.
Solution 2)
You can possibly also do the following (didn't try proving it, but seems correct):
Maintain an array of the 1/X values, sorted.
Now given an R, you try and find the closest sum to 1/R with two numbers in the array of 1/Xs.
For this you maintain two pointers to the 1/X array, one at the smallest and one at the largest, and keep incrementing one and decrementing the other to find the one closest to 1/R. (This is a classic interview question: Find if a sorted array has two numbers which sum to X)
This will be O(n) comparisons and additions in the worst case. This is also prone to precision issues. You could avoid some of the precision issues by maintaining a reverse sorted array of X's, though.
Two ideas come to my mind:
1) Since the set A is constant, some pre-processing can be helpful. Assuming the value span of A is not too large, you can create an array of size N = max(A). For each index i you can store the closest value in A to i. This way you can improve your algorithm by finding the closest value in constant time, instead of using a binary search.
2) I see that you omit X<=R, and this is correct. If you define that X<=Y, you can restrict the search range even further, since X>2R will yield no solutions either. So the range to be scanned is R<X<=2R, and this guarantees no symetric solutions, and that X<=Y.
When the size of the input is (roughly) constant, an O(n*log(n)) solution might run faster than a particular O(n) solution.
I would start with the solution that you understand the best, and optimize from there if needed.