Added radius and diameter search

This commit is contained in:
Unick Soft 2018-02-17 17:32:25 +03:00
parent 8a3ad5c598
commit 9361664643
5 changed files with 316 additions and 37 deletions

View File

@ -671,7 +671,7 @@ Application.prototype.GetStatus = function()
Application.prototype.GetAdjacencyMatrix = function ()
{
return this.graph.GetAdjacencyMatrix();
return this.graph.GetAdjacencyMatrixStr();
}
Application.prototype.TestAdjacencyMatrix = function (matrix, rowsObj, colsObj, separator = ",")

View File

@ -18,6 +18,8 @@ function Graph()
this.hasDirect = false;
};
// infinity
Graph.prototype.infinity = 1E8;
Graph.prototype.AddNewVertex = function(vertex)
{
@ -146,7 +148,7 @@ Graph.prototype.FindEdge = function(id1, id2)
return res;
}
Graph.prototype.GetAdjacencyMatrix = function ()
Graph.prototype.GetAdjacencyMatrixStr = function ()
{
var matrix = "";
for (var i = 0; i < this.vertices.length; i++)
@ -175,6 +177,32 @@ Graph.prototype.GetAdjacencyMatrix = function ()
return matrix;
}
Graph.prototype.GetAdjacencyMatrix = function ()
{
var matrix = [];
for (var i = 0; i < this.vertices.length; i ++)
{
matrix.push([]);
var v1 = this.vertices[i];
for (var j = 0; j < this.vertices.length; j ++)
{
var v2 = this.vertices[j];
var edge = this.FindEdge(v1.id, v2.id);
if (edge != null)
{
matrix[i][j] = edge.GetWeight();
}
else
{
matrix[i][j] = this.infinity;
}
}
}
return matrix;
}
Graph.prototype.TestAdjacencyMatrix = function (matrix, rowsObj, colsObj, separator = ",")
{
var bGoodFormat = true;

View File

@ -33,6 +33,17 @@ FindConnectedComponentNew.prototype.getMessage = function(local)
}
FindConnectedComponentNew.prototype.result = function(resultCallback)
{
this.calculate(true);
var result = {};
result["version"] = 1;
this.selectedObjects = this.component;
return result;
}
FindConnectedComponentNew.prototype.calculate = function(fillUpText = false)
{
this.connectedComponentNumber = 0;
this.component = {};
@ -55,7 +66,10 @@ FindConnectedComponentNew.prototype.result = function(resultCallback)
{
var stackElement = stack[i];
this.component[stackElement.id] = connectedComponentNumber;
stackElement.upText = connectedComponentNumber;
if (fillUpText)
{
stackElement.upText = connectedComponentNumber;
}
if (connectedVertex.hasOwnProperty(stackElement.id))
{
@ -81,11 +95,12 @@ FindConnectedComponentNew.prototype.result = function(resultCallback)
}
}
this.connectedComponentNumber = connectedComponentNumber;
var result = {};
result["version"] = 1;
this.selectedObjects = this.component;
//var result = {};
//result["version"] = 1;
//this.selectedObjects = this.component;
return result;
return this.connectedComponentNumber;
}
FindConnectedComponentNew.prototype.getObjectSelectedGroup = function(object)

View File

@ -46,35 +46,7 @@ FloidAlgorithm.prototype.result = function(resultCallback)
this.matrix = [];
for (var i = 0; i < this.graph.vertices.length; i ++)
{
this.matrix.push([]);
var v1 = this.graph.vertices[i];
var str = "";
for (var j = 0; j < this.graph.vertices.length; j ++)
{
var v2 = this.graph.vertices[j];
var edge = this.graph.FindEdge(v1.id, v2.id);
if (edge != null)
{
this.matrix[i][j] = edge.GetWeight();
}
else
{
this.matrix[i][j] = this.infinity;
}
}
}
for (var k = 0; k < this.graph.vertices.length; k ++)
for (var i = 0; i < this.graph.vertices.length; i ++)
for (var j = 0; j < this.graph.vertices.length; j ++)
{
if (this.matrix[i][j] > this.matrix[i][k] + this.matrix[k][j])
{
this.matrix[i][j] = this.matrix[i][k] + this.matrix[k][j];
}
}
this.resultMatrix();
//console.log(this.matrix);
@ -118,6 +90,45 @@ FloidAlgorithm.prototype.result = function(resultCallback)
*/
}
FloidAlgorithm.prototype.resultMatrix = function()
{
this.matrix = [];
for (var i = 0; i < this.graph.vertices.length; i ++)
{
this.matrix.push([]);
var v1 = this.graph.vertices[i];
var str = "";
for (var j = 0; j < this.graph.vertices.length; j ++)
{
var v2 = this.graph.vertices[j];
var edge = this.graph.FindEdge(v1.id, v2.id);
if (edge != null)
{
this.matrix[i][j] = edge.GetWeight();
}
else
{
this.matrix[i][j] = this.infinity;
}
}
}
for (var k = 0; k < this.graph.vertices.length; k ++)
for (var i = 0; i < this.graph.vertices.length; i ++)
for (var j = 0; j < this.graph.vertices.length; j ++)
{
if (this.matrix[i][j] > this.matrix[i][k] + this.matrix[k][j])
{
this.matrix[i][j] = this.matrix[i][k] + this.matrix[k][j];
}
}
return this.matrix;
}
FloidAlgorithm.prototype.getObjectSelectedGroup = function(object)
{
return 0;
@ -155,7 +166,7 @@ FloidAlgorithm.prototype.messageWasChanged = function()
FloidAlgorithm.prototype.GetFloidMatrix = function()
{
return this.graph.GetAdjacencyMatrix();
return this.graph.GetAdjacencyMatrixStr();
}

View File

@ -0,0 +1,225 @@
/**
* Algorithm for reorder graph.
*
*/
function RadiusAndDiameter(graph, app)
{
BaseAlgorithm.apply(this, arguments);
this.diameter = 0;
this.radius = 0;
this.diameterSelectedObjects = [];
this.radiusSelectedObjects = [];
this.centerVertexes = [];
this.peripheralVertexes = [];
this.isNotConnected = false;
this.isOneVertex = false;
}
// inheritance.
RadiusAndDiameter.prototype = Object.create(BaseAlgorithm.prototype);
RadiusAndDiameter.prototype.getName = function(local)
{
return local == "ru" ? "Поиск радиуса и диаметра графа": "Search graph radius and diameter";
}
RadiusAndDiameter.prototype.getId = function()
{
return "OlegSh.RadiusAndDiameter";
}
// @return message for user.
RadiusAndDiameter.prototype.getMessage = function(local)
{
if (this.isNotConnected)
{
return (local == "ru" ? "Граф не является связным" : "Graph is disconnected");
}
if (this.isOneVertex)
{
return (local == "ru" ? "Граф содержит только одну вершину" : "Graph contains only one vertex");
}
var text = (local == "ru" ? "Радуис граф: " : "Graph radius: ") + this.radius;
text = text + " (";
for (i = 0; i < this.radiusSelectedObjects.length; i++)
{
if (this.radiusSelectedObjects[i] instanceof BaseVertex)
{
text = text + this.radiusSelectedObjects[i].mainText + ((i < this.radiusSelectedObjects.length - 1) ? "&rArr;" : "");
}
}
text = text + ").";
text = text + (local == "ru" ? " Диаметр граф: " : "Graph diameter: ") + this.diameter;
text = text + " (";
for (i = 0; i < this.diameterSelectedObjects.length; i++)
{
if (this.diameterSelectedObjects[i] instanceof BaseVertex)
{
text = text + this.diameterSelectedObjects[i].mainText + ((i < this.diameterSelectedObjects.length - 1) ? "&rArr;" : "");
}
}
text = text + ").";
return text;
}
RadiusAndDiameter.prototype.result = function(resultCallback)
{
var result = {};
result["version"] = 1;
if (this.graph.vertices.length == 1)
{
this.isOneVertex = true;
return;
}
var connectedComponents = new FindConnectedComponentNew(this.graph, this.app);
var connectedComponentNumber = connectedComponents.calculate();
if (connectedComponentNumber == 1)
{
var floid = new FloidAlgorithm(this.graph, this.app);
var matrix = floid.resultMatrix();
this.diameter = -1;
var diameterStart = 0;
var diameterFinish = 0;
this.radius = 1E10;
var radiusStart = 0;
var radiusFinish = 0;
var eccentricity = [];
for (var i = 0; i < matrix.length; i++)
{
var vertex = -1;//(i == 0 ? 1 : 0);
var vertexEccentricity = -1;//matrix[i][vertex];
for (var j = 0; j < matrix[i].length; j++)
{
if (vertexEccentricity < matrix[i][j] && i != j && matrix[i][j] != floid.infinity)
{
vertexEccentricity = matrix[i][j];
vertex = j;
}
}
var res = {value: vertexEccentricity, vertex: vertex};
eccentricity.push(res);
}
for (var i = 0; i < eccentricity.length; i++)
{
var vertexEccentricity = eccentricity[i].value;
if (vertexEccentricity < 0)
{
continue;
}
if (this.radius > vertexEccentricity)
{
this.radius = vertexEccentricity;
radiusStart = i;
radiusFinish = eccentricity[i].vertex;
}
if (this.diameter < vertexEccentricity)
{
this.diameter = vertexEccentricity;
diameterStart = i;
diameterFinish = eccentricity[i].vertex;
}
}
for (var i = 0; i < eccentricity.length; i++)
{
var vertexEccentricity = eccentricity[i].value;
if (vertexEccentricity < 0)
{
continue;
}
if (eccentricity[i].value == this.radius)
{
this.centerVertexes.push(this.graph.vertices[i].id);
this.graph.vertices[i].upText = (g_language == "ru" ? "Центральная" : "Central");
}
if (eccentricity[i].value == this.diameter)
{
this.peripheralVertexes.push(this.graph.vertices[i].id);
this.graph.vertices[i].upText = (g_language == "ru" ? "Периферийная" : "Peripheral");
}
}
this.diameterSelectedObjects = this.getPathByMatrix(this.graph.GetAdjacencyMatrix(), matrix, diameterStart, diameterFinish, this.diameter);
this.radiusSelectedObjects = this.getPathByMatrix(this.graph.GetAdjacencyMatrix(), matrix, radiusStart, radiusFinish, this.radius);
}
else
{
this.isNotConnected = true;
}
return result;
}
RadiusAndDiameter.prototype.getPathByMatrix = function(adjacencyMatrix, minPathMatrix, startNode, finishNode, length)
{
var res = [];
vertices = this.graph.vertices;
while (length != adjacencyMatrix[startNode][finishNode])
{
for (var i = 0; i < adjacencyMatrix.length; i ++)
{
if (minPathMatrix[i][finishNode] == length - adjacencyMatrix[startNode][i] && i != startNode)
{
res.push(vertices[startNode]);
res.push(this.graph.FindEdge(vertices[startNode].id, vertices[i].id));
length -= adjacencyMatrix[startNode][i];
startNode = i;
break;
}
}
}
res.push(vertices[startNode]);
res.push(this.graph.FindEdge(vertices[startNode].id, vertices[finishNode].id));
res.push(vertices[finishNode]);
return res;
}
RadiusAndDiameter.prototype.getObjectSelectedGroup = function(object)
{
var res = (this.diameterSelectedObjects.includes(object)) ? 1 : 0;
res = (this.radiusSelectedObjects.includes(object)) ? 2 : res;
//res = (this.centerVertexes.includes(object.id)) ? 3 : res;
//res = (this.peripheralVertexes.includes(object.id)) ? 4 : res;
return res;
}
RadiusAndDiameter.prototype.getPriority = function()
{
return -8.5;
}
// Factory for connected components.
function CreateAlgorithmRadiusAndDiameter(graph, app)
{
return new RadiusAndDiameter(graph, app)
}
// Gerister connected component.
RegisterAlgorithm (CreateAlgorithmRadiusAndDiameter);