0

I know this has been asked before but I can't seem to figure out the solution from the examples and translate them to javascript. not even when following : https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm

I have an unweighted graph or 2d array for example that looks like this:

const testMatrix = [
  [0, 0, 0, 0],
  [0, 0, 0, 0],
  [0, 1, 0, 0],
  [0, 1, 0, 0]
];

I then Traverse that using BFS: (i currently hardCoded the item to find as element 2,2 in the array). And return the seen list item list. but I can't figure out how the seen list supposes to show the way to the shortest path.


const traversalBFS = function(matrix) {
  counter = 0;
  const seen = 
    new Array(matrix.length).fill(0).map(() => new Array(matrix[0].length).fill(false));

  const values = [];
  const queue = [[0, 0]];

  while(queue.length) {
    const currentPos = queue.shift();
    const row = currentPos[0];
    const col = currentPos[1];
    
    if(row < 0 || row >= matrix.length || col < 0 || col >= matrix[0].length || seen[row][col] || matrix[row][col] === 1) {
      continue;
    }

 

    counter++;
    seen[row][col] = true;
    values.push(matrix[row][col]);
     if(row === 2 && col === 2) {
        return seen;
    }
    
    for(let i = 0; i < directions.length; i++) {
      const currentDir = directions[i];
      queue.push([row + currentDir[0], col + currentDir[1]]);
    }
  }

  return false;
}

even if I run this code

temp = traversalBFS(testMatrix);
let path = [];
for(i = 0; i <= 2; i++) {
  for(j = 0; j <= 2; j++) {
       if(temp[i][j]) {
          path.push([i, j]);
       }
  }
}

it will return:

0: (2) [0, 0]
1: (2) [0, 1]
2: (2) [0, 2]
3: (2) [1, 0]
4: (2) [1, 1]
5: (2) [1, 2]
6: (2) [2, 0]
7: (2) [2, 2]

which is not a correct path in any way, and also not the shortest path.

expected result example: hmmm lets say end point will be 1,1 and start will be 0, 0 the expected result is an array with the shortest path:

[[0,0], [0, 1], [1,1]]

if the start point is 0, 0 and the end point is 2,2: I think the result should be:

[[0,0], [0, 1], [1,1],[1,2],[2,2];

using the test matrix I wrote as an example. as there are no 1 aka walls in the way.

Shaked Tayeb
  • 112
  • 9
  • do you have an example of the wanted result? – Nina Scholz Apr 18 '21 at 16:16
  • hmmm lets say end point will be 1,1 and start will be 0, 0 the expected result is an array with the shortest path: ``` [[0,0], [0, 1], [1,1]] ``` if the start point is 0, 0 and the end point is 2,2: i think the result should be: ``` [[0,0], [0, 1], [1,1],[1,2],[2,2]; ``` using the test matrix i wrote as an example. as there are no 1 aka walls in the way. – Shaked Tayeb Apr 18 '21 at 16:27

1 Answers1

0

For getting an ide how Dijkstra's algorithm work, you could take the approach of the given link and take a large value for a start and take smaller values as soon as the neighbours have them.

This example uses (step) values instead of indices, but it could be replaced by the coordinates of the path to the target.

This approach uses obstacle avoidance and a short cicuit if the target is found.

const
    travel = (array, from, to) => {
        const
            go = (i, j, smallest) => {
                if (array[i]?.[j] === 1) return;
                if (i === to[0] && j === to[1]) return;
                if (unvisited[i]?.[j] > smallest) {
                    unvisited[i][j] = smallest;
                    go(i + 1, j, smallest + 1);
                    go(i - 1, j, smallest + 1);
                    go(i, j + 1, smallest + 1);
                    go(i, j - 1, smallest + 1);
                }
            },
            unvisited = testMatrix.map(a => a.map(_ => Number.MAX_VALUE));

        go(from[0], from[1], 0);
        return unvisited;
    },
    testMatrix = [[0, 0, 0, 0], [0, 0, 0, 0], [0, 1, 0, 0], [0, 1, 0, 0]],
    result = travel(testMatrix, [0, 0], [3, 2]);

result.forEach(a => console.log(a.map(v => v === Number.MAX_VALUE ?'*': v).join(' ')));
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392