Finding shortest path in two dimensional array (Javascript) Announcing the arrival of Valued Associate #679: Cesar Manara Planned maintenance scheduled April 23, 2019 at 23:30 UTC (7:30pm US/Eastern) Data science time! April 2019 and salary with experience The Ask Question Wizard is Live!Finding shortest path in 2d arrayHow can I merge properties of two JavaScript objects dynamically?How do I check if an array includes an object in JavaScript?Compare two dates with JavaScriptHow to insert an item into an array at a specific index (JavaScript)?How can I create a two dimensional array in JavaScript?How do I empty an array in JavaScript?Loop through an array in JavaScriptEasy interview question got harder: given numbers 1..100, find the missing number(s)How do I remove a particular element from an array in JavaScript?For-each over an array in JavaScript?
Noise in Eigenvalues plot
How can I list files in reverse time order by a command and pass them as arguments to another command?
How does TikZ render an arc?
Does the main washing effect of soap come from foam?
Table formatting with tabularx?
Any stored/leased 737s that could substitute for grounded MAXs?
Did pre-Columbian Americans know the spherical shape of the Earth?
draw a pulley system
How does the body cool itself in a stillsuit?
Was the pager message from Nick Fury to Captain Marvel unnecessary?
Why do the Z-fighters hide their power?
3D Masyu - A Die
An isoperimetric-type inequality inside a cube
Are there any irrational/transcendental numbers for which the distribution of decimal digits is not uniform?
Where and when has Thucydides been studied?
why doesn't university give past final exams' answers
How to make triangles with rounded sides and corners? (squircle with 3 sides)
Marquee sign letters
What does Sonny Burch mean by, "S.H.I.E.L.D. and HYDRA don't even exist anymore"?
Why not use the yoke to control yaw, as well as pitch and roll?
Problem with display of presentation
Can I cut the hair of a conjured korred with a blade made of precious material to harvest that material from the korred?
Improvising over quartal voicings
How to achieve cat-like agility?
Finding shortest path in two dimensional array (Javascript)
Announcing the arrival of Valued Associate #679: Cesar Manara
Planned maintenance scheduled April 23, 2019 at 23:30 UTC (7:30pm US/Eastern)
Data science time! April 2019 and salary with experience
The Ask Question Wizard is Live!Finding shortest path in 2d arrayHow can I merge properties of two JavaScript objects dynamically?How do I check if an array includes an object in JavaScript?Compare two dates with JavaScriptHow to insert an item into an array at a specific index (JavaScript)?How can I create a two dimensional array in JavaScript?How do I empty an array in JavaScript?Loop through an array in JavaScriptEasy interview question got harder: given numbers 1..100, find the missing number(s)How do I remove a particular element from an array in JavaScript?For-each over an array in JavaScript?
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;
I am trying to implement an algorithm, that finds the shortest path in the following two dimensional array (from the top left corner, to the right bottom corner):
[ [ 'A', 'A', 'A', 'B', 'A' ],
[ 'B', 'B', 'B', 'B', 'B' ],
[ 'A', 'B', 'A', 'A', 'A' ],
[ 'A', 'B', 'B', 'B', 'B' ],
[ 'A', 'A', 'A', 'A', 'A' ] ]
The rules are, that the path must alternate between A's and B's.
The output must be a number specifying the smallest number of steps it will take to go through the array. (In the example the expected output is 13)
Does anyone know of a simple Graph implementation that can help me solve this problem?
javascript algorithm graph-theory
|
show 2 more comments
I am trying to implement an algorithm, that finds the shortest path in the following two dimensional array (from the top left corner, to the right bottom corner):
[ [ 'A', 'A', 'A', 'B', 'A' ],
[ 'B', 'B', 'B', 'B', 'B' ],
[ 'A', 'B', 'A', 'A', 'A' ],
[ 'A', 'B', 'B', 'B', 'B' ],
[ 'A', 'A', 'A', 'A', 'A' ] ]
The rules are, that the path must alternate between A's and B's.
The output must be a number specifying the smallest number of steps it will take to go through the array. (In the example the expected output is 13)
Does anyone know of a simple Graph implementation that can help me solve this problem?
javascript algorithm graph-theory
Shortest path from and to?
– nick zoum
Mar 19 at 11:01
Whats is each value in the Array? Can you provide an sample output you are expecting from the provided data.
– Dipak
Mar 19 at 11:01
Can you give more inputs to your problem statement
– Kartikeya Sharma
Mar 19 at 11:01
Sorry, it is from the top left corner to the right bottom corner
– Boris Grunwald
Mar 19 at 11:02
I've updated the question, please let me know if you need more information
– Boris Grunwald
Mar 19 at 11:04
|
show 2 more comments
I am trying to implement an algorithm, that finds the shortest path in the following two dimensional array (from the top left corner, to the right bottom corner):
[ [ 'A', 'A', 'A', 'B', 'A' ],
[ 'B', 'B', 'B', 'B', 'B' ],
[ 'A', 'B', 'A', 'A', 'A' ],
[ 'A', 'B', 'B', 'B', 'B' ],
[ 'A', 'A', 'A', 'A', 'A' ] ]
The rules are, that the path must alternate between A's and B's.
The output must be a number specifying the smallest number of steps it will take to go through the array. (In the example the expected output is 13)
Does anyone know of a simple Graph implementation that can help me solve this problem?
javascript algorithm graph-theory
I am trying to implement an algorithm, that finds the shortest path in the following two dimensional array (from the top left corner, to the right bottom corner):
[ [ 'A', 'A', 'A', 'B', 'A' ],
[ 'B', 'B', 'B', 'B', 'B' ],
[ 'A', 'B', 'A', 'A', 'A' ],
[ 'A', 'B', 'B', 'B', 'B' ],
[ 'A', 'A', 'A', 'A', 'A' ] ]
The rules are, that the path must alternate between A's and B's.
The output must be a number specifying the smallest number of steps it will take to go through the array. (In the example the expected output is 13)
Does anyone know of a simple Graph implementation that can help me solve this problem?
javascript algorithm graph-theory
javascript algorithm graph-theory
edited Mar 19 at 11:09
Boris Grunwald
asked Mar 19 at 10:59
Boris GrunwaldBoris Grunwald
496412
496412
Shortest path from and to?
– nick zoum
Mar 19 at 11:01
Whats is each value in the Array? Can you provide an sample output you are expecting from the provided data.
– Dipak
Mar 19 at 11:01
Can you give more inputs to your problem statement
– Kartikeya Sharma
Mar 19 at 11:01
Sorry, it is from the top left corner to the right bottom corner
– Boris Grunwald
Mar 19 at 11:02
I've updated the question, please let me know if you need more information
– Boris Grunwald
Mar 19 at 11:04
|
show 2 more comments
Shortest path from and to?
– nick zoum
Mar 19 at 11:01
Whats is each value in the Array? Can you provide an sample output you are expecting from the provided data.
– Dipak
Mar 19 at 11:01
Can you give more inputs to your problem statement
– Kartikeya Sharma
Mar 19 at 11:01
Sorry, it is from the top left corner to the right bottom corner
– Boris Grunwald
Mar 19 at 11:02
I've updated the question, please let me know if you need more information
– Boris Grunwald
Mar 19 at 11:04
Shortest path from and to?
– nick zoum
Mar 19 at 11:01
Shortest path from and to?
– nick zoum
Mar 19 at 11:01
Whats is each value in the Array? Can you provide an sample output you are expecting from the provided data.
– Dipak
Mar 19 at 11:01
Whats is each value in the Array? Can you provide an sample output you are expecting from the provided data.
– Dipak
Mar 19 at 11:01
Can you give more inputs to your problem statement
– Kartikeya Sharma
Mar 19 at 11:01
Can you give more inputs to your problem statement
– Kartikeya Sharma
Mar 19 at 11:01
Sorry, it is from the top left corner to the right bottom corner
– Boris Grunwald
Mar 19 at 11:02
Sorry, it is from the top left corner to the right bottom corner
– Boris Grunwald
Mar 19 at 11:02
I've updated the question, please let me know if you need more information
– Boris Grunwald
Mar 19 at 11:04
I've updated the question, please let me know if you need more information
– Boris Grunwald
Mar 19 at 11:04
|
show 2 more comments
4 Answers
4
active
oldest
votes
Since it represents an undirected unweighted graph, you can simply use BFS:
const m =
[ [ 'A', 'A', 'A', 'B', 'A' ],
[ 'B', 'B', 'B', 'B', 'B' ],
[ 'A', 'B', 'A', 'A', 'A' ],
[ 'A', 'B', 'B', 'B', 'B' ],
[ 'A', 'A', 'A', 'A', 'A' ] ]
let successors = (root, m) =>
let connectedCells = [
[root[0] - 1, root[1]],
[root[0], root[1] - 1],
[root[0] + 1, root[1]],
[root[0], root[1] + 1]
]
const validCells = connectedCells.filter(
(cell) => (
cell[0] >= 0 && cell[0] < m.length
&& cell[1] >= 0 && cell[1] < m[0].length)
)
const successors = validCells.filter(
(cell) => (m[cell[0]][cell[1]] !== m[root[0]][root[1]])
)
return successors
const buildPath = (traversalTree, to) =>
let path = [to]
let parent = traversalTree[to]
while (parent)
path.push(parent)
parent = traversalTree[parent]
return path.reverse()
const bfs = (from, to) =>
let traversalTree = []
let visited = new Set
let queue = []
queue.push(from)
while (queue.length)
let subtreeRoot = queue.shift()
visited.add(subtreeRoot.toString())
if (subtreeRoot.toString() == to.toString()) return buildPath(traversalTree, to)
for (child of successors(subtreeRoot, m))
if (!visited.has(child.toString()))
traversalTree[child] = subtreeRoot
queue.push(child)
console.log(bfs([0,0], [4,4]).length) // => 13
add a comment |
Well you can use grids as graphs without converting them to usual graph adjacency list representation.
So every pair (row,column) is a node,
You can go to next node only if: 2 nodes are neighbors and have different values,
The purpose of adjacency list is to get neighboring nodes efficient, but with grid cells you can just always check all 4 directions and process nodes that exist.
Sample code:
let A = [ [ 'A', 'A', 'A', 'B', 'A' ],
[ 'B', 'B', 'B', 'B', 'B' ],
[ 'A', 'B', 'A', 'A', 'A' ],
[ 'A', 'B', 'B', 'B', 'B' ],
[ 'A', 'A', 'A', 'A', 'A' ] ];
let visited = new Set();
let rows = A.length;
let columns = A[0].length;
let distance = Array(rows).fill().map(() => Array(columns).fill(-1));
distance[0][0]=0;
let Q = []; //Queue
Q.push([0,0]);
visited.add([0,0].toString());
let dr = [-1,1,0,0];
let dc = [0,0,-1,1];
while(Q.length > 0)
let cur = Q.shift();
let row = cur[0];
let col = cur[1];
for(let k=0; k<4; k++)
let newRow = row + dr[k];
let newCol = col + dc[k];
if(!visited.has([newRow,newCol].toString()) && newRow>=0 && newCol >=0 && newRow < rows && newCol < columns && A[newRow][newCol] !== A[row][col])
visited.add([newRow,newCol].toString());
distance[newRow][newCol] = distance[row][col] + 1;
Q.push([newRow,newCol]);
if(distance[rows-1][columns-1] === -1)console.log("Path does not exist");
else console.log(distance[rows-1][columns-1]);
add a comment |
One way to solve your problem is to first represent your 2D array as a graph, where each letter is a node, and there exists an edge between two nodes if the letter they represent are neighbor in the array, and these letters are different (one A
and one B
).
Then all you have to do is to use a classical shortest path algorithm, such as Dijkstra's, or A*, to find the shortest path between two nodes of your graph. This will be equivalent to finding the shortest path between two letters of your array.
Edit:
here is a pseudocode to answer the question you asked in the comment.
nodes = init_a_2d_array_of_graph_nodes(ARRAY_WIDTH, ARRAY_HEIGHT)
for i from 1 to ARRAY_WIDTH:
for j from 1 to ARRAY_HEIGHT:
if i < ARRAY_WIDTH and array[i][j] != array[i+1][j]:
add_edge(nodes[i][j], nodes[i+1][j])
if j < ARRAY_HEIGHT and array[i][j] != array[i][j+1]:
add_edge(nodes[i][j], nodes[i][j+1])
First, you need to initialize a graph structure. If you don't know how to do that, check online, there must be plenty of ways to do it, it is rather simple.
Then, you need to create one node for each letter in your array. It is convenient to store these node in a 2D array as well, so you can find out easily which letter of your array corresponds to which node in your graph.
Then, for all neighbor letters, you check if these letters are different (that is what is checked in the 2 if
conditions). If it is the case, you connect the two nodes with an edge.
After that, you'll need to run a shortest path algorithm on your graph, between your source node and destination node. Dijkstra's algorithm is the best way to get started with shortest path algorithm, it is the most widely used, and is fast enough in most of the situations you'll encounter.
Finally, once you have your path, you need to retrieve the index (row and column) of the nodes of your graph, that will give you the corresponding path in your letters array.
Feel free to comment again if there is still something you do not understand.
That is exactly what I am trying to do right now. What I am having trouble with right now, is finding a way to create an adjacency list from the array.
– Boris Grunwald
Mar 19 at 13:24
add a comment |
Does anyone know of a simple Graph implementation that can help me solve this problem?
The Dijkstra algortihm is used to find the shortest path between two nodes. Every position in your two-dimensional array represents a node, the edges are dynamically derived from the surrounding nodes that fulfill your "alternating" rule.
You can further optimise it for your use case with bidirectional search and a goal metric (A*).
IMO it would be simpler (and in any opinion - asymptotically faster) to use BFS for undirected non-weighted graphs.
– akurtser
Mar 19 at 15:34
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55239386%2ffinding-shortest-path-in-two-dimensional-array-javascript%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
Since it represents an undirected unweighted graph, you can simply use BFS:
const m =
[ [ 'A', 'A', 'A', 'B', 'A' ],
[ 'B', 'B', 'B', 'B', 'B' ],
[ 'A', 'B', 'A', 'A', 'A' ],
[ 'A', 'B', 'B', 'B', 'B' ],
[ 'A', 'A', 'A', 'A', 'A' ] ]
let successors = (root, m) =>
let connectedCells = [
[root[0] - 1, root[1]],
[root[0], root[1] - 1],
[root[0] + 1, root[1]],
[root[0], root[1] + 1]
]
const validCells = connectedCells.filter(
(cell) => (
cell[0] >= 0 && cell[0] < m.length
&& cell[1] >= 0 && cell[1] < m[0].length)
)
const successors = validCells.filter(
(cell) => (m[cell[0]][cell[1]] !== m[root[0]][root[1]])
)
return successors
const buildPath = (traversalTree, to) =>
let path = [to]
let parent = traversalTree[to]
while (parent)
path.push(parent)
parent = traversalTree[parent]
return path.reverse()
const bfs = (from, to) =>
let traversalTree = []
let visited = new Set
let queue = []
queue.push(from)
while (queue.length)
let subtreeRoot = queue.shift()
visited.add(subtreeRoot.toString())
if (subtreeRoot.toString() == to.toString()) return buildPath(traversalTree, to)
for (child of successors(subtreeRoot, m))
if (!visited.has(child.toString()))
traversalTree[child] = subtreeRoot
queue.push(child)
console.log(bfs([0,0], [4,4]).length) // => 13
add a comment |
Since it represents an undirected unweighted graph, you can simply use BFS:
const m =
[ [ 'A', 'A', 'A', 'B', 'A' ],
[ 'B', 'B', 'B', 'B', 'B' ],
[ 'A', 'B', 'A', 'A', 'A' ],
[ 'A', 'B', 'B', 'B', 'B' ],
[ 'A', 'A', 'A', 'A', 'A' ] ]
let successors = (root, m) =>
let connectedCells = [
[root[0] - 1, root[1]],
[root[0], root[1] - 1],
[root[0] + 1, root[1]],
[root[0], root[1] + 1]
]
const validCells = connectedCells.filter(
(cell) => (
cell[0] >= 0 && cell[0] < m.length
&& cell[1] >= 0 && cell[1] < m[0].length)
)
const successors = validCells.filter(
(cell) => (m[cell[0]][cell[1]] !== m[root[0]][root[1]])
)
return successors
const buildPath = (traversalTree, to) =>
let path = [to]
let parent = traversalTree[to]
while (parent)
path.push(parent)
parent = traversalTree[parent]
return path.reverse()
const bfs = (from, to) =>
let traversalTree = []
let visited = new Set
let queue = []
queue.push(from)
while (queue.length)
let subtreeRoot = queue.shift()
visited.add(subtreeRoot.toString())
if (subtreeRoot.toString() == to.toString()) return buildPath(traversalTree, to)
for (child of successors(subtreeRoot, m))
if (!visited.has(child.toString()))
traversalTree[child] = subtreeRoot
queue.push(child)
console.log(bfs([0,0], [4,4]).length) // => 13
add a comment |
Since it represents an undirected unweighted graph, you can simply use BFS:
const m =
[ [ 'A', 'A', 'A', 'B', 'A' ],
[ 'B', 'B', 'B', 'B', 'B' ],
[ 'A', 'B', 'A', 'A', 'A' ],
[ 'A', 'B', 'B', 'B', 'B' ],
[ 'A', 'A', 'A', 'A', 'A' ] ]
let successors = (root, m) =>
let connectedCells = [
[root[0] - 1, root[1]],
[root[0], root[1] - 1],
[root[0] + 1, root[1]],
[root[0], root[1] + 1]
]
const validCells = connectedCells.filter(
(cell) => (
cell[0] >= 0 && cell[0] < m.length
&& cell[1] >= 0 && cell[1] < m[0].length)
)
const successors = validCells.filter(
(cell) => (m[cell[0]][cell[1]] !== m[root[0]][root[1]])
)
return successors
const buildPath = (traversalTree, to) =>
let path = [to]
let parent = traversalTree[to]
while (parent)
path.push(parent)
parent = traversalTree[parent]
return path.reverse()
const bfs = (from, to) =>
let traversalTree = []
let visited = new Set
let queue = []
queue.push(from)
while (queue.length)
let subtreeRoot = queue.shift()
visited.add(subtreeRoot.toString())
if (subtreeRoot.toString() == to.toString()) return buildPath(traversalTree, to)
for (child of successors(subtreeRoot, m))
if (!visited.has(child.toString()))
traversalTree[child] = subtreeRoot
queue.push(child)
console.log(bfs([0,0], [4,4]).length) // => 13
Since it represents an undirected unweighted graph, you can simply use BFS:
const m =
[ [ 'A', 'A', 'A', 'B', 'A' ],
[ 'B', 'B', 'B', 'B', 'B' ],
[ 'A', 'B', 'A', 'A', 'A' ],
[ 'A', 'B', 'B', 'B', 'B' ],
[ 'A', 'A', 'A', 'A', 'A' ] ]
let successors = (root, m) =>
let connectedCells = [
[root[0] - 1, root[1]],
[root[0], root[1] - 1],
[root[0] + 1, root[1]],
[root[0], root[1] + 1]
]
const validCells = connectedCells.filter(
(cell) => (
cell[0] >= 0 && cell[0] < m.length
&& cell[1] >= 0 && cell[1] < m[0].length)
)
const successors = validCells.filter(
(cell) => (m[cell[0]][cell[1]] !== m[root[0]][root[1]])
)
return successors
const buildPath = (traversalTree, to) =>
let path = [to]
let parent = traversalTree[to]
while (parent)
path.push(parent)
parent = traversalTree[parent]
return path.reverse()
const bfs = (from, to) =>
let traversalTree = []
let visited = new Set
let queue = []
queue.push(from)
while (queue.length)
let subtreeRoot = queue.shift()
visited.add(subtreeRoot.toString())
if (subtreeRoot.toString() == to.toString()) return buildPath(traversalTree, to)
for (child of successors(subtreeRoot, m))
if (!visited.has(child.toString()))
traversalTree[child] = subtreeRoot
queue.push(child)
console.log(bfs([0,0], [4,4]).length) // => 13
const m =
[ [ 'A', 'A', 'A', 'B', 'A' ],
[ 'B', 'B', 'B', 'B', 'B' ],
[ 'A', 'B', 'A', 'A', 'A' ],
[ 'A', 'B', 'B', 'B', 'B' ],
[ 'A', 'A', 'A', 'A', 'A' ] ]
let successors = (root, m) =>
let connectedCells = [
[root[0] - 1, root[1]],
[root[0], root[1] - 1],
[root[0] + 1, root[1]],
[root[0], root[1] + 1]
]
const validCells = connectedCells.filter(
(cell) => (
cell[0] >= 0 && cell[0] < m.length
&& cell[1] >= 0 && cell[1] < m[0].length)
)
const successors = validCells.filter(
(cell) => (m[cell[0]][cell[1]] !== m[root[0]][root[1]])
)
return successors
const buildPath = (traversalTree, to) =>
let path = [to]
let parent = traversalTree[to]
while (parent)
path.push(parent)
parent = traversalTree[parent]
return path.reverse()
const bfs = (from, to) =>
let traversalTree = []
let visited = new Set
let queue = []
queue.push(from)
while (queue.length)
let subtreeRoot = queue.shift()
visited.add(subtreeRoot.toString())
if (subtreeRoot.toString() == to.toString()) return buildPath(traversalTree, to)
for (child of successors(subtreeRoot, m))
if (!visited.has(child.toString()))
traversalTree[child] = subtreeRoot
queue.push(child)
console.log(bfs([0,0], [4,4]).length) // => 13
const m =
[ [ 'A', 'A', 'A', 'B', 'A' ],
[ 'B', 'B', 'B', 'B', 'B' ],
[ 'A', 'B', 'A', 'A', 'A' ],
[ 'A', 'B', 'B', 'B', 'B' ],
[ 'A', 'A', 'A', 'A', 'A' ] ]
let successors = (root, m) =>
let connectedCells = [
[root[0] - 1, root[1]],
[root[0], root[1] - 1],
[root[0] + 1, root[1]],
[root[0], root[1] + 1]
]
const validCells = connectedCells.filter(
(cell) => (
cell[0] >= 0 && cell[0] < m.length
&& cell[1] >= 0 && cell[1] < m[0].length)
)
const successors = validCells.filter(
(cell) => (m[cell[0]][cell[1]] !== m[root[0]][root[1]])
)
return successors
const buildPath = (traversalTree, to) =>
let path = [to]
let parent = traversalTree[to]
while (parent)
path.push(parent)
parent = traversalTree[parent]
return path.reverse()
const bfs = (from, to) =>
let traversalTree = []
let visited = new Set
let queue = []
queue.push(from)
while (queue.length)
let subtreeRoot = queue.shift()
visited.add(subtreeRoot.toString())
if (subtreeRoot.toString() == to.toString()) return buildPath(traversalTree, to)
for (child of successors(subtreeRoot, m))
if (!visited.has(child.toString()))
traversalTree[child] = subtreeRoot
queue.push(child)
console.log(bfs([0,0], [4,4]).length) // => 13
answered Mar 19 at 15:27
akurtserakurtser
523511
523511
add a comment |
add a comment |
Well you can use grids as graphs without converting them to usual graph adjacency list representation.
So every pair (row,column) is a node,
You can go to next node only if: 2 nodes are neighbors and have different values,
The purpose of adjacency list is to get neighboring nodes efficient, but with grid cells you can just always check all 4 directions and process nodes that exist.
Sample code:
let A = [ [ 'A', 'A', 'A', 'B', 'A' ],
[ 'B', 'B', 'B', 'B', 'B' ],
[ 'A', 'B', 'A', 'A', 'A' ],
[ 'A', 'B', 'B', 'B', 'B' ],
[ 'A', 'A', 'A', 'A', 'A' ] ];
let visited = new Set();
let rows = A.length;
let columns = A[0].length;
let distance = Array(rows).fill().map(() => Array(columns).fill(-1));
distance[0][0]=0;
let Q = []; //Queue
Q.push([0,0]);
visited.add([0,0].toString());
let dr = [-1,1,0,0];
let dc = [0,0,-1,1];
while(Q.length > 0)
let cur = Q.shift();
let row = cur[0];
let col = cur[1];
for(let k=0; k<4; k++)
let newRow = row + dr[k];
let newCol = col + dc[k];
if(!visited.has([newRow,newCol].toString()) && newRow>=0 && newCol >=0 && newRow < rows && newCol < columns && A[newRow][newCol] !== A[row][col])
visited.add([newRow,newCol].toString());
distance[newRow][newCol] = distance[row][col] + 1;
Q.push([newRow,newCol]);
if(distance[rows-1][columns-1] === -1)console.log("Path does not exist");
else console.log(distance[rows-1][columns-1]);
add a comment |
Well you can use grids as graphs without converting them to usual graph adjacency list representation.
So every pair (row,column) is a node,
You can go to next node only if: 2 nodes are neighbors and have different values,
The purpose of adjacency list is to get neighboring nodes efficient, but with grid cells you can just always check all 4 directions and process nodes that exist.
Sample code:
let A = [ [ 'A', 'A', 'A', 'B', 'A' ],
[ 'B', 'B', 'B', 'B', 'B' ],
[ 'A', 'B', 'A', 'A', 'A' ],
[ 'A', 'B', 'B', 'B', 'B' ],
[ 'A', 'A', 'A', 'A', 'A' ] ];
let visited = new Set();
let rows = A.length;
let columns = A[0].length;
let distance = Array(rows).fill().map(() => Array(columns).fill(-1));
distance[0][0]=0;
let Q = []; //Queue
Q.push([0,0]);
visited.add([0,0].toString());
let dr = [-1,1,0,0];
let dc = [0,0,-1,1];
while(Q.length > 0)
let cur = Q.shift();
let row = cur[0];
let col = cur[1];
for(let k=0; k<4; k++)
let newRow = row + dr[k];
let newCol = col + dc[k];
if(!visited.has([newRow,newCol].toString()) && newRow>=0 && newCol >=0 && newRow < rows && newCol < columns && A[newRow][newCol] !== A[row][col])
visited.add([newRow,newCol].toString());
distance[newRow][newCol] = distance[row][col] + 1;
Q.push([newRow,newCol]);
if(distance[rows-1][columns-1] === -1)console.log("Path does not exist");
else console.log(distance[rows-1][columns-1]);
add a comment |
Well you can use grids as graphs without converting them to usual graph adjacency list representation.
So every pair (row,column) is a node,
You can go to next node only if: 2 nodes are neighbors and have different values,
The purpose of adjacency list is to get neighboring nodes efficient, but with grid cells you can just always check all 4 directions and process nodes that exist.
Sample code:
let A = [ [ 'A', 'A', 'A', 'B', 'A' ],
[ 'B', 'B', 'B', 'B', 'B' ],
[ 'A', 'B', 'A', 'A', 'A' ],
[ 'A', 'B', 'B', 'B', 'B' ],
[ 'A', 'A', 'A', 'A', 'A' ] ];
let visited = new Set();
let rows = A.length;
let columns = A[0].length;
let distance = Array(rows).fill().map(() => Array(columns).fill(-1));
distance[0][0]=0;
let Q = []; //Queue
Q.push([0,0]);
visited.add([0,0].toString());
let dr = [-1,1,0,0];
let dc = [0,0,-1,1];
while(Q.length > 0)
let cur = Q.shift();
let row = cur[0];
let col = cur[1];
for(let k=0; k<4; k++)
let newRow = row + dr[k];
let newCol = col + dc[k];
if(!visited.has([newRow,newCol].toString()) && newRow>=0 && newCol >=0 && newRow < rows && newCol < columns && A[newRow][newCol] !== A[row][col])
visited.add([newRow,newCol].toString());
distance[newRow][newCol] = distance[row][col] + 1;
Q.push([newRow,newCol]);
if(distance[rows-1][columns-1] === -1)console.log("Path does not exist");
else console.log(distance[rows-1][columns-1]);
Well you can use grids as graphs without converting them to usual graph adjacency list representation.
So every pair (row,column) is a node,
You can go to next node only if: 2 nodes are neighbors and have different values,
The purpose of adjacency list is to get neighboring nodes efficient, but with grid cells you can just always check all 4 directions and process nodes that exist.
Sample code:
let A = [ [ 'A', 'A', 'A', 'B', 'A' ],
[ 'B', 'B', 'B', 'B', 'B' ],
[ 'A', 'B', 'A', 'A', 'A' ],
[ 'A', 'B', 'B', 'B', 'B' ],
[ 'A', 'A', 'A', 'A', 'A' ] ];
let visited = new Set();
let rows = A.length;
let columns = A[0].length;
let distance = Array(rows).fill().map(() => Array(columns).fill(-1));
distance[0][0]=0;
let Q = []; //Queue
Q.push([0,0]);
visited.add([0,0].toString());
let dr = [-1,1,0,0];
let dc = [0,0,-1,1];
while(Q.length > 0)
let cur = Q.shift();
let row = cur[0];
let col = cur[1];
for(let k=0; k<4; k++)
let newRow = row + dr[k];
let newCol = col + dc[k];
if(!visited.has([newRow,newCol].toString()) && newRow>=0 && newCol >=0 && newRow < rows && newCol < columns && A[newRow][newCol] !== A[row][col])
visited.add([newRow,newCol].toString());
distance[newRow][newCol] = distance[row][col] + 1;
Q.push([newRow,newCol]);
if(distance[rows-1][columns-1] === -1)console.log("Path does not exist");
else console.log(distance[rows-1][columns-1]);
let A = [ [ 'A', 'A', 'A', 'B', 'A' ],
[ 'B', 'B', 'B', 'B', 'B' ],
[ 'A', 'B', 'A', 'A', 'A' ],
[ 'A', 'B', 'B', 'B', 'B' ],
[ 'A', 'A', 'A', 'A', 'A' ] ];
let visited = new Set();
let rows = A.length;
let columns = A[0].length;
let distance = Array(rows).fill().map(() => Array(columns).fill(-1));
distance[0][0]=0;
let Q = []; //Queue
Q.push([0,0]);
visited.add([0,0].toString());
let dr = [-1,1,0,0];
let dc = [0,0,-1,1];
while(Q.length > 0)
let cur = Q.shift();
let row = cur[0];
let col = cur[1];
for(let k=0; k<4; k++)
let newRow = row + dr[k];
let newCol = col + dc[k];
if(!visited.has([newRow,newCol].toString()) && newRow>=0 && newCol >=0 && newRow < rows && newCol < columns && A[newRow][newCol] !== A[row][col])
visited.add([newRow,newCol].toString());
distance[newRow][newCol] = distance[row][col] + 1;
Q.push([newRow,newCol]);
if(distance[rows-1][columns-1] === -1)console.log("Path does not exist");
else console.log(distance[rows-1][columns-1]);
let A = [ [ 'A', 'A', 'A', 'B', 'A' ],
[ 'B', 'B', 'B', 'B', 'B' ],
[ 'A', 'B', 'A', 'A', 'A' ],
[ 'A', 'B', 'B', 'B', 'B' ],
[ 'A', 'A', 'A', 'A', 'A' ] ];
let visited = new Set();
let rows = A.length;
let columns = A[0].length;
let distance = Array(rows).fill().map(() => Array(columns).fill(-1));
distance[0][0]=0;
let Q = []; //Queue
Q.push([0,0]);
visited.add([0,0].toString());
let dr = [-1,1,0,0];
let dc = [0,0,-1,1];
while(Q.length > 0)
let cur = Q.shift();
let row = cur[0];
let col = cur[1];
for(let k=0; k<4; k++)
let newRow = row + dr[k];
let newCol = col + dc[k];
if(!visited.has([newRow,newCol].toString()) && newRow>=0 && newCol >=0 && newRow < rows && newCol < columns && A[newRow][newCol] !== A[row][col])
visited.add([newRow,newCol].toString());
distance[newRow][newCol] = distance[row][col] + 1;
Q.push([newRow,newCol]);
if(distance[rows-1][columns-1] === -1)console.log("Path does not exist");
else console.log(distance[rows-1][columns-1]);
answered Mar 19 at 14:10
PhotonPhoton
794714
794714
add a comment |
add a comment |
One way to solve your problem is to first represent your 2D array as a graph, where each letter is a node, and there exists an edge between two nodes if the letter they represent are neighbor in the array, and these letters are different (one A
and one B
).
Then all you have to do is to use a classical shortest path algorithm, such as Dijkstra's, or A*, to find the shortest path between two nodes of your graph. This will be equivalent to finding the shortest path between two letters of your array.
Edit:
here is a pseudocode to answer the question you asked in the comment.
nodes = init_a_2d_array_of_graph_nodes(ARRAY_WIDTH, ARRAY_HEIGHT)
for i from 1 to ARRAY_WIDTH:
for j from 1 to ARRAY_HEIGHT:
if i < ARRAY_WIDTH and array[i][j] != array[i+1][j]:
add_edge(nodes[i][j], nodes[i+1][j])
if j < ARRAY_HEIGHT and array[i][j] != array[i][j+1]:
add_edge(nodes[i][j], nodes[i][j+1])
First, you need to initialize a graph structure. If you don't know how to do that, check online, there must be plenty of ways to do it, it is rather simple.
Then, you need to create one node for each letter in your array. It is convenient to store these node in a 2D array as well, so you can find out easily which letter of your array corresponds to which node in your graph.
Then, for all neighbor letters, you check if these letters are different (that is what is checked in the 2 if
conditions). If it is the case, you connect the two nodes with an edge.
After that, you'll need to run a shortest path algorithm on your graph, between your source node and destination node. Dijkstra's algorithm is the best way to get started with shortest path algorithm, it is the most widely used, and is fast enough in most of the situations you'll encounter.
Finally, once you have your path, you need to retrieve the index (row and column) of the nodes of your graph, that will give you the corresponding path in your letters array.
Feel free to comment again if there is still something you do not understand.
That is exactly what I am trying to do right now. What I am having trouble with right now, is finding a way to create an adjacency list from the array.
– Boris Grunwald
Mar 19 at 13:24
add a comment |
One way to solve your problem is to first represent your 2D array as a graph, where each letter is a node, and there exists an edge between two nodes if the letter they represent are neighbor in the array, and these letters are different (one A
and one B
).
Then all you have to do is to use a classical shortest path algorithm, such as Dijkstra's, or A*, to find the shortest path between two nodes of your graph. This will be equivalent to finding the shortest path between two letters of your array.
Edit:
here is a pseudocode to answer the question you asked in the comment.
nodes = init_a_2d_array_of_graph_nodes(ARRAY_WIDTH, ARRAY_HEIGHT)
for i from 1 to ARRAY_WIDTH:
for j from 1 to ARRAY_HEIGHT:
if i < ARRAY_WIDTH and array[i][j] != array[i+1][j]:
add_edge(nodes[i][j], nodes[i+1][j])
if j < ARRAY_HEIGHT and array[i][j] != array[i][j+1]:
add_edge(nodes[i][j], nodes[i][j+1])
First, you need to initialize a graph structure. If you don't know how to do that, check online, there must be plenty of ways to do it, it is rather simple.
Then, you need to create one node for each letter in your array. It is convenient to store these node in a 2D array as well, so you can find out easily which letter of your array corresponds to which node in your graph.
Then, for all neighbor letters, you check if these letters are different (that is what is checked in the 2 if
conditions). If it is the case, you connect the two nodes with an edge.
After that, you'll need to run a shortest path algorithm on your graph, between your source node and destination node. Dijkstra's algorithm is the best way to get started with shortest path algorithm, it is the most widely used, and is fast enough in most of the situations you'll encounter.
Finally, once you have your path, you need to retrieve the index (row and column) of the nodes of your graph, that will give you the corresponding path in your letters array.
Feel free to comment again if there is still something you do not understand.
That is exactly what I am trying to do right now. What I am having trouble with right now, is finding a way to create an adjacency list from the array.
– Boris Grunwald
Mar 19 at 13:24
add a comment |
One way to solve your problem is to first represent your 2D array as a graph, where each letter is a node, and there exists an edge between two nodes if the letter they represent are neighbor in the array, and these letters are different (one A
and one B
).
Then all you have to do is to use a classical shortest path algorithm, such as Dijkstra's, or A*, to find the shortest path between two nodes of your graph. This will be equivalent to finding the shortest path between two letters of your array.
Edit:
here is a pseudocode to answer the question you asked in the comment.
nodes = init_a_2d_array_of_graph_nodes(ARRAY_WIDTH, ARRAY_HEIGHT)
for i from 1 to ARRAY_WIDTH:
for j from 1 to ARRAY_HEIGHT:
if i < ARRAY_WIDTH and array[i][j] != array[i+1][j]:
add_edge(nodes[i][j], nodes[i+1][j])
if j < ARRAY_HEIGHT and array[i][j] != array[i][j+1]:
add_edge(nodes[i][j], nodes[i][j+1])
First, you need to initialize a graph structure. If you don't know how to do that, check online, there must be plenty of ways to do it, it is rather simple.
Then, you need to create one node for each letter in your array. It is convenient to store these node in a 2D array as well, so you can find out easily which letter of your array corresponds to which node in your graph.
Then, for all neighbor letters, you check if these letters are different (that is what is checked in the 2 if
conditions). If it is the case, you connect the two nodes with an edge.
After that, you'll need to run a shortest path algorithm on your graph, between your source node and destination node. Dijkstra's algorithm is the best way to get started with shortest path algorithm, it is the most widely used, and is fast enough in most of the situations you'll encounter.
Finally, once you have your path, you need to retrieve the index (row and column) of the nodes of your graph, that will give you the corresponding path in your letters array.
Feel free to comment again if there is still something you do not understand.
One way to solve your problem is to first represent your 2D array as a graph, where each letter is a node, and there exists an edge between two nodes if the letter they represent are neighbor in the array, and these letters are different (one A
and one B
).
Then all you have to do is to use a classical shortest path algorithm, such as Dijkstra's, or A*, to find the shortest path between two nodes of your graph. This will be equivalent to finding the shortest path between two letters of your array.
Edit:
here is a pseudocode to answer the question you asked in the comment.
nodes = init_a_2d_array_of_graph_nodes(ARRAY_WIDTH, ARRAY_HEIGHT)
for i from 1 to ARRAY_WIDTH:
for j from 1 to ARRAY_HEIGHT:
if i < ARRAY_WIDTH and array[i][j] != array[i+1][j]:
add_edge(nodes[i][j], nodes[i+1][j])
if j < ARRAY_HEIGHT and array[i][j] != array[i][j+1]:
add_edge(nodes[i][j], nodes[i][j+1])
First, you need to initialize a graph structure. If you don't know how to do that, check online, there must be plenty of ways to do it, it is rather simple.
Then, you need to create one node for each letter in your array. It is convenient to store these node in a 2D array as well, so you can find out easily which letter of your array corresponds to which node in your graph.
Then, for all neighbor letters, you check if these letters are different (that is what is checked in the 2 if
conditions). If it is the case, you connect the two nodes with an edge.
After that, you'll need to run a shortest path algorithm on your graph, between your source node and destination node. Dijkstra's algorithm is the best way to get started with shortest path algorithm, it is the most widely used, and is fast enough in most of the situations you'll encounter.
Finally, once you have your path, you need to retrieve the index (row and column) of the nodes of your graph, that will give you the corresponding path in your letters array.
Feel free to comment again if there is still something you do not understand.
edited Mar 19 at 15:15
answered Mar 19 at 12:58
m.raynalm.raynal
1,002717
1,002717
That is exactly what I am trying to do right now. What I am having trouble with right now, is finding a way to create an adjacency list from the array.
– Boris Grunwald
Mar 19 at 13:24
add a comment |
That is exactly what I am trying to do right now. What I am having trouble with right now, is finding a way to create an adjacency list from the array.
– Boris Grunwald
Mar 19 at 13:24
That is exactly what I am trying to do right now. What I am having trouble with right now, is finding a way to create an adjacency list from the array.
– Boris Grunwald
Mar 19 at 13:24
That is exactly what I am trying to do right now. What I am having trouble with right now, is finding a way to create an adjacency list from the array.
– Boris Grunwald
Mar 19 at 13:24
add a comment |
Does anyone know of a simple Graph implementation that can help me solve this problem?
The Dijkstra algortihm is used to find the shortest path between two nodes. Every position in your two-dimensional array represents a node, the edges are dynamically derived from the surrounding nodes that fulfill your "alternating" rule.
You can further optimise it for your use case with bidirectional search and a goal metric (A*).
IMO it would be simpler (and in any opinion - asymptotically faster) to use BFS for undirected non-weighted graphs.
– akurtser
Mar 19 at 15:34
add a comment |
Does anyone know of a simple Graph implementation that can help me solve this problem?
The Dijkstra algortihm is used to find the shortest path between two nodes. Every position in your two-dimensional array represents a node, the edges are dynamically derived from the surrounding nodes that fulfill your "alternating" rule.
You can further optimise it for your use case with bidirectional search and a goal metric (A*).
IMO it would be simpler (and in any opinion - asymptotically faster) to use BFS for undirected non-weighted graphs.
– akurtser
Mar 19 at 15:34
add a comment |
Does anyone know of a simple Graph implementation that can help me solve this problem?
The Dijkstra algortihm is used to find the shortest path between two nodes. Every position in your two-dimensional array represents a node, the edges are dynamically derived from the surrounding nodes that fulfill your "alternating" rule.
You can further optimise it for your use case with bidirectional search and a goal metric (A*).
Does anyone know of a simple Graph implementation that can help me solve this problem?
The Dijkstra algortihm is used to find the shortest path between two nodes. Every position in your two-dimensional array represents a node, the edges are dynamically derived from the surrounding nodes that fulfill your "alternating" rule.
You can further optimise it for your use case with bidirectional search and a goal metric (A*).
answered Mar 19 at 14:28
BergiBergi
383k64591922
383k64591922
IMO it would be simpler (and in any opinion - asymptotically faster) to use BFS for undirected non-weighted graphs.
– akurtser
Mar 19 at 15:34
add a comment |
IMO it would be simpler (and in any opinion - asymptotically faster) to use BFS for undirected non-weighted graphs.
– akurtser
Mar 19 at 15:34
IMO it would be simpler (and in any opinion - asymptotically faster) to use BFS for undirected non-weighted graphs.
– akurtser
Mar 19 at 15:34
IMO it would be simpler (and in any opinion - asymptotically faster) to use BFS for undirected non-weighted graphs.
– akurtser
Mar 19 at 15:34
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55239386%2ffinding-shortest-path-in-two-dimensional-array-javascript%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Shortest path from and to?
– nick zoum
Mar 19 at 11:01
Whats is each value in the Array? Can you provide an sample output you are expecting from the provided data.
– Dipak
Mar 19 at 11:01
Can you give more inputs to your problem statement
– Kartikeya Sharma
Mar 19 at 11:01
Sorry, it is from the top left corner to the right bottom corner
– Boris Grunwald
Mar 19 at 11:02
I've updated the question, please let me know if you need more information
– Boris Grunwald
Mar 19 at 11:04