3

I am currently working on a project, in which I have to perform tasks with a 2 dimensional array, containing random numbers. The array forms a grid, which represents peaks (heights) of a mountain. I resolved every task except the last one:

The last task would be to find if there exists a path, which goes form the smallest peak to the highest (it doesn't have to be the shortest). The path should consist of ever growing peaks, I can't step on a lower peak.

Here's an example, for simplicity's sake, represented on 3x3 grid (original is much bigger, and not necessary square-like, it's generated as the user wants and numbers are completely random).

2  4  5    
1  3  8
9  7  10

The possible ways would be 1-3-7-10, 1-3-8-10, 1-2-4-5-8-10.

I am pretty sure, that I should use some kind of a recursion. I read about a* pathfinder, but to work with it, I have to have a "map" with the "obstacles" (the nodes where I cannot step = smaller peaks) and that is exactly, which I can't make, as you only find it out on the go.

By that I mean I could put number 7 on a "exception list" -as steps 1-9-7 are forbidden, but steps 1-3-7-10 are perfect, so putting 7 on a exception list would be a mistake.

1
  • You missed 1-3-4-5-8-10 :) Commented Dec 2, 2012 at 9:59

3 Answers 3

3

The key is to first convert your array into a "digraph" which is a directed-graph consisting only of the valid cell-to-cell moves according to your rules. This digraph would be an array or list of entries consisting of: {FromCell, ToCell}

Your digraph would contain data like this:

2,4
4,5
5,8
1,2
1,3
1,9
3,4
3,8
3,7
8,10
7,10

From here you should be able to apply the A* algorithm, or any of a number of others.

(note: I am not posting a completed answer, as I assume that you want to do this yourself)


That said, you could just do a brute-force recursive search with back-tracking. This is the simplest solution, though probably not the most efficient.

Sign up to request clarification or add additional context in comments.

4 Comments

Nice solution :), but the complexity might be a bit high. Isn't it O(n^2) to create all the pairs plus the complexity of the A* algorithm
No, its O(n) to create the pairs. They do have to be adjacent don't they? There's never more than four adjacent TO-cells for any given FROM-cell. Even if the do not, you could just sort them by value first, which would make it at worst, O(N log N)
Touche.. my bad. It's late here :)
So if I understand you correctly, I could collect the valid movements by performing a simple search and putting the valid movements in another 2d array, which should be dynamic. Then, as I move along peaks I should look if the peaks match up with the valid movement, am I correct? Also, as i am still a rookie in programming I don't really know how I should implement your solution recursively.
0

You could do the following:

  1. Create a weighted graph from your matrix (the weight of each edge would be the abs( difference between the values of the two nodes))

    2 - 4 - 5
    
    |   |   |
    
    1 - 3 - 8
    
    |   |   |
    
    9 - 7 - 9 
    

the weight of (2, 4) is abs(4 - 2) = 2

the weight of (4, 5) is abs(4 - 5) = 1

  1. Apply a shortest path algorithm which takes into account the weight of the edges http://www.informatics.susx.ac.uk/courses/dats/notes/html/node147.html

  2. Remove the solutions in which the values of the nodes aren't ascending

7 Comments

Do you mean the modulus operation with mod or just a difference of which you take the absolute value?
absolute value of the difference between 2 numbers
I like the idea, but I don't think you understood my exact problem. My problem is that I need a "map" or a "blacklist", with which I can avoid illegal steps to use path algorithms.
Yeah ... it seems so. I didn't really read the question through. Maybe you could use my answer in a similar problem :)
Your idea could be good for this task, but I don't know how to use graphs yet and it might complicate the implementation in a task as "simple" as mine (everything is difficult for a beginner like me, tough).
|
0

(I fixed post and placed the answer here.)

This is how I finally solved it:

Since I already had the min and max places, I surrounded the original array with zeroes. Zeroes are global minimums of the array, as I never generate zeroes by default. With this I don't have to check every time if I'm out or in the array (I only step on bigger numbers).

I created two queues (QueueX,QueueY). Starting from the smallest number (whose place I en-queued in the beginning into the queues, gave to x,y variables of array t[x,y], and then de-queue).

I then en-queue every bigger numbers' "coordinates" into the respective queues. If I found all the bigger numbers around the actual point (t[x,y]), I en-queue the next X,Y coordinates, which will be the new actual points (as explained in the start). And the inspection repeats.

The whole thing is in a while cycle, which stays in while one of the queues empty out.

If at any given inspection X,Y is the same as max peak's X,Y coordinates, I return and there exists a path. At the end of the while cycle if X,Y isn't the same as max's X,Y, there is no path.

I hope my explanation is somewhat understandable, English isn't my native language. If you'd like, I could post the code here.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.