From 6fd8c3cb9bf4c36bfb3d3b36a60ea3d9671fdacd Mon Sep 17 00:00:00 2001 From: lumunge Date: Tue, 1 Feb 2022 13:21:37 +0300 Subject: [PATCH 1/7] correcting typing error --- code/dfs-visual.html | 4 ++-- code/dijkstra-visual.html | 4 ++-- code/index.html | 4 ++-- code/islands-visual.html | 4 ++-- code/max-Island-visual.html | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/code/dfs-visual.html b/code/dfs-visual.html index 28da8d2..9da6860 100644 --- a/code/dfs-visual.html +++ b/code/dfs-visual.html @@ -15,7 +15,7 @@ - + @@ -25,7 +25,7 @@ - + diff --git a/code/dijkstra-visual.html b/code/dijkstra-visual.html index 19caa80..57959cb 100644 --- a/code/dijkstra-visual.html +++ b/code/dijkstra-visual.html @@ -15,7 +15,7 @@ - + @@ -26,7 +26,7 @@ - + diff --git a/code/index.html b/code/index.html index a59dff3..437bdbf 100644 --- a/code/index.html +++ b/code/index.html @@ -15,7 +15,7 @@ - + @@ -25,7 +25,7 @@ - + diff --git a/code/islands-visual.html b/code/islands-visual.html index 81a24eb..cded7c4 100644 --- a/code/islands-visual.html +++ b/code/islands-visual.html @@ -15,7 +15,7 @@ - + @@ -25,7 +25,7 @@ - + diff --git a/code/max-Island-visual.html b/code/max-Island-visual.html index eddb9a3..a0243ea 100644 --- a/code/max-Island-visual.html +++ b/code/max-Island-visual.html @@ -15,7 +15,7 @@ - + @@ -26,7 +26,7 @@ - + From b7237c5d93636a6c2e9f6952c8e81c86b2204757 Mon Sep 17 00:00:00 2001 From: lumunge Date: Tue, 1 Feb 2022 13:22:52 +0300 Subject: [PATCH 2/7] finding all paths from source to destination makrup --- code/find-paths.html | 250 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 250 insertions(+) create mode 100644 code/find-paths.html diff --git a/code/find-paths.html b/code/find-paths.html new file mode 100644 index 0000000..81b62cd --- /dev/null +++ b/code/find-paths.html @@ -0,0 +1,250 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Finding all paths between two vertices in a graph. + + + + +
+
+

Find all paths between two vertices - dpeth first search visualization

+
+
+
+
+

Speed

+ +
+
+

Obstacles

+
+ +   + +
+
+
+ + + + + +
+
+ +
+

Controls

+

Speed - increase or decrease the speed of the visualization

+

Obstacles- - create walls/obstacles, on a map these can be buildings or + structures which hinder a path. You can adjust the number of obstacles generated per click. +
- You can also click on the grid cells to create + obstacles. +

+

Start - After adjusting the speed and creating obstacles, you can now start the + visualization to see the workings of the algorithm.

+

Manual - After running the visualization normally you can run it manually to see + how the shortest path was obtained. After the click you can proceed with pressing enter key. +

+

Clear Path - After visualizing, you may opt to clear the path and add more + obstacles.

+

Speed - If the grid becomes to cluttered you can reload it and repeat the above + steps.

+
+
+
+ +
+ + +
+
+
+
+
+
+
+
+
+
  +
This is an empty path without any walls, you can click is to add obstacles/walls.
+
+
+
A
  +
Start Node -> this is the starting point(source), + search for a path starts here.
+
+
+
B
  +
End Node -> where the search stops when a path to destination has been found
+
+
+
  +
These act as obstacles, walls. On a real map these may be buildings or structures that may + block + a shorter path to a destination.
+
+
+
7
  +
After the algorithm is complete, we have arrived at the destination, now the shortest path is + highlighted in green with the cost of path written written in black inside the path.
+
+
+
+
+
+

Depth first traversal.

+
+
+

+ This algorithm starts its search at the root and + explores one of its children's subtree and then moves + on to the next child's subtree and etcetera
+ The idea used is to go as deep into the graph as + possible and backtrack once we reach a vertex with + unvisited neighbors.
+ That is, start search at one vertex, after visiting + the vertex, perform dfs for each unvisited adjacent + vertex. In this way we visit all vertices reachable + from the starting vertex.
+ We use a stack data structure. +

+
+
+

Algorithm

+

+ 1. Mark the current node as visited(initially + current node is the root node). +

+

+ 2. Check if current node is the end node, If so, + then return it. +

+

+ 3. Iterate over children nodes of current node, + and do the following: +

+

+ 1. Check if a child node is not visited. +

+

+ 2.If so, then, mark it as visited. +

+

+ 3. Go to it's sub graph recursively until you + find the end node(In other words, do the same + steps here passing the child node as the current + node in the next recursive call). +

+

+ 4. If the child node has the end node in this + sub graph, then, return it. +

+

+ 4. If end node is not found, then end node is + not in the graph! +

+
+
+

Computational complexity

+ This algorithm takes O(V + E) where v is the number of + vertices and e is the number of edges. +
+
+

Applications

+
    +
  • topological sorting.
  • +
  • bipartite graph testing.
  • +
  • finding strongly connected components.
  • +
  • + solving puzzles that can only have one + solution. +
  • +
  • detecting cycles in a graph.
  • +
+
+
+

References

+ dfs +
+
+
+
+
+ + + + + + \ No newline at end of file From b3b10f984ceccb0f0205c7fd8d9506bb3587c516 Mon Sep 17 00:00:00 2001 From: lumunge Date: Wed, 2 Feb 2022 01:34:26 +0300 Subject: [PATCH 3/7] find paths button --- code/find-paths.html | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/code/find-paths.html b/code/find-paths.html index 81b62cd..058fbf8 100644 --- a/code/find-paths.html +++ b/code/find-paths.html @@ -12,7 +12,7 @@ - + @@ -61,7 +61,7 @@
-

Find all paths between two vertices - dpeth first search visualization

+

Find all paths between two vertices - dpeth first search visualization

@@ -79,6 +79,7 @@

Find all paths between two vertices - dpeth first sear

+ From 3084f40b9facb148cb992ea9a68a498821b78611 Mon Sep 17 00:00:00 2001 From: lumunge Date: Wed, 2 Feb 2022 01:34:44 +0300 Subject: [PATCH 4/7] find paths function --- code/assets/js/visual/Grid/index.js | 498 +++++++++++++++------------- 1 file changed, 263 insertions(+), 235 deletions(-) diff --git a/code/assets/js/visual/Grid/index.js b/code/assets/js/visual/Grid/index.js index a0bd844..844b52a 100644 --- a/code/assets/js/visual/Grid/index.js +++ b/code/assets/js/visual/Grid/index.js @@ -1,10 +1,10 @@ import { - createEmptyBoard, - createBoard, - createStartNode, - createEndNode, - refreshBoard, - refreshEmptyBoard, + createEmptyBoard, + createBoard, + createStartNode, + createEndNode, + refreshBoard, + refreshEmptyBoard, } from "./createGrid.js"; import { setWall } from "./createWalls.js"; import { setObstacles } from "./generateObstacles.js"; @@ -13,10 +13,11 @@ import { bfs } from "../PathFindingAlgorithms/bfs.js"; import { bfsIslands } from "../Islands/bfsIslands.js"; import { dfsIslands } from "../Islands/dfsIslands.js"; import { maxIsland } from "../Islands/largeIsland.js"; +import { findPaths } from "../PathFindingAlgorithms/findPaths.js"; import { - bellmanFord, - relaxations, - bellmanStepsLength, + bellmanFord, + relaxations, + bellmanStepsLength, } from "../PathFindingAlgorithms/bellmanFord.js"; // get dom elements @@ -26,6 +27,7 @@ export const resetBtn = document.querySelector(".reset"); const weightBtn = document.querySelector(".weight"); const algoBtn = document.querySelector(".algo"); export const startBtn = document.querySelector(".start"); +const findNextPath = document.querySelector(".findNext"); export const wallBtn = document.querySelector(".setWalls"); export const speedSlider = document.querySelector(".speedSlider"); const islandAlgoBtn = document.querySelector(".islandsAlgo"); @@ -45,7 +47,7 @@ export var mouseDown = false; export var weightType = weightBtn.options[weightBtn.selectedIndex].value; export var algorithm = algoBtn.options[algoBtn.selectedIndex].value; export var islandAlgo = - islandAlgoBtn.options[islandAlgoBtn.selectedIndex].value; + islandAlgoBtn.options[islandAlgoBtn.selectedIndex].value; //steps arrays export let bfsSteps = []; @@ -53,42 +55,44 @@ export let dfsSteps = []; export let bellmanSteps = []; export let dijkstrasPath = []; export let bellmanFordPath = []; +export let visitedPaths = []; //event listeners gridContainer.addEventListener("mousedown", () => { - mouseDown = true; + mouseDown = true; }); gridContainer.addEventListener("mouseup", () => { - mouseDown = false; + mouseDown = false; }); gridContainer.addEventListener("mouseover", () => { - setWall; + setWall; }); wallBtn.addEventListener("click", setObstacles); islandAlgoBtn.addEventListener("change", () => { - window.location.reload(); + window.location.reload(); }); //clear path after traversal export const clearPath = () => { - gridContainer.addEventListener("mousedown", setWall); - gridContainer.addEventListener("mouseup", setWall); - gridContainer.addEventListener("mouseover", setWall); - if ( - algorithmType.classList.contains("bfs") || - algorithmType.classList.contains("dfs") || - algorithmType.classList.contains("numIslands") || - algorithmType.classList.contains("maxIsland") - ) { - refreshEmptyBoard(); - } else if ( - algorithmType.classList.contains("dijkstras") || - algorithmType.classList.contains("bellman-ford") - ) { - refreshBoard(); - } - startBtn.style.visibility = "visible"; + gridContainer.addEventListener("mousedown", setWall); + gridContainer.addEventListener("mouseup", setWall); + gridContainer.addEventListener("mouseover", setWall); + if ( + algorithmType.classList.contains("bfs") || + algorithmType.classList.contains("dfs") || + algorithmType.classList.contains("numIslands") || + algorithmType.classList.contains("maxIsland") || + algorithmType.classList.contains("findPaths") + ) { + refreshEmptyBoard(); + } else if ( + algorithmType.classList.contains("dijkstras") || + algorithmType.classList.contains("bellman-ford") + ) { + refreshBoard(); + } + startBtn.style.visibility = "visible"; }; resetBtn.addEventListener("click", () => location.reload()); @@ -102,223 +106,247 @@ stepsContainer.append(stepsTitle); //log steps for algorithm export const notification = (row, col, erow, ecol, cost, prevCost) => { - var step = document.createElement("div"); - step.classList.add("step"); - var push = document.createElement("p"); - var explore = document.createElement("p"); - var costText = document.createElement("p"); - if (algorithmType.classList.contains("bellman-ford")) { - if (bellmanSteps.length == 0) { - push.textContent = `Selected (${row}, ${col}) as path.`; - } else { - if ( - bellmanSteps.length <= - bellmanStepsLength - bellmanStepsLength / relaxations - ) { - push.textContent = `Relaxing (${row}, ${col}): current cost ${prevCost}, updated cost ${ - cost || "inf" - }.`; - explore.textContent = `Processing (${erow}, ${ecol}).`; - } else { - push.textContent = `Pushed (${row}, ${col}) to dist[] array.`; - explore.textContent = `Exploring (${erow}, ${ecol}).`; - } - } - } else if ( - algorithmType.classList.contains("dijkstras") || - algorithmType.classList.contains("bfs") - ) { - if (bfsSteps.length == 0) { - push.textContent = `Selected (${row}, ${col}) as path.`; - } else { - push.textContent = `Pushed (${row}, ${col}) to array.`; - explore.textContent = `Processing (${erow}, ${ecol}).`; - costText.textContent = `Cost from source is ${cost}`; - } - } else if (algorithmType.classList.contains("dfs")) { - if (row == erow && col == ecol) { - push.textContent = `Pushed (${erow}, ${ecol}) to stack.`; - explore.textContent = `Exploring (${erow}, ${ecol}).`; - } else { - push.textContent = `Popped (${row}, ${col}) from stack.`; - } - } - step.appendChild(push); - step.appendChild(explore); - step.appendChild(costText); - stepsContainer.append(step); - stepsContainer.scrollTop = stepsContainer.scrollHeight; + var step = document.createElement("div"); + step.classList.add("step"); + var push = document.createElement("p"); + var explore = document.createElement("p"); + var costText = document.createElement("p"); + if (algorithmType.classList.contains("bellman-ford")) { + if (bellmanSteps.length == 0) { + push.textContent = `Selected (${row}, ${col}) as path.`; + } else { + if ( + bellmanSteps.length <= + bellmanStepsLength - bellmanStepsLength / relaxations + ) { + push.textContent = `Relaxing (${row}, ${col}): current cost ${prevCost}, updated cost ${ + cost || "inf" + }.`; + explore.textContent = `Processing (${erow}, ${ecol}).`; + } else { + push.textContent = `Pushed (${row}, ${col}) to dist[] array.`; + explore.textContent = `Exploring (${erow}, ${ecol}).`; + } + } + } else if ( + algorithmType.classList.contains("dijkstras") || + algorithmType.classList.contains("bfs") || + algorithmType.classList.contains("findPaths") + ) { + if (bfsSteps.length == 0) { + push.textContent = `Selected (${row}, ${col}) as path.`; + } else { + push.textContent = `Pushed (${row}, ${col}) to array.`; + explore.textContent = `Processing (${erow}, ${ecol}).`; + costText.textContent = `Cost from source is ${cost}`; + } + } else if (algorithmType.classList.contains("dfs")) { + if (row == erow && col == ecol) { + push.textContent = `Pushed (${erow}, ${ecol}) to stack.`; + explore.textContent = `Exploring (${erow}, ${ecol}).`; + } else { + push.textContent = `Popped (${row}, ${col}) from stack.`; + } + } + step.appendChild(push); + step.appendChild(explore); + step.appendChild(costText); + stepsContainer.append(step); + stepsContainer.scrollTop = stepsContainer.scrollHeight; - step.addEventListener("click", () => { - let node = document.querySelector(`div[row='${row}'][col='${col}']`); - let node1 = document.querySelector(`div[row='${erow}'][col='${ecol}']`); - setTimeout(() => { - node.setAttribute("class", "pathColor"); - node1.setAttribute("class", "pathColor"); - }, 1000); - node1.setAttribute("class", "manualStep"); - node.setAttribute("class", "chosenPath"); - }); + step.addEventListener("click", () => { + let node = document.querySelector(`div[row='${row}'][col='${col}']`); + let node1 = document.querySelector(`div[row='${erow}'][col='${ecol}']`); + setTimeout(() => { + node.setAttribute("class", "pathColor"); + node1.setAttribute("class", "pathColor"); + }, 1000); + node1.setAttribute("class", "manualStep"); + node.setAttribute("class", "chosenPath"); + }); }; // step by step visualization let isPath = true; export const stepper = (steps) => { - gridContainer.removeEventListener("mousedown", setWall); - gridContainer.removeEventListener("mouseover", setWall); - // wallBtn.setAttribute("disabled", true); - if (isPath) { - clearPath(); - bellmanFordPath.splice( - 0, - bellmanFordPath.length - bellmanFordPath.length / 5 - ); - startBtn.setAttribute("disabled", "true"); - clearPathBtn.setAttribute("disabled", "true"); - stepsContainer.classList.remove("notification"); - stepsContainer.classList.add("show"); - wallBtn.setAttribute("disabled", "true"); - isPath = false; - } - if (steps.length == 0) { - if ( - algorithmType.classList.contains("dijkstras") || - algorithmType.classList.contains("bfs") - ) { - if (dijkstrasPath.length == 0) { - alert("Steps completed!"); - } else { - //draw path - var pcol = dijkstrasPath[0][0]; - var prow = dijkstrasPath[0][1]; - setTimeout(() => { - node.setAttribute("class", "pathColor"); - }, 1000); - node.setAttribute("class", "chosenPath"); - notification(pcol, prow, 0, 0); - dijkstrasPath.shift(); - } - } else if (algorithmType.classList.contains("bellman-ford")) { - if (bellmanFordPath.length == 0) { - alert("Bellman ford steps completed!"); - } else { - //draw path - var pcol = bellmanFordPath[0][0]; - var prow = bellmanFordPath[0][1]; - let node = document.querySelector( - `div[row='${pcol}'][col='${prow}']` - ); - node.setAttribute("class", "chosenPath"); - notification(pcol, prow, 0, 0); - bellmanFordPath.shift(); - } - } else { - alert("Completed Steps"); - } - } else { - var cr = steps[0][0]; - var cc = steps[0][1]; - var cost = steps[0][2]; - var er = steps[0][3]; - var ec = steps[0][4]; - let node = document.querySelector(`div[row='${cr}'][col='${cc}']`); - setTimeout(() => { - node.setAttribute("class", "pathColor"); - }, 1000); - node.setAttribute("class", "chosenPath"); - //relaxation for bellman ford nodes - let prevCost = node.innerHTML; - node.innerHTML = cost || "inf"; - notification(cr, cc, er, ec, cost, prevCost); - steps.shift(); - } + gridContainer.removeEventListener("mousedown", setWall); + gridContainer.removeEventListener("mouseover", setWall); + // wallBtn.setAttribute("disabled", true); + if (isPath) { + clearPath(); + bellmanFordPath.splice( + 0, + bellmanFordPath.length - bellmanFordPath.length / 5 + ); + startBtn.setAttribute("disabled", "true"); + clearPathBtn.setAttribute("disabled", "true"); + stepsContainer.classList.remove("notification"); + stepsContainer.classList.add("show"); + wallBtn.setAttribute("disabled", "true"); + isPath = false; + } + if (steps.length == 0) { + if ( + algorithmType.classList.contains("dijkstras") || + algorithmType.classList.contains("bfs") + ) { + if (dijkstrasPath.length == 0) { + alert("Steps completed!"); + } else { + //draw path + var pcol = dijkstrasPath[0][0]; + var prow = dijkstrasPath[0][1]; + setTimeout(() => { + node.setAttribute("class", "pathColor"); + }, 1000); + node.setAttribute("class", "chosenPath"); + notification(pcol, prow, 0, 0); + dijkstrasPath.shift(); + } + } else if (algorithmType.classList.contains("bellman-ford")) { + if (bellmanFordPath.length == 0) { + alert("Bellman ford steps completed!"); + } else { + //draw path + var pcol = bellmanFordPath[0][0]; + var prow = bellmanFordPath[0][1]; + let node = document.querySelector(`div[row='${pcol}'][col='${prow}']`); + node.setAttribute("class", "chosenPath"); + notification(pcol, prow, 0, 0); + bellmanFordPath.shift(); + } + } else { + alert("Completed Steps"); + } + } else { + var cr = steps[0][0]; + var cc = steps[0][1]; + var cost = steps[0][2]; + var er = steps[0][3]; + var ec = steps[0][4]; + let node = document.querySelector(`div[row='${cr}'][col='${cc}']`); + setTimeout(() => { + node.setAttribute("class", "pathColor"); + }, 1000); + node.setAttribute("class", "chosenPath"); + //relaxation for bellman ford nodes + let prevCost = node.innerHTML; + node.innerHTML = cost || "inf"; + notification(cr, cc, er, ec, cost, prevCost); + steps.shift(); + } +}; + +const findNextPathFunc = (nodes) => { + let startNextRow = nodes.slice(-1)[0][0]; + let startNextCol = nodes.slice(-1)[0][1]; + let node = document.querySelector( + `div[row='${startNextRow}'][col='${startNextCol}']` + ); + dfs(startRow, startCol, endRow, endCol); + nodes.pop(); + clearPath(); + if (parseInt(node.getAttribute("wall")) == 0) { + node.setAttribute("wall", 1); + } }; //run normal visualization const startVisualization = () => { - if (algorithmType.classList.contains("bfs")) { - bfs(startRow, startCol, endRow, endCol); - manualStart.addEventListener("click", () => { - stepper(bfsSteps); - }); - } else if (algorithmType.classList.contains("dfs")) { - dfs(startRow, startCol, endRow, endCol); - manualStart.addEventListener("click", () => { - stepper(dfsSteps); - }); - } else if (algorithmType.classList.contains("dijkstras")) { - bfs(startRow, startCol, endRow, endCol); - manualStart.addEventListener("click", () => { - stepper(bfsSteps); - }); - } else if (algorithmType.classList.contains("bellman-ford")) { - bellmanFord(startRow, startCol, endRow, endCol); - manualStart.addEventListener("click", () => { - stepper(bellmanSteps); - }); - } else if (algorithmType.classList.contains("numIslands")) { - if (islandAlgo === "bfs") { - bfsIslands(); - } else if (islandAlgo === "dfs") { - dfsIslands(); - } - } else if (algorithmType.classList.contains("maxIsland")) { - maxIsland(); - } + if (algorithmType.classList.contains("bfs")) { + bfs(startRow, startCol, endRow, endCol); + manualStart.addEventListener("click", () => { + stepper(bfsSteps); + }); + } else if (algorithmType.classList.contains("dfs")) { + dfs(startRow, startCol, endRow, endCol); + manualStart.addEventListener("click", () => { + stepper(dfsSteps); + }); + } else if (algorithmType.classList.contains("dijkstras")) { + bfs(startRow, startCol, endRow, endCol); + manualStart.addEventListener("click", () => { + stepper(bfsSteps); + }); + } else if (algorithmType.classList.contains("bellman-ford")) { + bellmanFord(startRow, startCol, endRow, endCol); + manualStart.addEventListener("click", () => { + stepper(bellmanSteps); + }); + } else if (algorithmType.classList.contains("numIslands")) { + if (islandAlgo === "bfs") { + bfsIslands(); + } else if (islandAlgo === "dfs") { + dfsIslands(); + } + } else if (algorithmType.classList.contains("maxIsland")) { + maxIsland(); + } else if (algorithmType.classList.contains("findPaths")) { + findPaths(startRow, startCol, endRow, endCol); + findNextPath.addEventListener("click", () => { + findNextPathFunc(visitedPaths); + }); + manualStart.addEventListener("click", () => { + stepper(dfsSteps); + }); + } }; startBtn.addEventListener("click", startVisualization); +// findNextPath.addEventListener("click"); //Initialize board window.onload = () => { - gridContainer.addEventListener("mousedown", setWall); - gridContainer.addEventListener("mouseup", setWall); - gridContainer.addEventListener("mouseover", setWall); - if ( - algorithmType.classList.contains("bfs") || - algorithmType.classList.contains("dfs") || - algorithmType.classList.contains("numIslands") || - algorithmType.classList.contains("maxIsland") - ) { - createEmptyBoard(); - } else if ( - algorithmType.classList.contains("dijkstras") || - algorithmType.classList.contains("bellman-ford") - ) { - createBoard(); - } - if ( - algorithmType.classList.contains("bfs") || - algorithmType.classList.contains("dfs") || - algorithmType.classList.contains("dijkstras") || - algorithmType.classList.contains("bellman-ford") - ) { - createStartNode(startRow, startCol); - createEndNode(endRow, endCol); - } else if ( - algorithmType.classList.contains("numIslands") || - algorithmType.classList.contains("maxIslands") - ) { - if (islandAlgo === "bfs") { - createStartNode(0, 0); - createEndNode(19, 39); - document - .querySelector(`div[row='${0}'][col='${0}']`) - .classList.add("islandsPathNode"); - document - .querySelector(`div[row='${19}'][col='${39}']`) - .classList.add("islandsPathNode"); - } else if ( - islandAlgo === "dfs" || - algorithmType.classList.contains("maxIslands") - ) { - createStartNode(0, 0); - createEndNode(0, 1); - document - .querySelector(`div[row='${0}'][col='${0}']`) - .classList.add("islandsPathNode"); - document - .querySelector(`div[row='${0}'][col='${1}']`) - .classList.add("islandsPathNode"); - } - } + gridContainer.addEventListener("mousedown", setWall); + gridContainer.addEventListener("mouseup", setWall); + gridContainer.addEventListener("mouseover", setWall); + if ( + algorithmType.classList.contains("bfs") || + algorithmType.classList.contains("dfs") || + algorithmType.classList.contains("numIslands") || + algorithmType.classList.contains("maxIsland") || + algorithmType.classList.contains("findPaths") + ) { + createEmptyBoard(); + } else if ( + algorithmType.classList.contains("dijkstras") || + algorithmType.classList.contains("bellman-ford") + ) { + createBoard(); + } + if ( + algorithmType.classList.contains("bfs") || + algorithmType.classList.contains("dfs") || + algorithmType.classList.contains("dijkstras") || + algorithmType.classList.contains("bellman-ford") || + algorithmType.classList.contains("findPaths") + ) { + createStartNode(startRow, startCol); + createEndNode(endRow, endCol); + } else if ( + algorithmType.classList.contains("numIslands") || + algorithmType.classList.contains("maxIslands") + ) { + if (islandAlgo === "bfs") { + createStartNode(0, 0); + createEndNode(19, 39); + document + .querySelector(`div[row='${0}'][col='${0}']`) + .classList.add("islandsPathNode"); + document + .querySelector(`div[row='${19}'][col='${39}']`) + .classList.add("islandsPathNode"); + } else if ( + islandAlgo === "dfs" || + algorithmType.classList.contains("maxIslands") + ) { + createStartNode(0, 0); + createEndNode(0, 1); + document + .querySelector(`div[row='${0}'][col='${0}']`) + .classList.add("islandsPathNode"); + document + .querySelector(`div[row='${0}'][col='${1}']`) + .classList.add("islandsPathNode"); + } + } }; From 06af26cd86c9decb2aa04be42f80825e2b3c4408 Mon Sep 17 00:00:00 2001 From: lumunge Date: Wed, 2 Feb 2022 01:35:40 +0300 Subject: [PATCH 5/7] find paths algorithm --- .../visual/PathFindingAlgorithms/findPaths.js | 139 ++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 code/assets/js/visual/PathFindingAlgorithms/findPaths.js diff --git a/code/assets/js/visual/PathFindingAlgorithms/findPaths.js b/code/assets/js/visual/PathFindingAlgorithms/findPaths.js new file mode 100644 index 0000000..c4d1501 --- /dev/null +++ b/code/assets/js/visual/PathFindingAlgorithms/findPaths.js @@ -0,0 +1,139 @@ +import { setWall } from "../Grid/createWalls.js"; +import { + rowSize, + colSize, + manualStart, + dfsSteps, + visitedPaths, + startBtn, + clearPathBtn, + wallBtn, + gridContainer, +} from "../Grid/index.js"; + +let speedSlider = document.querySelector(".speedSlider"); +let time = speedSlider.value; +let bool = false; +let count = 1; + +//check edge cases +const checker = (row, col) => { + if (row >= 0 && col >= 0 && row < rowSize && col < colSize) return true; + return false; +}; + +// visualize algorithm +const changeColor = (node, cost) => { + setTimeout(() => { + node.setAttribute("class", "chosenPath"); + node.innerHTML = cost; + }, cost * time); + // draw path blue + setTimeout(() => { + node.setAttribute("class", "pathColor"); + }, cost * time + 100); + //draw path green + setTimeout(() => { + node.setAttribute("class", "chosenPath"); + }, cost * time + 1000); +}; + +// const blockPath = (nodes) => { +// for(let i = 0; i < nodes.length; i++){ +// let node = document.querySelector(`div[row='${nodes[i][0]}'][col='${nodes[i][1]}']`); +// node.setAttribute("wall", 1); +// } +// let startNode = document.querySelector(`div[row='${4}'][col='${5}']`); +// startNode.setAttribute("wall", 0); +// } + +//traverse grid +const traverse = (node, visited, cost, endNode) => { + let row = parseInt(node.getAttribute("row")); + let col = parseInt(node.getAttribute("col")); + if (bool || node == endNode) { + bool = true; + return; + } + + let wall = parseInt(node.getAttribute("wall")); + if (wall == 1) return; + + visited.push(node); + visitedPaths.push([row, col]); + dfsSteps.push([row, col, cost, row, col]); + changeColor(node, cost); + + // Check all sides of a node + let cr = row, + cc = col; + + if (checker(cr + 1, cc)) { + let child = document.querySelector(`div[row="${cr + 1}"][col="${cc}"]`); + if (!visited.includes(child)) { + traverse(child, visited, cost + 1, endNode); + count++; + } else { + dfsSteps.push([row, col, cost, cr + 1, cc]); + } + } + if (checker(cr, cc + 1)) { + let child = document.querySelector(`div[row="${cr}"][col="${cc + 1}"]`); + if (!visited.includes(child)) { + traverse(child, visited, cost + 1, endNode); + count++; + } else { + dfsSteps.push([row, col, cost, cr, cc + 1]); + } + } + if (checker(cr - 1, cc)) { + let child = document.querySelector(`div[row="${cr - 1}"][col="${cc}"]`); + if (!visited.includes(child)) { + traverse(child, visited, cost + 1, endNode); + count++; + } else { + dfsSteps.push([row, col, cost, cr - 1, cc]); + } + } + if (checker(cr, cc - 1)) { + let child = document.querySelector(`div[row="${cr}"][col="${cc - 1}"]`); + if (!visited.includes(child)) { + traverse(child, visited, cost + 1, endNode); + count++; + } else { + dfsSteps.push([row, col, cost, cr, cc - 1]); + } + } +}; + +//depth first search algorithm +export const findPaths = (x1 = 0, y1 = 0, x2 = rowSize - 1, y2 = colSize - 1) => { + time = speedSlider.value; + time = 40 + (time - 1) * -2; + gridContainer.removeEventListener("mousedown", setWall); + gridContainer.removeEventListener("mouseover", setWall); + let startNode = document.querySelector(`div[row='${x1}'][col='${y1}']`); + let endNode = document.querySelector(`div[row='${x2}'][col='${y2}']`); + + //disable start and clear path buttons + startBtn.setAttribute("disabled", "true"); + clearPathBtn.setAttribute("disabled", "true"); + wallBtn.setAttribute("disabled", "true"); + + let visited = []; + let cost = 1; + bool = false; + + traverse(startNode, visited, cost, endNode); + + // re-enable disabled buttons + setTimeout(() => { + startBtn.removeAttribute("disabled"); + clearPathBtn.removeAttribute("disabled"); + manualStart.removeAttribute("disabled"); + wallBtn.removeAttribute("disabled"); + // blockPath(dfsSteps); + // console.log(dfsSteps); + // console.log(visitedPaths); + }, count * time + 100); +}; From 3c0bbf501de0c4ecdf27893d65091e40c9b308ad Mon Sep 17 00:00:00 2001 From: lumunge Date: Thu, 3 Feb 2022 03:49:16 +0300 Subject: [PATCH 6/7] finding all paths --- code/assets/js/visual/Grid/index.js | 15 +- .../js/visual/PathFindingAlgorithms/dfs.js | 190 +++--- .../visual/PathFindingAlgorithms/findPaths.js | 207 +++---- code/dfs-visual.html | 563 ++++++++++-------- 4 files changed, 513 insertions(+), 462 deletions(-) diff --git a/code/assets/js/visual/Grid/index.js b/code/assets/js/visual/Grid/index.js index 844b52a..6c86cc0 100644 --- a/code/assets/js/visual/Grid/index.js +++ b/code/assets/js/visual/Grid/index.js @@ -27,14 +27,16 @@ export const resetBtn = document.querySelector(".reset"); const weightBtn = document.querySelector(".weight"); const algoBtn = document.querySelector(".algo"); export const startBtn = document.querySelector(".start"); -const findNextPath = document.querySelector(".findNext"); +export const findNextPath = document.querySelector(".findNext"); export const wallBtn = document.querySelector(".setWalls"); export const speedSlider = document.querySelector(".speedSlider"); const islandAlgoBtn = document.querySelector(".islandsAlgo"); export const stepsContainer = document.querySelector(".notification"); export const algorithmType = document.querySelector(".algorithm"); export var manualStart = document.querySelector(".manual"); + manualStart.setAttribute("disabled", "true"); +findNextPath.setAttribute("disabled", "true"); //global variables export var rowSize = 20; @@ -83,6 +85,7 @@ export const clearPath = () => { algorithmType.classList.contains("dfs") || algorithmType.classList.contains("numIslands") || algorithmType.classList.contains("maxIsland") || + algorithmType.classList.contains("findPaths") || algorithmType.classList.contains("findPaths") ) { refreshEmptyBoard(); @@ -243,12 +246,14 @@ const findNextPathFunc = (nodes) => { let node = document.querySelector( `div[row='${startNextRow}'][col='${startNextCol}']` ); - dfs(startRow, startCol, endRow, endCol); nodes.pop(); clearPath(); + dfs(startRow, startCol, endRow, endCol); + console.log(startNextRow + " " + startNextCol); if (parseInt(node.getAttribute("wall")) == 0) { node.setAttribute("wall", 1); } + console.log(nodes); }; //run normal visualization @@ -286,9 +291,9 @@ const startVisualization = () => { findNextPath.addEventListener("click", () => { findNextPathFunc(visitedPaths); }); - manualStart.addEventListener("click", () => { - stepper(dfsSteps); - }); + // manualStart.addEventListener("click", () => { + // stepper(dfsSteps); + // }); } }; startBtn.addEventListener("click", startVisualization); diff --git a/code/assets/js/visual/PathFindingAlgorithms/dfs.js b/code/assets/js/visual/PathFindingAlgorithms/dfs.js index b859b31..c885655 100644 --- a/code/assets/js/visual/PathFindingAlgorithms/dfs.js +++ b/code/assets/js/visual/PathFindingAlgorithms/dfs.js @@ -1,13 +1,13 @@ import { setWall } from "../Grid/createWalls.js"; import { - rowSize, - colSize, - manualStart, - dfsSteps, - startBtn, - clearPathBtn, - wallBtn, - gridContainer, + rowSize, + colSize, + manualStart, + dfsSteps, + startBtn, + clearPathBtn, + wallBtn, + gridContainer, } from "../Grid/index.js"; let speedSlider = document.querySelector(".speedSlider"); @@ -16,110 +16,110 @@ let bool = false; let count = 1; //check edge cases -const checker = (row, col) => { - if (row >= 0 && col >= 0 && row < rowSize && col < colSize) return true; - return false; +export const checker = (row, col) => { + if (row >= 0 && col >= 0 && row < rowSize && col < colSize) return true; + return false; }; // visualize algorithm -const changeColor = (node, cost) => { - setTimeout(() => { - node.setAttribute("class", "chosenPath"); - node.innerHTML = cost; - }, cost * time); - // draw path blue - setTimeout(() => { - node.setAttribute("class", "pathColor"); - }, cost * time + 100); - //draw path green - setTimeout(() => { - node.setAttribute("class", "chosenPath"); - }, cost * time + 1000); +export const changeColor = (node, cost) => { + setTimeout(() => { + node.setAttribute("class", "chosenPath"); + node.innerHTML = cost; + }, cost * time); + // draw path blue + setTimeout(() => { + node.setAttribute("class", "pathColor"); + }, cost * time + 100); + //draw path green + setTimeout(() => { + node.setAttribute("class", "chosenPath"); + }, cost * time + 1000); }; //traverse grid const traverse = (node, visited, cost, endNode) => { - let row = parseInt(node.getAttribute("row")); - let col = parseInt(node.getAttribute("col")); - if (bool || node == endNode) { - bool = true; - return; - } + let row = parseInt(node.getAttribute("row")); + let col = parseInt(node.getAttribute("col")); + if (bool || node == endNode) { + bool = true; + return; + } - let wall = parseInt(node.getAttribute("wall")); - if (wall == 1) return; + let wall = parseInt(node.getAttribute("wall")); + if (wall == 1) return; - visited.push(node); - dfsSteps.push([row, col, cost, row, col]); - changeColor(node, cost); + visited.push(node); + dfsSteps.push([row, col, cost, row, col]); + changeColor(node, cost); - // Check all sides of a node - let cr = row, - cc = col; + // Check all sides of a node + let cr = row, + cc = col; - if (checker(cr + 1, cc)) { - let child = document.querySelector(`div[row="${cr + 1}"][col="${cc}"]`); - if (!visited.includes(child)) { - traverse(child, visited, cost + 1, endNode); - count++; - } else { - dfsSteps.push([row, col, cost, cr + 1, cc]); - } - } - if (checker(cr, cc + 1)) { - let child = document.querySelector(`div[row="${cr}"][col="${cc + 1}"]`); - if (!visited.includes(child)) { - traverse(child, visited, cost + 1, endNode); - count++; - } else { - dfsSteps.push([row, col, cost, cr, cc + 1]); - } - } - if (checker(cr - 1, cc)) { - let child = document.querySelector(`div[row="${cr - 1}"][col="${cc}"]`); - if (!visited.includes(child)) { - traverse(child, visited, cost + 1, endNode); - count++; - } else { - dfsSteps.push([row, col, cost, cr - 1, cc]); - } - } - if (checker(cr, cc - 1)) { - let child = document.querySelector(`div[row="${cr}"][col="${cc - 1}"]`); - if (!visited.includes(child)) { - traverse(child, visited, cost + 1, endNode); - count++; - } else { - dfsSteps.push([row, col, cost, cr, cc - 1]); - } - } + if (checker(cr + 1, cc)) { + let child = document.querySelector(`div[row="${cr + 1}"][col="${cc}"]`); + if (!visited.includes(child)) { + traverse(child, visited, cost + 1, endNode); + count++; + } else { + dfsSteps.push([row, col, cost, cr + 1, cc]); + } + } + if (checker(cr, cc + 1)) { + let child = document.querySelector(`div[row="${cr}"][col="${cc + 1}"]`); + if (!visited.includes(child)) { + traverse(child, visited, cost + 1, endNode); + count++; + } else { + dfsSteps.push([row, col, cost, cr, cc + 1]); + } + } + if (checker(cr - 1, cc)) { + let child = document.querySelector(`div[row="${cr - 1}"][col="${cc}"]`); + if (!visited.includes(child)) { + traverse(child, visited, cost + 1, endNode); + count++; + } else { + dfsSteps.push([row, col, cost, cr - 1, cc]); + } + } + if (checker(cr, cc - 1)) { + let child = document.querySelector(`div[row="${cr}"][col="${cc - 1}"]`); + if (!visited.includes(child)) { + traverse(child, visited, cost + 1, endNode); + count++; + } else { + dfsSteps.push([row, col, cost, cr, cc - 1]); + } + } }; //depth first search algorithm export const dfs = (x1 = 0, y1 = 0, x2 = rowSize - 1, y2 = colSize - 1) => { - time = speedSlider.value; - time = 40 + (time - 1) * -2; - gridContainer.removeEventListener("mousedown", setWall); - gridContainer.removeEventListener("mouseover", setWall); - let startNode = document.querySelector(`div[row='${x1}'][col='${y1}']`); - let endNode = document.querySelector(`div[row='${x2}'][col='${y2}']`); + time = speedSlider.value; + time = 40 + (time - 1) * -2; + gridContainer.removeEventListener("mousedown", setWall); + gridContainer.removeEventListener("mouseover", setWall); + let startNode = document.querySelector(`div[row='${x1}'][col='${y1}']`); + let endNode = document.querySelector(`div[row='${x2}'][col='${y2}']`); - //disable start and clear path buttons - startBtn.setAttribute("disabled", "true"); - clearPathBtn.setAttribute("disabled", "true"); - wallBtn.setAttribute("disabled", "true"); + //disable start and clear path buttons + startBtn.setAttribute("disabled", "true"); + clearPathBtn.setAttribute("disabled", "true"); + wallBtn.setAttribute("disabled", "true"); - let visited = []; - let cost = 1; - bool = false; + let visited = []; + let cost = 1; + bool = false; - traverse(startNode, visited, cost, endNode); + traverse(startNode, visited, cost, endNode); - // re-enable disabled buttons - setTimeout(() => { - startBtn.removeAttribute("disabled"); - clearPathBtn.removeAttribute("disabled"); - manualStart.removeAttribute("disabled"); - wallBtn.removeAttribute("disabled"); - }, count * time + 100); + // re-enable disabled buttons + setTimeout(() => { + startBtn.removeAttribute("disabled"); + clearPathBtn.removeAttribute("disabled"); + manualStart.removeAttribute("disabled"); + wallBtn.removeAttribute("disabled"); + }, count * time + 100); }; diff --git a/code/assets/js/visual/PathFindingAlgorithms/findPaths.js b/code/assets/js/visual/PathFindingAlgorithms/findPaths.js index c4d1501..788bb55 100644 --- a/code/assets/js/visual/PathFindingAlgorithms/findPaths.js +++ b/code/assets/js/visual/PathFindingAlgorithms/findPaths.js @@ -1,139 +1,114 @@ import { setWall } from "../Grid/createWalls.js"; import { - rowSize, - colSize, - manualStart, - dfsSteps, - visitedPaths, - startBtn, - clearPathBtn, - wallBtn, - gridContainer, + rowSize, + colSize, + manualStart, + dfsSteps, + visitedPaths, + startBtn, + clearPathBtn, + wallBtn, + gridContainer, + findNextPath, } from "../Grid/index.js"; +import { changeColor, checker } from "./dfs.js"; let speedSlider = document.querySelector(".speedSlider"); let time = speedSlider.value; let bool = false; let count = 1; -//check edge cases -const checker = (row, col) => { - if (row >= 0 && col >= 0 && row < rowSize && col < colSize) return true; - return false; -}; - -// visualize algorithm -const changeColor = (node, cost) => { - setTimeout(() => { - node.setAttribute("class", "chosenPath"); - node.innerHTML = cost; - }, cost * time); - // draw path blue - setTimeout(() => { - node.setAttribute("class", "pathColor"); - }, cost * time + 100); - //draw path green - setTimeout(() => { - node.setAttribute("class", "chosenPath"); - }, cost * time + 1000); -}; - -// const blockPath = (nodes) => { -// for(let i = 0; i < nodes.length; i++){ -// let node = document.querySelector(`div[row='${nodes[i][0]}'][col='${nodes[i][1]}']`); -// node.setAttribute("wall", 1); -// } -// let startNode = document.querySelector(`div[row='${4}'][col='${5}']`); -// startNode.setAttribute("wall", 0); -// } - //traverse grid const traverse = (node, visited, cost, endNode) => { - let row = parseInt(node.getAttribute("row")); - let col = parseInt(node.getAttribute("col")); - if (bool || node == endNode) { - bool = true; - return; - } + let row = parseInt(node.getAttribute("row")); + let col = parseInt(node.getAttribute("col")); + if (bool || node == endNode) { + bool = true; + return; + } - let wall = parseInt(node.getAttribute("wall")); - if (wall == 1) return; + let wall = parseInt(node.getAttribute("wall")); + if (wall == 1) return; - visited.push(node); - visitedPaths.push([row, col]); - dfsSteps.push([row, col, cost, row, col]); - changeColor(node, cost); + visited.push(node); + visitedPaths.push([row, col]); + dfsSteps.push([row, col, cost, row, col]); + changeColor(node, cost); - // Check all sides of a node - let cr = row, - cc = col; + // Check all sides of a node + let cr = row, + cc = col; - if (checker(cr + 1, cc)) { - let child = document.querySelector(`div[row="${cr + 1}"][col="${cc}"]`); - if (!visited.includes(child)) { - traverse(child, visited, cost + 1, endNode); - count++; - } else { - dfsSteps.push([row, col, cost, cr + 1, cc]); - } - } - if (checker(cr, cc + 1)) { - let child = document.querySelector(`div[row="${cr}"][col="${cc + 1}"]`); - if (!visited.includes(child)) { - traverse(child, visited, cost + 1, endNode); - count++; - } else { - dfsSteps.push([row, col, cost, cr, cc + 1]); - } - } - if (checker(cr - 1, cc)) { - let child = document.querySelector(`div[row="${cr - 1}"][col="${cc}"]`); - if (!visited.includes(child)) { - traverse(child, visited, cost + 1, endNode); - count++; - } else { - dfsSteps.push([row, col, cost, cr - 1, cc]); - } - } - if (checker(cr, cc - 1)) { - let child = document.querySelector(`div[row="${cr}"][col="${cc - 1}"]`); - if (!visited.includes(child)) { - traverse(child, visited, cost + 1, endNode); - count++; - } else { - dfsSteps.push([row, col, cost, cr, cc - 1]); - } - } + if (checker(cr + 1, cc)) { + let child = document.querySelector(`div[row="${cr + 1}"][col="${cc}"]`); + if (!visited.includes(child)) { + traverse(child, visited, cost + 1, endNode); + count++; + } else { + dfsSteps.push([row, col, cost, cr + 1, cc]); + } + } + if (checker(cr, cc + 1)) { + let child = document.querySelector(`div[row="${cr}"][col="${cc + 1}"]`); + if (!visited.includes(child)) { + traverse(child, visited, cost + 1, endNode); + count++; + } else { + dfsSteps.push([row, col, cost, cr, cc + 1]); + } + } + if (checker(cr - 1, cc)) { + let child = document.querySelector(`div[row="${cr - 1}"][col="${cc}"]`); + if (!visited.includes(child)) { + traverse(child, visited, cost + 1, endNode); + count++; + } else { + dfsSteps.push([row, col, cost, cr - 1, cc]); + } + } + if (checker(cr, cc - 1)) { + let child = document.querySelector(`div[row="${cr}"][col="${cc - 1}"]`); + if (!visited.includes(child)) { + traverse(child, visited, cost + 1, endNode); + count++; + } else { + dfsSteps.push([row, col, cost, cr, cc - 1]); + } + } }; //depth first search algorithm -export const findPaths = (x1 = 0, y1 = 0, x2 = rowSize - 1, y2 = colSize - 1) => { - time = speedSlider.value; - time = 40 + (time - 1) * -2; - gridContainer.removeEventListener("mousedown", setWall); - gridContainer.removeEventListener("mouseover", setWall); - let startNode = document.querySelector(`div[row='${x1}'][col='${y1}']`); - let endNode = document.querySelector(`div[row='${x2}'][col='${y2}']`); +export const findPaths = ( + x1 = 0, + y1 = 0, + x2 = rowSize - 1, + y2 = colSize - 1 +) => { + time = speedSlider.value; + time = 40 + (time - 1) * -2; + gridContainer.removeEventListener("mousedown", setWall); + gridContainer.removeEventListener("mouseover", setWall); + let startNode = document.querySelector(`div[row='${x1}'][col='${y1}']`); + let endNode = document.querySelector(`div[row='${x2}'][col='${y2}']`); - //disable start and clear path buttons - startBtn.setAttribute("disabled", "true"); - clearPathBtn.setAttribute("disabled", "true"); - wallBtn.setAttribute("disabled", "true"); + //disable start and clear path buttons + startBtn.setAttribute("disabled", "true"); + clearPathBtn.setAttribute("disabled", "true"); + wallBtn.setAttribute("disabled", "true"); - let visited = []; - let cost = 1; - bool = false; + let visited = []; + let cost = 1; + bool = false; - traverse(startNode, visited, cost, endNode); + traverse(startNode, visited, cost, endNode); - // re-enable disabled buttons - setTimeout(() => { - startBtn.removeAttribute("disabled"); - clearPathBtn.removeAttribute("disabled"); - manualStart.removeAttribute("disabled"); - wallBtn.removeAttribute("disabled"); - // blockPath(dfsSteps); - // console.log(dfsSteps); - // console.log(visitedPaths); - }, count * time + 100); + // re-enable disabled buttons + setTimeout(() => { + startBtn.removeAttribute("disabled"); + clearPathBtn.removeAttribute("disabled"); + manualStart.removeAttribute("disabled"); + findNextPath.removeAttribute("disabled"); + wallBtn.removeAttribute("disabled"); + console.log(visitedPaths); + }, count * time + 100); }; diff --git a/code/dfs-visual.html b/code/dfs-visual.html index 9da6860..263dc66 100644 --- a/code/dfs-visual.html +++ b/code/dfs-visual.html @@ -1,249 +1,320 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Depth first search path finding algorithm. + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Depth first search path finding algorithm. - - - - -
-
-

Depth first search visualization

-
-
-
-
-

Speed

- -
-
-

Obstacles

-
- -   - -
-
-
- - - - - -
-
- -
-

Controls

-

Speed - increase or decrease the speed of the visualization

-

Obstacles- - create walls/obstacles, on a map these can be buildings or - structures which hinder a path. You can adjust the number of obstacles generated per click. -
- You can also click on the grid cells to create - obstacles. -

-

Start - After adjusting the speed and creating obstacles, you can now start the - visualization to see the workings of the algorithm.

-

Manual - After running the visualization normally you can run it manually to see - how the shortest path was obtained. After the click you can proceed with pressing enter key. -

-

Clear Path - After visualizing, you may opt to clear the path and add more - obstacles.

-

Speed - If the grid becomes to cluttered you can reload it and repeat the above - steps.

-
-
-
- -
- - -
-
-
-
-
-
-
-
-
-
  -
This is an empty path without any walls, you can click is to add obstacles/walls.
-
-
-
A
  -
Start Node -> this is the starting point(source), - search for a path starts here.
-
-
-
B
  -
End Node -> where the search stops when a path to destination has been found
-
-
-
  -
These act as obstacles, walls. On a real map these may be buildings or structures that may - block - a shorter path to a destination.
-
-
-
7
  -
After the algorithm is complete, we have arrived at the destination, now the shortest path is - highlighted in green with the cost of path written written in black inside the path.
-
-
-
-
-
-

Depth first traversal.

-
-
-

- This algorithm starts its search at the root and - explores one of its children's subtree and then moves - on to the next child's subtree and etcetera
- The idea used is to go as deep into the graph as - possible and backtrack once we reach a vertex with - unvisited neighbors.
- That is, start search at one vertex, after visiting - the vertex, perform dfs for each unvisited adjacent - vertex. In this way we visit all vertices reachable - from the starting vertex.
- We use a stack data structure. -

-
-
-

Algorithm

-

- 1. Mark the current node as visited(initially - current node is the root node). -

-

- 2. Check if current node is the end node, If so, - then return it. -

-

- 3. Iterate over children nodes of current node, - and do the following: -

-

- 1. Check if a child node is not visited. -

-

- 2.If so, then, mark it as visited. -

-

- 3. Go to it's sub graph recursively until you - find the end node(In other words, do the same - steps here passing the child node as the current - node in the next recursive call). -

-

- 4. If the child node has the end node in this - sub graph, then, return it. -

-

- 4. If end node is not found, then end node is - not in the graph! -

-
-
-

Computational complexity

- This algorithm takes O(V + E) where v is the number of - vertices and e is the number of edges. -
-
-

Applications

-
    -
  • topological sorting.
  • -
  • bipartite graph testing.
  • -
  • finding strongly connected components.
  • -
  • - solving puzzles that can only have one - solution. -
  • -
  • detecting cycles in a graph.
  • -
-
-
-

References

- dfs -
-
-
-
-
- - - - - - \ No newline at end of file + + +
+
+

Depth first search visualization

+
+
+
+
+

Speed

+ +
+
+

Obstacles

+
+ +   + +
+
+
+ + + + + + +
+
+ +
+

Controls

+

+ Speed - increase or decrease the speed of the + visualization +

+

+ Obstacles- - create walls/obstacles, on a map these + can be buildings or structures which hinder a path. You can + adjust the number of obstacles generated per click.
+ - You can also click on the grid cells to create obstacles. +

+

+ Start - After adjusting the speed and creating + obstacles, you can now start the visualization to see the + workings of the algorithm. +

+

+ Manual - After running the visualization normally + you can run it manually to see how the shortest path was + obtained. After the click you can proceed with pressing enter + key. +

+

+ Clear Path - After visualizing, you may opt to + clear the path and add more obstacles. +

+

+ Speed - If the grid becomes to cluttered you can + reload it and repeat the above steps. +

+
+
+
+ +
+ + +
+
+
+
+
+
+
+
+
+
+   +
+ This is an empty path without any walls, you can click is to add + obstacles/walls. +
+
+
+
A
+   +
+ Start Node -> this is the starting point(source), search for a + path starts here. +
+
+
+
B
+   +
+ End Node -> where the search stops when a path to destination has + been found +
+
+
+
+   +
+ These act as obstacles, walls. On a real map these may be + buildings or structures that may block a shorter path to a + destination. +
+
+
+
7
+   +
+ After the algorithm is complete, we have arrived at the + destination, now the shortest path is highlighted in green with + the cost of path written written in black inside the path. +
+
+
+
+
+
+

Depth first traversal.

+
+
+

+ This algorithm starts its search at the root and explores one of + its children's subtree and then moves on to the next child's + subtree and etcetera
+ The idea used is to go as deep into the graph as possible and + backtrack once we reach a vertex with unvisited neighbors. +
+ That is, start search at one vertex, after visiting the vertex, + perform dfs for each unvisited adjacent vertex. In this way we + visit all vertices reachable from the starting vertex.
+ We use a stack data structure. +

+
+
+

Algorithm

+

+ 1. Mark the current node as visited(initially current node is + the root node). +

+

+ 2. Check if current node is the end node, If so, then return it. +

+

+ 3. Iterate over children nodes of current node, and do the + following: +

+

1. Check if a child node is not visited.

+

2.If so, then, mark it as visited.

+

+ 3. Go to it's sub graph recursively until you find the end + node(In other words, do the same steps here passing the child + node as the current node in the next recursive call). +

+

+ 4. If the child node has the end node in this sub graph, then, + return it. +

+

+ 4. If end node is not found, then end node is not in the graph! +

+
+
+

Computational complexity

+ This algorithm takes O(V + E) where v is the + number of vertices and e is the number of edges. +
+
+

Applications

+
    +
  • topological sorting.
  • +
  • bipartite graph testing.
  • +
  • finding strongly connected components.
  • +
  • solving puzzles that can only have one solution.
  • +
  • detecting cycles in a graph.
  • +
+
+
+

References

+ dfs +
+
+
+
+
+ + + + + From 1543f6219d36b1f31e5e63fff3b57b5c4a83c151 Mon Sep 17 00:00:00 2001 From: lumunge Date: Thu, 3 Feb 2022 03:53:04 +0300 Subject: [PATCH 7/7] removed console.logs --- code/assets/js/visual/Grid/index.js | 2 -- code/assets/js/visual/PathFindingAlgorithms/findPaths.js | 1 - 2 files changed, 3 deletions(-) diff --git a/code/assets/js/visual/Grid/index.js b/code/assets/js/visual/Grid/index.js index 6c86cc0..9d46f3a 100644 --- a/code/assets/js/visual/Grid/index.js +++ b/code/assets/js/visual/Grid/index.js @@ -249,11 +249,9 @@ const findNextPathFunc = (nodes) => { nodes.pop(); clearPath(); dfs(startRow, startCol, endRow, endCol); - console.log(startNextRow + " " + startNextCol); if (parseInt(node.getAttribute("wall")) == 0) { node.setAttribute("wall", 1); } - console.log(nodes); }; //run normal visualization diff --git a/code/assets/js/visual/PathFindingAlgorithms/findPaths.js b/code/assets/js/visual/PathFindingAlgorithms/findPaths.js index 788bb55..42aeebd 100644 --- a/code/assets/js/visual/PathFindingAlgorithms/findPaths.js +++ b/code/assets/js/visual/PathFindingAlgorithms/findPaths.js @@ -109,6 +109,5 @@ export const findPaths = ( manualStart.removeAttribute("disabled"); findNextPath.removeAttribute("disabled"); wallBtn.removeAttribute("disabled"); - console.log(visitedPaths); }, count * time + 100); };