How to traverse a grid using two different paths to maximize the sum of the path? - algorithm

I have an N by N grid, with values in each box. I have to move from the top-left corner to the bottom-right corner (path 1) and from the top-right corner to the bottom-left (path 2). When I move from top-left to bottom-right I can only move down or to the right. Likewise, when I move from the top-right to the bottom-left I can only move left and down.
But if I move down while taking path 1, the corresponding move for path 2 should be to the left. Similarly, if I move right while taking path 1, the corresponding move for path 2 should be down.
As we take both paths, we sum up the values we encounter in each box. What is the maximum value we can obtain?
Consider as an example the following grid:
6 0 3 -1
7 4 2 4
-3 3 -2 8
13 10 -1 -4
The best paths we can take are represented as follows: path one is represented by a *, while path 2 by a ~.
(6*) (0) (3~) (-1~)
(7*) (4*~) (2~) (4)
(-3) (3*~) (-2*) (8*)
(13~) (10~) (-1) (-4*)
The sum for both of these paths is 56.
We have to devise an algorithm to compute the maximum possible score given an arbitrary N by N grid.
It was pretty clear that this was a DP problem. So, I tried to identify a recurrence relation, so to speak. I tried using the recurrence relation from the classic problem of finding the maximum sum over all paths in an N by M grid, but that didn't work because it just got too complicated.
I tried to divide the N by N grid into four (N-1) by (N-1) grids that overlap, so demonstrating this in a 3 by 3 grid:
a1 a2 a3
a4 a5 a6
a7 a8 a9
I divided this into four 2 x 2 grids:
a1 a2 , a2 a3 , a4 a5 , a5 a6
a4 a5 , a5 a6 , a7 a8 , a8 a9
Assuming we know the best paths for all these grids, can we then compute the best path for the larger grid?
Well, this seemed promising, but I quickly found out that these recurrence relations, were dependent on the larger case. For example,
If we consider the second 2 x 2 grid, assuming we know the best path 1 and path 2 = S. Now, clearly, for us to get from a1 to a2, we need to move right, but this means that the first move in the sub case (the first move in path 2) should be to the down, which isn't guaranteed.
How do we solve this?

The rules for moving the two points are equivalent to finding a single path through a grid which is a sum of your grid and itself rotated -90 degrees (90 degrees to the left / counterclockwise / anti-clockwise, depending on your locale).
"Down" for the top-left point corresponds to "Left" for the top-right point, which when rotated -90 degrees is down. "Right" for the top-left point corresponds to "Down" for the top-right point, which when rotated -90 degrees is right. (Got it?)
So your example grid is
6-1 0+4 3+8 -1-4 5 4 11 -5
7+3 4+2 2-2 4-1 10 6 0 3
=
-3+0 3+4 -2+3 8+10 -3 7 1 18
13+6 10+7 -1-3 -4+13 19 17 -4 9
You can now find a path from top-left to bottom-right by any of the usual means. In fact, you don't need the path, just the maximal sum, which is easier: collapse the matrix from top-left down by addition. The initial condition is the above grid. The next step is to add the top left value to its valid neighbors:
9 11 -5
15 6 0 3
-3 7 1 18
19 17 -4 9
Then pick the larger of the two neighbors for any grid point with two valid neighbors (here 21 is larger than 20 and 12):
20 -5
21 0 3
12 7 1 18
19 17 -4 9
And so on...
15
21 3 24
->
28 1 18 29 18 -> 47
->
31 17 -4 9 48 -4 9 44 9 56
I have just solved your 4x4 case by hand, and the answer is 56.

You can reduce this to the case for just one path on one grid. Make a second copy of the grid, rotate the second copy, then matrix-add them together and solve on the new grid with just one path. The dynamic programming problem is easy from there (i.e. compute partial maximums for each node).

Related

Find the number of all possible path in a grid, from (0, 0) to (n, n)

I don't know how to find the number of all possible path in a grid, from a Point A to a Point B.
The point A is on (0,0) and the point B is on (n,n).
A can move up, down, right, and left, and can't move on visited points.
While A moving, A(x,y) = (x,y|(0=<x=<n)∩(0=<y=<n)).
You can solve this problem with recursive backtracking, but there's another approach which I think is more interesting.
If we work out the first few cases by hand we find that:
A 1x1 square has 1 path
A 2x2 square has 2 paths
A 3x3 square has 12 paths
If we then go to OEIS (the Online Encyclopedia of Integer Sequences) and put in the search phrase "1,2,12 paths", the very first result is A007764 which is entitled "Number of nonintersecting (or self-avoiding) rook paths joining opposite corners of an n X n grid".
Knowing what integer sequence you're looking for unlocks significant mathematical resources, including source code to generate the sequence, related sequences, and best-known values.
The known values of the sequence are:
1 1
2 2
3 12
4 184
5 8512
6 1262816
7 575780564
8 789360053252
9 3266598486981642
10 41044208702632496804
11 1568758030464750013214100
12 182413291514248049241470885236
13 64528039343270018963357185158482118
14 69450664761521361664274701548907358996488
15 227449714676812739631826459327989863387613323440
16 2266745568862672746374567396713098934866324885408319028
17 68745445609149931587631563132489232824587945968099457285419306
18 6344814611237963971310297540795524400449443986866480693646369387855336
19 1782112840842065129893384946652325275167838065704767655931452474605826692782532
20 1523344971704879993080742810319229690899454255323294555776029866737355060592877569255844
21 3962892199823037560207299517133362502106339705739463771515237113377010682364035706704472064940398
22 31374751050137102720420538137382214513103312193698723653061351991346433379389385793965576992246021316463868
23 755970286667345339661519123315222619353103732072409481167391410479517925792743631234987038883317634987271171404439792
24 55435429355237477009914318489061437930690379970964331332556958646484008407334885544566386924020875711242060085408513482933945720
25 12371712231207064758338744862673570832373041989012943539678727080484951695515930485641394550792153037191858028212512280926600304581386791094
26 8402974857881133471007083745436809127296054293775383549824742623937028497898215256929178577083970960121625602506027316549718402106494049978375604247408
27 17369931586279272931175440421236498900372229588288140604663703720910342413276134762789218193498006107082296223143380491348290026721931129627708738890853908108906396
You can generate the first few terms yourself on paper or via recursive backtracking, per the other answer.
I would suggest solving this with naive recursion.
Keep a set visted of places that you have visited. And in pseudo-code that is deliberately not any particular language:
function recursive_call(i, j, visited=none)
if visited is none then
visited = set()
end if
if i = n and j = n then
return 1
else if (i, j) in visited or not in grid then
return 0
else
total = 0
add (i, j) to visited
for direction in directions:
(new_i, new_j) = move(i, j, direction)
total += recursive_call(new_i, new_j, visited)
remove (i, j) from visited
return total
end if
end function

Find elements of given matrix

You are given an infinite matrix whose upper-left square starts with 1. Here are the first five rows of the infinite matrix :
1 2 9 10 25
4 3 8 11 24
5 6 7 12 23
16 15 14 13 22
17 18 19 20 21
Your task is to find out the number in presents at row x and column y after observing a certain kind of patter present in the matrix
Input Format
The first input line contains an integer t: the number of test cases
After this, there are t lines, each containing integer x and y
For each test, print the number present at xth row and yth column.
sample input
3
2 3
1 1
4 2
sample output
8
1
15
Hint: the numbers at the right and bottom border of a left upper square are consecutive (going either down and left, or right and up). First determine in which border your position is, then find out which direction applies, and finally find the correct number at the position (which easy formula gives you the first number in the border?).

Convert diamond matrix 2d coordinates to 1d index and back

I have a 2d game board that expands as tiles are added to the board. Tiles can only be adjacent to existing tiles in the up, down, left and right positions.
So I thought a diamond spiral matrix would be the most efficient way to store the board, but I cannot find a way to convert the x,y coordinates to a 1d array index or the reverse operation.
like this layout
X -3 -2 -1 0 1 2 3
Y 3 13
2 24 5 14
1 23 12 1 6 15
0 22 11 4 0 2 7 16
-1 21 10 3 8 17
-2 20 9 18
-3 19
Tile 1 will always be at position 0, tile 2 will be at 1,2,3 or 4, tile 3 somewhere from 1 to 12 etc.
So I need an algorithm that goes from X,Y to an index and from an index back to the original X and Y.
Anyone know how to do this, or recommend another space filling algorithm that suits my needs. I'm probably going to use Java but would prefer something language neutral.
Thanks
As I can understand form the problem statement, there is no guarantee that the tiles will be filled evenly on the sides. for example:
X -3 -2 -1 0 1 2 3
Y 3 6
2 3 4 5
1 1
0 0 2
-1
So, I think a diamond matrix won't be the best choice.
I would suggest storing them in a hash-map, like implementing a dictionary for 2 letter words.
Also, You need to be more specific to what your requirements are. Like, do you prioritize space complexity over time? Or do you want a fast access time and don't care about memory usage that much.
IMPORTANT :
Also, what is the
Max number of tiles that we have to hold
Max width and height of the board.

Matlab - Algorithm for calculating 1d consecutive line segment edges from midpoints?

So I have a rectilinear grid that can be described with 2 vectors. 1 for the x-coordinates of the cell centres and one for the y-coordinates. These are just points with spacing like x spacing is 50 scaled to 10 scaled to 20 (55..45..30..10,10,10..10,12..20,20,20) and y spacing is 60 scaled to 40 scaled to 60 (60,60,60,55..42,40,40,40..40,42..60,60) and the grid is made like this
e.g. x = 1 2 3, gridx = 1 2 3, y = 10 11 12, gridy = 10 10 10
1 2 3 11 11 11
1 2 3 12 12 12
so then cell centre 1 is 1,10 cc2 is 2,10 etc.
Now Im trying to formulate an algorithm to calculate the positions of the cell edges in the x and y direction. So like my first idea was to first get the first edge using x(1)-[x(2)-x(1)]/2, in the real case x(2)-x(1) is equal to 60 and x(1) = 16348.95 so celledge1 = x(1)-30 = 16318.95. Then after calculating the first one I go through a loop and calculate the rest like this:
for aa = 2:length(x)+1
celledge1(aa) = x(aa-1) + [x(aa-1)-celledge(aa-1)]
end
And I did the same for y. This however does not work and my y vector in the area where the edge spacing should be should be 40 is 35,45,35,45... approx.
Anyone have any idea why this doesnt work and can point me in the right direction. Cheers
Edit: Tried to find a solution using geometric alebra:
We are trying to find the points A,B,C,....H. From basic geometry we know:
c1 (centre 1) = [A+B]/2 and c2 = [B+C]/2 etc. etc.
So we have 7 equations and 8 variables. We also know the the first few distances between centres are equal (60,60,60,60) therefore the first segment is 60 too.
B - A = 60
So now we have 8 equations and 8 variables so I made this algorithm in Matlab:
edgex = zeros(length(DATA2.x)+1,1);
edgey = zeros(length(DATA2.y)+1,1);
edgex(1) = (DATA2.x(1)*2-diffx(1))/2;
edgey(1) = (DATA2.y(1)*2-diffy(1))/2;
for aa = 2:length(DATA2.x)+1
edgex(aa) = DATA2.x(aa-1)*2-edgex(aa-1);
end
for aa = 2:length(DATA2.y)+1
edgey(aa) = DATA2.y(aa-1)*2-edgey(aa-1);
end
And I still got the same answer as before with the y spacing going 35,45,35,45 where it should be 40,40,40... Could it be an accuracy error??
Edit: here are the numbers if ur interested and I did the same computation as above only in excel: http://www.filedropper.com/workoutedges
It seems you're just trying to interpolate your data. You can do this with the built-in interp1
x = [30 24 19 16 8 7 16 22 29 31];
xi = interp1(2:2:numel(x)*2, x, 1:(numel(x)*2+1), 'linear', 'extrap');
This just sets up the original data as the even-indexed elements and interpolates the odd indices, including extrapolation for the two end points.
Results:
xi =
Columns 1 through 11:
33.0000 30.0000 27.0000 24.0000 21.5000 19.0000 17.5000 16.0000 12.0000 8.0000 7.5000
Columns 12 through 21:
7.0000 11.5000 16.0000 19.0000 22.0000 25.5000 29.0000 30.0000 31.0000 32.0000

How to assign a different value to each node and each arc of a tree

I wanted to ask a somewhat specific question. I had to solve a problem, which I manage to do with some help. I want to explain what I did and then say what I've been told I'm missing.
What I did: Given a list of nodes (a-b,b-c) I return nodes "ids" from 1 to N (like giving them a name, each an unique number). Then, I see which nodes are connected, and calculate the absolute number that subtracting its names/ids gives me (a-b would be 1-2, abs of that is 1. b-c would have 2-3 as values and would get another 1 for their arc. If I had an a-d node, I would return 1-4, so 3 as their arc value).
Then I return the list of nodes and their IDs/values, and the list of the arcs and its values (1,a-b), (1,a-c).
Graphically:
6a
5 4
1b 2e
2 3
3c 5f
1
4d
5a
4 3
1b 2e
1 2
3c 4f
5a
4 3
1b 2e
2
3c
1
4d
9a
8 7
1b 2e
6 4
7c 6f
2 2
5d 4g
3 1
8h 3i
I've worked this by hand so... still no clear algorythm.
What I've been told I'm missing: Each ARC has to have an unique number, too. So not only nodes, but nodes and arc can only have one number, from 1 to N, being N the number of nodes/arcs.
Problem is, I can't figure this out, at all. Closer I get if I do it on paper, I would calculate doing longer and longer ecuations, but not sure that would actually solve anything, so far I found nothing.
The reason for me not understanding this is that the tree/list a-b,b-c would have as nodes:
a-3,b-2,c-1 ; and arcs: 2,a-b|1,b-c
And another, very simple list like a-b,a-c would have:
a-2,b-1,c-3 ; and arcs: 2,a-b|1,a-c
This is one possible solution, but if the trees grow bigger, I fail to see how is it possible for each arc to have one value between 1 and N, non repeating, and same for each node. Is this even possible? How should I approach this task/am I missing some kind of point of view?
Thanks in advance.
edit: since I am not being clear with terminology:
enumerate(CONNECTIONS_IN, NODES_OUT, ARCS_OUT)
?- enumerate([a-b,b-c], EnumNodos, EnumArcos) returns, as of right now:
EnumNodos=[(1,a),(2,b),(3,c)]
EnumArcos=[(1,a-b), (1,a-c)]
It should give:
EnumNodos=[(3,a),(1,b),(2,c)]
EnumArcos=[(1,a-b), (2,a-c)]%because each arc HAS to have an unique number from 1 to N-1 (nodes are from 1 to N)

Resources