a variant of shortest path problem - algorithm

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.

Related

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).

Algorithm to find best combination or path through nodes

As I am not very proficient in various optimization/tree algorithms, I am seeking help.
Problem Description:
Assume, a large sequence of sorted nodes is given with each node representing an integer value L. L is always getting bigger with each node and no nodes have the same L.
The goal now is to find the best combination of nodes, where the difference between the L-values of subsequent nodes is closest to a given integer value M(L) that changes over L.
Example:
So, in the beginning I would have L = 50 and M = 100. The next nodes have L = 70,140,159,240,310.
First, the value of 159 seems to be closest to L+M = 150, so it is chosen as the right value.
However, in the next step, M=100 is still given and we notice that L+M = 259, which is far away from 240.
If we now go back and choose the node with L=140 instead, which then is followed by 240, the overall match between the M values and the L-differences is stronger. The algorithm should be able to find back to the optimal path, even if a mistake was made along the way.
Some additional information:
1) the start node is not necessarily part of the best combination/path, but if required, one could first develop an algorithm, which chooses the best starter candidate.
2) the optimal combination of nodes is following the sorted sequence and not "jumping back" -> so 1,3,5,7 is possible but not 1,3,5,2,7.
3) in the end, the differences between the L values of chosen nodes should in the mean squared sense be closest to the M values
Every help is much appreciated!
If I understand your question correctly, you could use Dijktras algorithm:
https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm
http://www.mathworks.com/matlabcentral/fileexchange/20025-dijkstra-s-minimum-cost-path-algorithm
For that you have to know your neighbours of every node and create an Adjacency Matrix. With the implementation of Dijktras algorithm which I posted above you can specify edge weights. You could specify your edge weight in a manner that it is L of the node accessed + M. So for every node combination you have your L of new node + M. In that way the algorithm should find the optimum path between your nodes.
To get all edge combinations you can use Matlabs graph functions:
http://se.mathworks.com/help/matlab/ref/graph.html
If I understand your problem correctly you need an undirected graph.
You can access all edges with the command
G.Edges after you have created the graph.
I know its not the perfect answer but I hope it helps!
P.S. Just watch out, Djikstras algorithm can only handle positive edge weights.
Suppose we are given a number M and a list of n numbers, L[1], ..., L[n], and we want to find a subsequence of at least q of the latter numbers that minimises the sum of squared errors (SSE) with respect to M, where the SSE of a list of k positions x[1], ..., x[k] with respect to M is given by
SSE(M, x[1], ..., x[k]) = sum((L[x[i]]-L[x[i-1]]-M)^2) over all 2 <= i <= k,
with the SSE of a list of 0 or 1 positions defined to be 0.
(I'm introducing the parameter q and associated constraint on the subsequence length here because without it, there always exists a subsequence of length exactly 2 that achieves the minimum possible SSE -- and I'm guessing that such a short sequence isn't helpful to you.)
This problem can be solved in O(qn^2) time and O(qn) space using dynamic programming.
Define f(i, j) to be the minimum sum of squared errors achievable under the following constraints:
The number at position i is selected, and is the rightmost selected position. (Here, i = 0 implies that no positions are selected.)
We require that at least j (instead of q) of these first i numbers are selected.
Also define g(i, j) to be the minimum of f(k, j) over all 0 <= k <= i. Thus g(n, q) will be the minimum sum of squared errors achievable on the entire original problem. For efficient (O(1)) calculation of g(i, j), note that
g(i>0, j>0) = min(g(i-1, j), f(i, j))
g(0, 0) = 0
g(0, j>0) = infinity
To calculate f(i, j), note that if i > 0 then any solution must be formed by appending the ith position to some solution Y that selects at least j-1 positions and whose rightmost selected position is to the left of i -- i.e. whose rightmost selected position is k, for some k < i. The total SSE of this solution to the (i, j) subproblem will be whatever the SSE of Y was, plus a fixed term of (L[x[i]]-L[x[k]]-M)^2 -- so to minimise this total SSE, it suffices to minimise the SSE of Y. But we can compute that minimum: it is g(k, j-1).
Since this holds for any 0 <= k < i, it suffices to try all such values of k, and take the one that gives the lowest total SSE:
f(i>=j, j>=2) = min of (g(k, j-1) + (L[x[i]]-L[x[k]]-M)^2) over all 0 <= k < i
f(i>=j, j<2) = 0 # If we only need 0 or 1 position, SSE is 0
f(i, j>i) = infinity # Can't choose > i positions if the rightmost chosen position is i
With the above recurrences and base cases, we can compute g(n, q), the minimum possible sum of squared errors for the entire problem. By memoising values of f(i, j) and g(i, j), the time to compute all needed values of f(i, j) is O(qn^2), since there are at most (n+1)*(q+1) possible distinct combinations of input parameters (i, j), and computing a particular value of f(i, j) requires at most (n+1) iterations of the loop that chooses values of k, each iteration of which takes O(1) time outside of recursive subcalls. Storing solution values of f(i, j) requires at most (n+1)*(q+1), or O(qn), space, and likewise for g(i, j). As established above, g(i, j) can be computed in O(1) time when all needed values of f(x, y) have been computed, so g(n, q) can be computed in the same time complexity.
To actually reconstruct a solution corresponding to this minimum SSE, you can trace back through the computed values of f(i, j) in reverse order, each time looking for a value of k that achieves a minimum value in the recurrence (there may in general be many such values of k), setting i to this value of k, and continuing on until i=0. This is a standard dynamic programming technique.
I now answer my own post with my current implementation, in order to structure my post and load images. Unfortunately, the code does not do what it should do. Imagine L,M and q given like in the images below. With the calcf and calcg functions I calculated the F and G matrices where F(i+1,j+1) is the calculated and stored f(i,j) and G(i+1,j+1) from g(i,j). The SSE of the optimal combination should be G(N+1,q+1), but the result is wrong. If anyone found the mistake, that would be much appreciated.
G and F Matrix of given problem in the workspace. G and F are created by calculating g(N,q) via calcg(L,N,q,M).
calcf and calcg functions

How does my professor come up with the recursive case in this algorithm analysis?

My professor gave us the following explanation for the recursive algorithm for finding the permutations of a set of numbers:
When he has (T(m+1), n-1)) where does that come from? Why is it m+1 and n-1? I'm really confused as to where that comes from.
As he said, m represents the current size of P and n represents the size of S, in each recursive call you remove a number from S and add it to P, thus the size of your current permutation is increased by 1 (m+1) and the number of available numbers to add to the permutation is decreased by 1 (n-1)
Note that it is multiplied by n as you perform this action for each number in S.
Note that part that says:
Let m be the length of P and n be the size of S
And then in printperm(P, S), you're calling printperm((P,i), S-{i}).
So, when recursing, we will add one element to P, and remove on element from S.
Thus m will increase by one and n will decrease by one, thus we get T(m+1, n-1)
I hope that helps.

Find whether any possible combination exists for the following:

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.

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