Find whether any possible combination exists for the following: - algorithm

I am given N numbers, n1, n2, n3, n4, …, nN (all being positive). Finally I am given a number K as input.
I am asked if it is possible to find some possible combination over n1, n2, …, nN such that the sum equals K, i.e. find coefficients a, b, c, …, n such that:
a·‍n1 + b·‍n2 + … + n·‍nN = K
where a, b, c, …, n may assume any integral value from 0 to K.
We just need to find out whether such a combination exist.
What I have been thinking is placing limits over the extreme values of a, b, …, n. For example, a can be bounded as: 0 ≤ a ≤ floor(K/‍a). Similarly, defining ranges for b, c, …, n. However, this algorithm eventually turns out to be O(nn-1) in the worst case.
Is this problem similar to Bin Packing problem? Is it NP complete?
Please help me with a better algorithm (I am not even sure if my algorithm is correct!!).

This is just another variant of the Knapsack problem (see the unbounded knapsack section) and is just as NP-complete and hard as the other versions.
Of course, if K is small you can use the dynamic programming solution and if N is small exaustive search works well also.

This solution supposes that the numbers n1, n2, ... nN are integers (or that they have a "smallest common divisor")
I've got a O(K*N) algorithm (thanks to missingno for the correction). The idea is a bit of dynamic programming, a bit of the Sieve of Eratosthenes.
Begin by creating a list L of K+1 booleans. L[i] is true if you can "build" the number i (more on that later). All values of L are initialised as false, except L[0]==true
Begin with you first number n1. For every value of i between 1 and K, check if L[i-n1]==true. Of course, if i-n1<0, then do as if L[i-n1]==false. If L[i-n1]==true, then change L[i] to true. Now, you have L[n1]==true, L[2*n1]==true, L[3*n1]==true ...
What does L mean now? L represent the numbers in [0..K] that can be built with only n1. If L[K]==true, congratulations, there is a solution built with only n1!
Take the number n2, and do the same. For every value of i between 1 and K such that L[i]==false, check if L[i-n2]==true. If it's the case change L[i] to true.
What does L mean now? L represent the numbers in [0..K] that can be built with n1 and n2. If L[K]==true, congratulations, there is a solution built with only n1 and n2!
If after filling L with all you N values L[K]==false, there is no solution to your problem.
The problem with dynamic programming is that it's always a problem to retrieve the solution once you've proven that there exists one... You need another list S such that S[i] describes what are the coefficients needed to "build" i. (exists only if L[i]==true of course)

This is an integer program, so if you have access to a solver, I'd recommend you profile its performance and see if it works for you.

Related

How do we find the logsumexp of all subsets (or some approximation to this)?

I have a set of numbers n_1, n_2, ... n_k. I need to find the sum (or mean, its the same) of the logsumexp of all possible subsets of this set of numbers. Is there a way to approximate this or compute it exactly?
Note, the logsumexp of a, b, c is log(e_a + e_b + e_c) (exp, followed by sum, followed by log)
I don’t know if this will be accurate enough, but log sum exp is sort of a smooth analog of max, so one possibility would be to sort so that n1 ≥ n2 ≥ … ≥ nk and return ∑i (2k−i / (2k − 1)) ni, which under-approximates the true mean by an error term between 0 and log k.
You could also use a sample mean of the log sum exp of {ni} ∪ (a random subset of {ni+1, ni+2, …, nk}) instead of ni in the sum. By using enough samples, you can make the approximation as good as you like (though obviously at some point it’s cheaper to evaluate with brute force).
(I’m assuming that the empty set is omitted.)
On a different tack, here’s a deterministic scheme whose additive error is at most ε. As in my other answer, we sort n1 ≥ … ≥ nk, define an approximation f(i) of the mean log sum exp over nonempty subsets where the minimum index is i, and evaluate ∑i (2k−i / (2k − 1)) f(i). If each f(i) is within ε, then so is the result.
Fix i and for 1 ≤ j ≤ k−i define dj = ni+j − ni. Note that dj ≤ 0. We define f(i) = ni + g(i) where g(i) will approximate the mean log one plus sum exp of subsets of {dj | j}.
I don’t want to write the next part formally since I believe that it will be harder to understand, so the idea is that with log sum exp being commutative and associative, we’re going to speed up the brute force algorithm that initializes the list of results as [0] and then, for each j, doubles the size of the list the list by appending the log sum exp with dj of each of its current elements. I claim that, if we round each intermediate result down to the nearest multiple of δ = ε/k, then the result will under-approximate at most ε. By switching from the list to its histogram, we can do each step in time proportional to the number of distinct entries. Finally, we set g(i) to the histogram average.
To analyze the running time, in the worst case, we have dj = 0 for all j, making the largest possible result log k. This means that the list can have at most (log k)/δ = ε−1 k log k + 1 entries, making the total running time O(ε−1 k3 log k). (This can undoubtedly be improved slightly with a faster convolution algorithm and/or by rounding the dj and taking advantage.)

How To Find K-th Smallest Element in Multiset-sum?

Need some help designing an algorithm to solve this problem.
Let a and b be integers with a ≤ b, and let [a,b] denote the set {a, a + 1, a + 2, ..., b}. Suppose we are given n such sets, [a1,b1],...[an,bn], their multiset-sum is
S = {a1, a1 + 1,..., b1, a2,a2 + 1,...,b2,...,an,an + 1, ..., bn}
For example, the multiset-sum of [5,25], [3,10], and [8,12], is
{3,4,5,5,6,6,7,7,8,8,8,9,9,9,10,10,10,...,25}
Given the sets[a1, b1],...,[an, bn] such that 0 ≤ ai, bi ≤ N and an integer k > 0, design an efficient algorithm that outputs the k smallest element in S, the multiset-sum of the sets. Determine the running time of the algorithm in terms of n and N.
I've already designed two helper algorithms called FindElementsBefore(x, [a1,b1]...[an,bn]) and FindElementsAfter(x, [a1,b1]...[an,bn]). These both accept an element x and each of the sets and return the number of elements in S less than x and greater than x respectively.
I've been told by my professor that using these two helper methods, I should be able to solve the above problem, but I am absolutely stumped. How do I solve this?
Use a binary search.
You already know the largest and smallest values in your multiset-sum. Thus, you have an upper and lower bound for the k-th smallest element. Now you can simply recurse on the upper and lower bounds, depending on the value of FindElementsBefore(mid, ...) <= k.

How can I solve this coding problem efficiently which involves the 'modulo' operation?

We are given an integer 'N' . We can choose any 2 numbers (a and b) in the range (1 to z) . The value of L is given by,
L = Max(( (N%a) %b) %N)
We have to calculate the number of pairs (a,b) which give(s) the value 'L' .
I know the brute-force , one, O(n2) solution.
Is there any more efficient way to solve this problem?!
The only way I can decipher Max(( (N%a) %b) %N) is that the max is taken over all a, b pairs. If I am wrong, please disregard the rest.
In case z > N/2:
First, observe that if both a and b are greater than N, then (N%a) % b yields N, so (N%a) %b) %N yields 1, which is unsatisfactory small. Therefore at least one of them shall be less than N.
Second, observe (better yet, prove) that the maximal value of N % a is achieved when a is N/2 + 1 for even N, and (N + 1)/2 for odd (important note: it is a half of the next multiple of 2 after N). Call it a maximizer.
Finally, observe that any b greater than that modulo leaves it untouched. Prove that this is indeed the desired maximum.
Now you have enough facts to come up with effectively a one-line program (don't forget the a > N, b = maximizer case).
The same logic works for z < N/2. Finding the maximizer is a bit trickier, but still possible in O(1) (see the important note above).

a variant of shortest path problem

Can someone help me on how I can approach this problem- all I can think of is recursively calling a function(but that doesn't really seem to work).
Let's say I start with zero and add either of two numbers at each step. So, at first I may add n1 or n2 to zero; so the new no. becomes n1 or n2, then add either of n1 or n2.
Doing this, how can I find whether or not a certain number, say N, is ever reached? And if the number is reached, how can I find the shortest path for it to reach N (solution could be something like n1,n1,n2)?
This looks more like a linear Diophantine equation with non-negativity constraints than like a shortest path problem.
To summarize from the article: if d is the greatest common divisor of n1 and n2, then there is a solution if and only if N is a multiple of d. If it is, then there an infinity of solutions (including a smallest one), which can be found by the extended Euclidean algorithm. You just have to do a little (hah!) extra work to determine if there is a smallest solution in non-negative integers. (E.g., there is no non-negative solution for 2n1 + 3n2 = 1.)
arrange the numbers so that n1>n2
repeatedly substruct n2 from N (result in M) till M % n1 = 0 and M>=0. That will give you the optimal solution, N = (M / n1) * n1 + rest * n2.
If your algorithm fails to find an M after n1 steps there is no solution.

Find sum in array equal to zero

Given an array of integers, find a set of at least one integer which sums to 0.
For example, given [-1, 8, 6, 7, 2, 1, -2, -5], the algorithm may output [-1, 6, 2, -2, -5] because this is a subset of the input array, which sums to 0.
The solution must run in polynomial time.
You'll have a hard time doing this in polynomial time, as the problem is known as the Subset sum problem, and is known to be NP-complete.
If you do find a polynomial solution, though, you'll have solved the "P = NP?" problem, which will make you quite rich.
The closest you get to a known polynomial solution is an approximation, such as the one listed on Wikipedia, which will try to get you an answer with a sum close to, but not necessarily equal to, 0.
This is a Subset sum problem, It's NP-Compelete but there is pseudo polynomial time algorithm for it. see wiki.
The problem can be solved in polynomial if the sum of items in set is polynomially related to number of items, from wiki:
The problem can be solved as follows
using dynamic programming. Suppose the
sequence is
x1, ..., xn
and we wish to determine if there is a
nonempty subset which sums to 0. Let N
be the sum of the negative values and
P the sum of the positive values.
Define the boolean-valued function
Q(i,s) to be the value (true or false)
of
"there is a nonempty subset of x1, ..., xi which sums to s".
Thus, the solution to the problem is
the value of Q(n,0).
Clearly, Q(i,s) = false if s < N or s
P so these values do not need to be stored or computed. Create an array to
hold the values Q(i,s) for 1 ≤ i ≤ n
and N ≤ s ≤ P.
The array can now be filled in using a
simple recursion. Initially, for N ≤ s
≤ P, set
Q(1,s) := (x1 = s).
Then, for i = 2, …, n, set
Q(i,s) := Q(i − 1,s) or (xi = s) or Q(i − 1,s − xi) for N ≤ s ≤ P.
For each assignment, the values of Q
on the right side are already known,
either because they were stored in the
table for the previous value of i or
because Q(i − 1,s − xi) = false if s −
xi < N or s − xi > P. Therefore, the
total number of arithmetic operations
is O(n(P − N)). For example, if all
the values are O(nk) for some k, then
the time required is O(nk+2).
This algorithm is easily modified to
return the subset with sum 0 if there
is one.
This solution does not count as
polynomial time in complexity theory
because P − N is not polynomial in the
size of the problem, which is the
number of bits used to represent it.
This algorithm is polynomial in the
values of N and P, which are
exponential in their numbers of bits.
A more general problem asks for a
subset summing to a specified value
(not necessarily 0). It can be solved
by a simple modification of the
algorithm above. For the case that
each xi is positive and bounded by the
same constant, Pisinger found a linear
time algorithm.[2]
It is well known Subset sum problem which NP-complete problem.
If you are interested in algorithms then most probably you are math enthusiast that I advise you look at
Subset Sum problem in mathworld
and here you can find the algorithm for it
Polynomial time approximation algorithm
initialize a list S to contain one element 0.
for each i from 1 to N do
let T be a list consisting of xi+y,
for all y in S
let U be the union of T and S
sort U
make S empty
let y be the smallest element of U
add y to S
for each element z of U in
increasing order do //trim the list by
eliminating numbers
close one to another
if y<(1-c/N)z, set y=z and add z to S
if S contains a number between (1-c)s and s, output yes, otherwise no

Resources