The "try every possible sequence until you get it right" algorithm - algorithm

This is probably completely rudimentary, but I'm still not sure how to do it.
Suppose that I have a list action of functions/operators/what-have-you and an object x. For some stored value y, I want to check if it is possible to obtain y by applying the members of action, and return the shortest sequence of actions which takes x to y.
The easiest way to do this is to apply every possible sequence of actions to x in order, returning the first sequence to yield y (this will always be the shortest possible sequence).
I have a vague idea of how this might be done but I'm not clear on the specifcs - something like:
//Set the maximum number of steps (to prevent overflow)
n = whatever
//Algorithm
<<start>>
While i<n
u = x
sequence = []
<<begin loop-like thing
u = apply actions to u
sequence = sequence.append(action.index(last action))
end loop-like thing>>
i = i + 1
if u==y
print sequence
else
<<return to start>>
(I'm using <<stuff>> as a placeholder for when I don't know what stuff is).
For a concrete example of application, consider action to be the list of legal twists of a Rubik's cube, and x to be the starting (scrambled) state, and y to be the solved state. This solves the Rubik's cube using the fewest possible steps and prints the solution.
You could also do this to solve mazes, but that would be silly, because there are much faster ways to solve mazes.

Related

Could anyone explain the Hidden Sequence problem in CodeChef?

I'm trying to solve the Hidden Sequence problem on Code Chef, but I don't fully understand the explanation. I especially don't understand what's the use of Y in the triplets.
We know that there is a hidden sequence A1,A2,…,AN which contains only integers between 1 and K inclusive. We have acquired M triplets (X1,Y1,Z1),(X2,Y2,Z2),…,(XM,YM,ZM). A very reliable source has given us intel that for each valid i, the Yi-th occurrence of the integer Xi in the sequence A is AZi, i.e. AZi=Xi and there are Yi−1 indices j<Zi such that Aj=Xi
Find any sequence A consistent with this information or determine that no such sequence exists.
Could anyone explain it?
The hidden array may have duplicate values, like [1,2,3,1,2,3,1,1].
One of the triplets could be X=3, Y=2, Z=6.
This tells us that the second 3 is at position 6. So:
X = the value
Y = the occurrence of that value X (whether it is the first, second, third, ... occurrence)
Z = the position of the Y-th occurrence of that value X
This may be the only info you will get about the value 3. So you might not get a triplet saying X=3, Y=1, Z=3, which would tell you where the first 3 is positioned. Instead your algorithm must derive that from the other triplets.
The algorithm should somehow stay aware that in the first 5 positions there must be a 3. From other triplets it will know similar things. At a certain point this bulk of information will not allow that 3 to occur at just any of those 5 positions, as some positions will be needed for other values. This will narrow down the possibilities, until maybe only a few are left over, or maybe none.
Hope this explains what Y is about.

Dyanamic Programming - Coin Change Problem

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.

Querying large amount of multidimensional points in R^N

I'm looking at listing/counting the number of integer points in R^N (in the sense of Euclidean space), within certain geometric shapes, such as circles and ellipses, subject to various conditions, for small N. By this I mean that N < 5, and the conditions are polynomial inequalities.
As a concrete example, take R^2. One of the queries I might like to run is "How many integer points are there in an ellipse (parameterised by x = 4 cos(theta), y = 3 sin(theta) ), such that y * x^2 - x * y = 4?"
I could implement this in Haskell like this:
ghci> let latticePoints = [(x,y) | x <- [-4..4], y <-[-3..3], 9*x^2 + 16*y^2 <= 144, y*x^2 - x*y == 4]
and then I would have:
ghci> latticePoints
[(-1,2),(2,2)]
Which indeed answers my question.
Of course, this is a very naive implementation, but it demonstrates what I'm trying to achieve. (I'm also only using Haskell here as I feel it most directly expresses the underlying mathematical ideas.)
Now, if I had something like "In R^5, how many integer points are there in a 4-sphere of radius 1,000,000, satisfying x^3 - y + z = 20?", I might try something like this:
ghci> :{
Prelude| let latticePoints2 = [(x,y,z,w,v) | x <-[-1000..1000], y <- [-1000..1000],
Prelude| z <- [-1000..1000], w <- [-1000..1000], v <-[1000..1000],
Prelude| x^2 + y^2 + z^2 + w^2 + v^2 <= 1000000, x^3 - y + z == 20]
Prelude| :}
so if I now type:
ghci> latticePoints2
Not much will happen...
I imagine the issue is because it's effectively looping through 2000^5 (32 quadrillion!) points, and it's clearly unreasonably of me to expect my computer to deal with that. I can't imagine doing a similar implementation in Python or C would help matters much either.
So if I want to tackle a large number of points in such a way, what would be my best bet in terms of general algorithms or data structures? I saw in another thread (Count number of points inside a circle fast), someone mention quadtrees as well as K-D trees, but I wouldn't know how to implement those, nor how to appropriately query one once it was implemented.
I'm aware some of these numbers are quite large, but the biggest circles, ellipses, etc I'd be dealing with are of radius 10^12 (one trillion), and I certainly wouldn't need to deal with R^N with N > 5. If the above is NOT possible, I'd be interested to know what sort of numbers WOULD be feasible?
There is no general way to solve this problem. The problem of finding integer solutions to algebraic equations (equations of this sort are called Diophantine equations) is known to be undecidable. Apparently, you can write equations of this sort such that solving the equations ends up being equivalent to deciding whether a given Turing machine will halt on a given input.
In the examples you've listed, you've always constrained the points to be on some well-behaved shape, like an ellipse or a sphere. While this particular class of problem is definitely decidable, I'm skeptical that you can efficiently solve these problems for more complex curves. I suspect that it would be possible to construct short formulas that describe curves that are mostly empty but have a huge bounding box.
If you happen to know more about the structure of the problems you're trying to solve - for example, if you're always dealing with spheres or ellipses - then you may be able to find fast algorithms for this problem. In general, though, I don't think you'll be able to do much better than brute force. I'm willing to admit that (and in fact, hopeful that) someone will prove me wrong about this, though.
The idea behind the kd-tree method is that you recursive subdivide the search box and try to rule out whole boxes at a time. Given the current box, use some method that either (a) declares that all points in the box match the predicate (b) declares that no points in the box match the predicate (c) makes no declaration (one possibility, which may be particularly convenient in Haskell: interval arithmetic). On (c), cut the box in half (say along the longest dimension) and recursively count in the halves. Obviously the method can choose (c) all the time, which devolves to brute force; the goal here is to do (a) or (b) as much as possible.
The performance of this method is very dependent on how it's instantiated. Try it -- it shouldn't be more than a couple dozen lines of code.
For nicely connected region, assuming your shape is significantly smaller than your containing search space, and given a seed point, you could do a growth/building algorithm:
Given a seed point:
Push seed point into test-queue
while test-queue has items:
Pop item from test-queue
If item tests to be within region (eg using a callback function):
Add item to inside-set
for each neighbour point (generated on the fly):
if neighbour not in outside-set and neighbour not in inside-set:
Add neighbour to test-queue
else:
Add item to outside-set
return inside-set
The trick is to find an initial seed point that is inside the function.
Make sure your set implementation gives O(1) duplicate checking. This method will eventually break down with large numbers of dimensions as the surface area exceeds the volume, but for 5 dimensions should be fine.

Stack overflow on an OCaml recursive solution to the knight's shortest path on chess board puzzle

The question is as described here: Knight's Shortest Path Chess Question. I tried to solve it using an intuitive recursive method, as follows:
let is_in_list x s = List.exists (fun y -> if y = x then true else false) s;; (* find out if an element belongs to a list *)
let next_step n = [n+10;n-6;n+6;n-10;n+17;n-17;n+15;n-15];;
let rec legal_next_step = function
|[]->[]
|x::s->
if x<0 or x>63 then legal_next_step s
else x::legal_next_step s;;
let find_next_step n = legal_next_step (next_step n);; (* here is to find all the valid next moves and put them into a list*)
let rec min s =
let rec loop result = function
|[]->result;
|x::s->
if x < result then loop x s
else loop result s in
loop (List.hd s) s;;
let rec find_shortest_path n m =
if is_in_list m (next_step n) then 1
else
1 + min (List.map (fun x -> find_shortest_path x m) (find_next_step n)) ;;
This causes a “stack overflow” issue. Why is that? Is my program creating too many layers of recursive call in the stack? Or something is terribly wrong with my code.
You have to understand that when you write
List.map (fun x -> find_shortest_path x m) (find_next_step n))
You will literally compute all "shortest path from here" from all possible neighbors -- then compute the minimum of all those results.
So there is an infinite loop in your code: if you start from position A and try to compute the shortest path from one of its neighbors B, then find_shortest_path called from B will inevitably try to see how long the path would be if his first move was to go back to A. So, among all other possible moves that will also be tried, you will compute the "length" of the loop A-B-A-B-A-B..., that is, loop endlessly.
There are several ways to avoid that issue (that is not related to OCaml programming per se, it's an error in your program logic that would be manifest in any language):
use a breadth-first search instead of a depth-first-search, so that you incrementally explore all paths of a given length, stopping at the smallest winning path you find; if you want, this corresponds to explore all paths in parallel, so it's not an issue to have infinite paths as long as you stop (because you have found another solution) before trying to search the whole infinite path
mark the places you've already visited, so as to not "go back" (this will never be the shortest way to reach your destination)
if you use depth-first search this is delicate because those marks must be local to a search (you cannot simply mutate a matrix of booleans); for example, you could add an int list parameter to your find_shortest_path functions, that would be the list of places that are part of the currently explored path; before trying to compute the shortest path from a possible neighbors, check that it is not in this list. For something more efficient, you can use a set (module IntSet = Set.Make(struct type t = int let compare = Pervasives.compare)) (logarithmic, instead of linear, membership test), or use a mutable boolean matrix where you are careful to backtrack state changes when you choose a different path.
if you use breadth-first search, you can use a global boolean matrix of "places you've already visited", because you simultaneously explore all paths upto a given length; so if you encounter a place that is already marked as visited, you know that another path visited it in an earlier time, so it is already ahead of you and there is no point trying to get a shortest path from there.
So the short answer is: you should learn about breadth-first search.
Well, the next legal move calculation looks wrong to me. If I'm at lower right (square 7, say), I can't move to square 1. This shouldn't cause looping, however, it should just get the wrong answer.
My guess is that you're just following some very long, failing paths. I think you need to do a breadth-first search rather than depth first. In essence, you keep a set of reachable squares, advance each currently reachable spot by one move at each step. Your code always tries to reach the destination from each new spot, and hence (possibly) follows many long paths.

Which algorithm will be required to do this?

I have data of this form:
for x=1, y is one of {1,4,6,7,9,18,16,19}
for x=2, y is one of {1,5,7,4}
for x=3, y is one of {2,6,4,8,2}
....
for x=100, y is one of {2,7,89,4,5}
Only one of the values in each set is the correct value, the rest is random noise.
I know that the correct values describe a sinusoid function whose parameters are unknown. How can I find the correct combination of values, one from each set?
I am looking something like "travelling salesman"combinatorial optimization algorithm
You're trying to do curve fitting, for which there are several algorithms depending on the type of curve you want to fit your curve to (linear, polynomial, etc.). I have no idea whether there is a specific algorithm for sinusoidal curves (Fourier approximations), but my first idea would be to use a polynomial fitting algorithm with a polynomial approximation of the sine.
I wonder whether you need to do this in the course of another larger program, or whether you are trying to do this task on its own. If so, then you'd be much better off using a statistical package, my preferred one being R. It allows you to import your data and fit curves and draw graphs in just a few lines, and you could also use R in batch-mode to call it from a script or even a program (this is what I tend to do).
It depends on what you mean by "exactly", and what you know beforehand. If you know the frequency w, and that the sinusoid is unbiased, you have an equation
a cos(w * x) + b sin(w * x)
with two (x,y) points at different x values you can find a and b, and then check the generated curve against all the other points. Choose the two x values with the smallest number of y observations and try it for all the y's. If there is a bias, i.e. your equation is
a cos(w * x) + b sin(w * x) + c
You need to look at three x values.
If you do not know the frequency, you can try the same technique, unfortunately the solutions may not be unique, there may be more than one w that fits.
Edit As I understand your problem, you have a real y value for each x and a bunch of incorrect ones. You want to find the real values. The best way to do this is to fit curves through a small number of points and check to see if the curve fits some y value in the other sets.
If not all the x values have valid y values then the same technique applies, but you need to look at a much larger set of pairs, triples or quadruples (essentially every pair, triple, or quad of points with different y values)
If your problem is something else, and I suspect it is, please specify it.
Define sinusoid. Most people take that to mean a function of the form a cos(w * x) + b sin(w * x) + c. If you mean something different, specify it.
2 Specify exactly what success looks like. An example with say 10 points instead of 100 would be nice.
It is extremely unclear what this has to do with combinatorial optimization.
Sinusoidal equations are so general that if you take any random value of all y's these values can be fitted in sinusoidal function unless you give conditions eg. Frequency<100 or all parameters are integers,its not possible to diffrentiate noise and data theorotically so work on finding such conditions from your data source/experiment first.
By sinusoidal, do you mean a function that is increasing for n steps, then decreasing for n steps, etc.? If so, you you can model your data as a sequence of nodes connected by up-links and down-links. For each node (possible value of y), record the length and end-value of chains of only ascending or descending links (there will be multiple chain per node). Then you scan for consecutive runs of equal length and opposite direction, modulo some initial offset.

Resources