From d282e2459025aa32fb7ba97831f6445056e05c31 Mon Sep 17 00:00:00 2001 From: Unick Soft Date: Thu, 3 Jan 2019 13:50:27 +0200 Subject: [PATCH] Added BFS and DFS --- lang/en/home.php | 3 ++ lang/ru/home.php | 3 ++ script/BaseTraversal.js | 56 ++++++++++++++++++++ script/merge.php | 2 +- script/plugins/BFS .js | 114 ++++++++++++++++++++++++++++++++++++++++ script/plugins/DFS.js | 113 +++++++++++++++++++++++++++++++++++++++ script/texts.js | 6 +++ tpl/home.php | 3 ++ 8 files changed, 299 insertions(+), 1 deletion(-) create mode 100644 script/BaseTraversal.js create mode 100644 script/plugins/BFS .js create mode 100644 script/plugins/DFS.js diff --git a/lang/en/home.php b/lang/en/home.php index ddfccbb..102cc85 100755 --- a/lang/en/home.php +++ b/lang/en/home.php @@ -135,4 +135,7 @@ $g_lang["has_hamiltonian_loop"] = "Graph has Hamiltonian cycle"; $g_lang["has_not_hamiltonian_loop"] = "Graph has not Hamiltonian cycle"; + + $g_lang["start_traversal"] = "Select start traversal vertex"; + $g_lang["traversal_order"] = "Traversal order: "; ?> diff --git a/lang/ru/home.php b/lang/ru/home.php index b062920..4cd5d71 100755 --- a/lang/ru/home.php +++ b/lang/ru/home.php @@ -138,4 +138,7 @@ $g_lang["has_hamiltonian_loop"] = "Граф содержит Гамильтонов цикл"; $g_lang["has_not_hamiltonian_loop"] = "Граф не содержит Гамильтонов цикл"; + + $g_lang["start_traversal"] = "Выбирете начальную вершину обхода"; + $g_lang["traversal_order"] = "Порядок обхода: "; ?> diff --git a/script/BaseTraversal.js b/script/BaseTraversal.js new file mode 100644 index 0000000..64d5fb1 --- /dev/null +++ b/script/BaseTraversal.js @@ -0,0 +1,56 @@ +/** + * Find short path. + * + */ +function BaseTraversal(graph, app) +{ + BaseAlgorithmEx.apply(this, arguments); + this.visited = []; + this.edges = []; + this.timer = null; +} + +// inheritance. +BaseTraversal.prototype = Object.create(BaseAlgorithmEx.prototype); +// timer interval +BaseTraversal.prototype.timerInterval = 500; + +BaseTraversal.prototype.result = function(resultCallback) +{ + var result = {}; + result["version"] = 1; + + return result; +} + +BaseTraversal.prototype.selectVertex = function(vertex) +{ + this.visited = []; + this.edges = []; + + if (this.timer) + clearTimeout(this.timer); + this.timer = null; + + this.visited.push(vertex); + + var context = this; + this.timer = setInterval(function() + { + context.step(); + }, this.timerInterval); + + this.message = this.getMainMessage(); + + return true; +} + +BaseTraversal.prototype.getObjectSelectedGroup = function(object) +{ + return (this.visited.includes(object) ? 1 : (this.edges.includes(object) ? 1 : 0)); +} + +BaseTraversal.prototype.instance = function() +{ + return false; +} diff --git a/script/merge.php b/script/merge.php index 09f879f..65a7f35 100644 --- a/script/merge.php +++ b/script/merge.php @@ -18,7 +18,7 @@ file_put_contents($outputFilename, file_get_contents("Graph.js"), FILE_APPEND); file_put_contents($outputFilename, file_get_contents("EnumVertices.js"), FILE_APPEND); file_put_contents($outputFilename, file_get_contents("Appilcation.js"), FILE_APPEND); file_put_contents($outputFilename, file_get_contents("main.js"), FILE_APPEND); - +file_put_contents($outputFilename, file_get_contents("BaseTraversal.js"), FILE_APPEND); if (file_exists($outputFilename)) { diff --git a/script/plugins/BFS .js b/script/plugins/BFS .js new file mode 100644 index 0000000..3458d69 --- /dev/null +++ b/script/plugins/BFS .js @@ -0,0 +1,114 @@ +/** + * Find short path. + * + */ +function BFSAlgorithm(graph, app) +{ + BaseTraversal.apply(this, arguments); + this.message = g_startTraversal; +} + +// inheritance. +BFSAlgorithm.prototype = Object.create(BaseTraversal.prototype); +// timer interval +BFSAlgorithm.prototype.timerInterval = 500; + +BFSAlgorithm.prototype.getName = function(local) +{ + return local == "ru" ? "Поиск в ширину" : "Breadth-first search"; +} + +BFSAlgorithm.prototype.getId = function() +{ + return "OlegSh.BFSAlgorithm"; +} + +// @return message for user. +BFSAlgorithm.prototype.getMessage = function(local) +{ + return this.message; +} + +BFSAlgorithm.prototype.result = function(resultCallback) +{ + var result = {}; + result["version"] = 1; + + return result; +} + +BFSAlgorithm.prototype.getMainMessage = function() +{ + var message = g_traversalOrder; + // calculate. + var tempVisited = this.visited.slice(); + var tempEdge = []; + + var oldLength = 0; + + while (oldLength < tempVisited.length) + { + oldLength = tempVisited.length; + for (var i = 0; i < tempVisited.length; i++) + { + if (this.bfs(tempVisited[i], tempVisited, tempEdge)) + break; + } + } + + // Format message + for (var i = 0; i < tempVisited.length; i ++) + { + tempVisited[i].upText = (i + 1) + ""; + message = message + tempVisited[i].mainText + " "; + } + + return message; +} + +BFSAlgorithm.prototype.getPriority = function() +{ + return -9.5; +} + +BFSAlgorithm.prototype.step = function() +{ + for (var i = 0; i < this.visited.length; i++) + { + if (this.bfs(this.visited[i], this.visited, this.edges)) + { + this.app.redrawGraph(); + return; + } + } + + clearTimeout(this.timer); + this.timer = null; + return; +} + +BFSAlgorithm.prototype.bfs = function(vertex, vertexArray, edgeArray) +{ + for (var i = 0; i < this.graph.vertices.length; i ++) + { + var nextVertex = this.graph.vertices[i]; + var edge = this.graph.FindEdge(vertex.id, nextVertex.id); + if (edge && !vertexArray.includes(nextVertex)) + { + edgeArray.push(edge); + vertexArray.push(nextVertex); + return true; + } + } + + return false; +} + +// Factory for connected components. +function CreateBFSAlgorithm(graph, app) +{ + return new BFSAlgorithm(graph, app) +} + +// Gerister connected component. +RegisterAlgorithm (CreateBFSAlgorithm); diff --git a/script/plugins/DFS.js b/script/plugins/DFS.js new file mode 100644 index 0000000..1d3db38 --- /dev/null +++ b/script/plugins/DFS.js @@ -0,0 +1,113 @@ +/** + * Find short path. + * + */ +function DFSAlgorithm(graph, app) +{ + BaseTraversal.apply(this, arguments); + this.message = g_startTraversal; +} + +// inheritance. +DFSAlgorithm.prototype = Object.create(BaseTraversal.prototype); +// timer interval +DFSAlgorithm.prototype.timerInterval = 500; + +DFSAlgorithm.prototype.getName = function(local) +{ + return local == "ru" ? "Поиск в глубину" : "Depth-first search"; +} + +DFSAlgorithm.prototype.getId = function() +{ + return "OlegSh.DFSAlgorithm"; +} + +// @return message for user. +DFSAlgorithm.prototype.getMessage = function(local) +{ + return this.message; +} + +DFSAlgorithm.prototype.result = function(resultCallback) +{ + var result = {}; + result["version"] = 1; + + return result; +} + +DFSAlgorithm.prototype.getMainMessage = function() +{ + var message = g_traversalOrder; + // calculate. + var tempVisited = this.visited.slice(); + var tempEdge = []; + + var oldLength = 0; + + while (oldLength < tempVisited.length) + { + oldLength = tempVisited.length; + for (var i = tempVisited.length - 1; i >= 0; i--) + { + if (this.dfs(tempVisited[i], tempVisited, tempEdge)) + break; + } + } + + // Format message + for (var i = 0; i < tempVisited.length; i ++) + { + tempVisited[i].upText = (i + 1) + ""; + message = message + tempVisited[i].mainText + " "; + } + return message; +} + +DFSAlgorithm.prototype.getPriority = function() +{ + return -9.5; +} + +DFSAlgorithm.prototype.step = function() +{ + for (var i = this.visited.length - 1; i >= 0; i--) + { + if (this.dfs(this.visited[i], this.visited, this.edges)) + { + this.app.redrawGraph(); + return; + } + } + + clearTimeout(this.timer); + this.timer = null; + return; +} + +DFSAlgorithm.prototype.dfs = function(vertex, vertexArray, edgeArray) +{ + for (var i = 0; i < this.graph.vertices.length; i ++) + { + var nextVertex = this.graph.vertices[i]; + var edge = this.graph.FindEdge(vertex.id, nextVertex.id); + if (edge && !vertexArray.includes(nextVertex)) + { + edgeArray.push(edge); + vertexArray.push(nextVertex); + return true; + } + } + + return false; +} + +// Factory for connected components. +function CreateDFSAlgorithm(graph, app) +{ + return new DFSAlgorithm(graph, app) +} + +// Gerister connected component. +RegisterAlgorithm (CreateDFSAlgorithm); diff --git a/script/texts.js b/script/texts.js index a408355..8298a2c 100644 --- a/script/texts.js +++ b/script/texts.js @@ -92,6 +92,9 @@ var g_hasNotHamiltonianLoop = "Graph has not Hamiltonian Loop"; var g_hasHamiltonianPath = "Graph has Hamiltonian Path"; var g_hasNotHamiltonianPath = "Graph has not Hamiltonian Path"; +var g_startTraversal = "Select start traversal vector"; +var g_traversalOrder = "Traversal order: "; + function loadTexts() { g_textsSelectAndMove = document.getElementById("SelectAndMoveObject").innerHTML; @@ -183,4 +186,7 @@ function loadTexts() g_hasHamiltonianPath = document.getElementById("hasHamiltonianPath").innerHTML; g_hasNotHamiltonianPath = document.getElementById("hasNotHamiltonianPath").innerHTML; + + g_startTraversal = document.getElementById("startTraversal").innerHTML; + g_traversalOrder = document.getElementById("traversalOrder").innerHTML; } diff --git a/tpl/home.php b/tpl/home.php index e6b699a..75fa8e8 100755 --- a/tpl/home.php +++ b/tpl/home.php @@ -425,6 +425,9 @@

+ +

+