Added BFS and DFS

This commit is contained in:
Unick Soft 2019-01-03 13:50:27 +02:00
parent f9050ca49c
commit d282e24590
8 changed files with 299 additions and 1 deletions

View File

@ -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: ";
?>

View File

@ -138,4 +138,7 @@
$g_lang["has_hamiltonian_loop"] = "Граф содержит Гамильтонов цикл";
$g_lang["has_not_hamiltonian_loop"] = "Граф не содержит Гамильтонов цикл";
$g_lang["start_traversal"] = "Выбирете начальную вершину обхода";
$g_lang["traversal_order"] = "Порядок обхода: ";
?>

56
script/BaseTraversal.js Normal file
View File

@ -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;
}

View File

@ -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))
{

114
script/plugins/BFS .js Normal file
View File

@ -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);

113
script/plugins/DFS.js Normal file
View File

@ -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);

View File

@ -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;
}

View File

@ -425,6 +425,9 @@
<p id="hasNotHamiltonianPath" class="translation"><?= L('has_not_hamiltonian_path')?></p>
<p id="hasHamiltonianPath" class="translation"><?= L('has_hamiltonian_path')?></p>
<p id="startTraversal" class="translation"><?= L('start_traversal')?></p>
<p id="traversalOrder" class="translation"><?= L('traversal_order')?></p>
</section>
<!--
<script>