From 1d8385f38355f53690aa7b7573634366b2a15ab5 Mon Sep 17 00:00:00 2001 From: Unick Soft Date: Wed, 9 May 2018 20:59:12 +0300 Subject: [PATCH] Added more colors for vertex. Added Coloring algorithm. Reorder algorithm. --- script/BaseVertexDrawer.js | 57 ++++++++- script/plugins/Coloring.js | 233 +++++++++++++++++++++++++++++++++++++ script/plugins/MaxFlow.js | 2 +- tpl/home.php | 2 +- 4 files changed, 291 insertions(+), 3 deletions(-) create mode 100644 script/plugins/Coloring.js diff --git a/script/BaseVertexDrawer.js b/script/BaseVertexDrawer.js index 65ec6b8..a809bdb 100644 --- a/script/BaseVertexDrawer.js +++ b/script/BaseVertexDrawer.js @@ -67,8 +67,63 @@ function SelectedVertexStyle4() SelectedVertexStyle4.prototype = Object.create(CommonVertexStyle.prototype); +function SelectedVertexStyle5() +{ + CommonVertexStyle.apply(this, arguments); + + this.strokeStyle = '#FF6200'; + this.mainTextColor = '#FF6200'; + this.fillStyle = '#0F4FA8'; +} + +SelectedVertexStyle5.prototype = Object.create(CommonVertexStyle.prototype); + +function SelectedVertexStyle6() +{ + CommonVertexStyle.apply(this, arguments); + + this.strokeStyle = '#8CA336'; + this.mainTextColor = '#8CA336'; + this.fillStyle = '#9C344C'; +} + +SelectedVertexStyle6.prototype = Object.create(CommonVertexStyle.prototype); + +function SelectedVertexStyle7() +{ + CommonVertexStyle.apply(this, arguments); + + this.strokeStyle = '#B59E22'; + this.mainTextColor = '#B59E22'; + this.fillStyle = '#22387A'; +} + +SelectedVertexStyle7.prototype = Object.create(CommonVertexStyle.prototype); + +function SelectedVertexStyle8() +{ + CommonVertexStyle.apply(this, arguments); + + this.strokeStyle = '#08806C'; + this.mainTextColor = '#08806C'; + this.fillStyle = '#CA980D'; +} + +SelectedVertexStyle8.prototype = Object.create(CommonVertexStyle.prototype); + +function SelectedVertexStyle9() +{ + CommonVertexStyle.apply(this, arguments); + + this.strokeStyle = '#AA8134'; + this.mainTextColor = '#AA8134'; + this.fillStyle = '#492A73'; +} + +SelectedVertexStyle9.prototype = Object.create(CommonVertexStyle.prototype); + var selectedGraphStyles = [new SelectedVertexStyle0(), new SelectedVertexStyle1(), - new SelectedVertexStyle2(), new SelectedVertexStyle3(), new SelectedVertexStyle4()]; + new SelectedVertexStyle2(), new SelectedVertexStyle3(), new SelectedVertexStyle4(), new SelectedVertexStyle5(), new SelectedVertexStyle6(), new SelectedVertexStyle7(), new SelectedVertexStyle8(), new SelectedVertexStyle9()]; function BaseVertexDrawer(context) { diff --git a/script/plugins/Coloring.js b/script/plugins/Coloring.js new file mode 100644 index 0000000..d4a3c14 --- /dev/null +++ b/script/plugins/Coloring.js @@ -0,0 +1,233 @@ +/** + * Default handler. + * Select using mouse, drag. + * + */ +function Coloring(graph, app) +{ + BaseAlgorithm.apply(this, arguments); + this.connectedComponentNumber = 0; + this.component = {}; + this.selectedObjects = []; + this.MaxColor = 1000; +} + + +// inheritance. +Coloring.prototype = Object.create(BaseAlgorithm.prototype); + + +Coloring.prototype.getName = function(local) +{ + return local == "ru" ? "Раскраска графов" : "Graph coloring"; +} + +Coloring.prototype.getId = function() +{ + return "OlegSh.GraphColoring"; +} + +// @return message for user. +Coloring.prototype.getMessage = function(local) +{ + return (local == "ru" ? "Найденное количество цветов " : "Color number is ") + this.connectedComponentNumber; +} + +Coloring.prototype.result = function(resultCallback) +{ + this.calculate(true); + + var result = {}; + result["version"] = 1; + this.selectedObjects = this.component; + + return result; +} + +Coloring.prototype.calculate = function(fillUpText = false) +{ + this.connectedComponentNumber = 0; + this.component = {}; + connectedVertex = getVertexToVertexArray(this.graph, true); + + var listOfOrders = []; + this.addSimpleAndRandomOrders(listOfOrders); + this.addBasedOnDegree(listOfOrders, connectedVertex); + + this.connectedComponentNumber = this.MaxColor; + + // Find minimal variant. + for (var i = 0; i < listOfOrders.length; i++) + { + var coloringComponent = this.makeColoring(listOfOrders[i], connectedVertex); + if (coloringComponent["max"] < this.connectedComponentNumber) + { + this.component = coloringComponent; + this.connectedComponentNumber = coloringComponent["max"]; + } + } + + // Fill Up text + for (var i = 0; i < this.graph.vertices.length; i++) + { + this.graph.vertices[i].upText = this.component[this.graph.vertices[i].id]; + } + + //var result = {}; + //result["version"] = 1; + //this.selectedObjects = this.component; + + return this.connectedComponentNumber; +} + +Coloring.prototype.makeColoring = function(vertexOrder, connectedVertex) +{ + var res = {}; + var maxColor = 0; + + for (var i = 0; i < vertexOrder.length; i++) + { + var id = this.graph.vertices[vertexOrder[i]].id; + var hasColor = {}; + if (id in connectedVertex) + { + // find color of neighbors. + for (var j = 0; j < connectedVertex[id].length; j++) + { + nearId = connectedVertex[id][j].id; + if (nearId in res) + { + hasColor[res[nearId]] = 1; + } + } + } + + // find color for current vertex; + var color = 0; + for (var j = 1; j < this.MaxColor; j++) + { + if (!(j in hasColor)) + { + color = j; + break; + } + } + res[id] = color; + maxColor = Math.max(maxColor, color); + } + + res["max"] = maxColor; + return res; +} + +Coloring.prototype.addSimpleAndRandomOrders = function(listOfOrders) +{ + var vertexOrder = []; + for (var i = 0; i < this.graph.vertices.length; i++) + { + vertexOrder.push(i); + } + + // As in graph + listOfOrders.push(vertexOrder); + // Push some randoms + for (var i = 0; i < Math.floor(Math.sqrt(this.graph.vertices.length)); i++) + { + listOfOrders.push(this.shuffleArray(vertexOrder)); + } +} + +Coloring.prototype.addBasedOnDegree = function(listOfOrders, connectedVertex) +{ + var vertexDegree = []; + for (var i = 0; i < this.graph.vertices.length; i++) + { + var degree = 0; + var id = this.graph.vertices[i].id; + if (id in connectedVertex) + { + degree = connectedVertex[id].length; + } + + vertexDegree.push({index : i, degree : degree}); + } + + // sort + vertexDegree.sort( + function(a, b) { + return (a.degree > b.degree) ? -1 : + ((b.degree > a.degree) ? 1 : 0); + }); + + var vertexOrder = []; + for (var i = 0; i < vertexDegree.length; i++) + { + vertexOrder.push(vertexDegree[i].index); + } + + //console.log(vertexDegree); + + // Sorted by degree. + listOfOrders.push(vertexOrder); + + var shuffleLitle = vertexOrder.slice(); + for (var i = 0; i < shuffleLitle.length - 1; i +=2) + { + var t = shuffleLitle[i]; + shuffleLitle[i] = shuffleLitle[i + 1]; + shuffleLitle[i + 1] = t; + } + + // Swap near. + listOfOrders.push(shuffleLitle); + + // shufl by half + if (vertexDegree.length > 1) + { + var pivotElement = Math.round(vertexOrder.length / 2); + var randomByPart = this.shuffleArray(vertexOrder.slice(0, pivotElement)).concat(this.shuffleArray(vertexOrder.slice(pivotElement))); + listOfOrders.push(randomByPart); + + // add with random pivots + for (var i = 0; i < Math.floor(Math.sqrt(this.graph.vertices.length)); i++) + { + var pivot = Math.floor(Math.random() * (vertexOrder.length - 2)) + 1; + + var randomByPart = this.shuffleArray(vertexOrder.slice(0, pivot)).concat(this.shuffleArray(vertexOrder.slice(pivot))); + listOfOrders.push(randomByPart); + //console.log(randomByPart); + } + } +} + +Coloring.prototype.shuffleArray = function(a) +{ + var j, x, i; + for (i = a.length - 1; i > 0; i--) { + j = Math.floor(Math.random() * (i + 1)); + x = a[i]; + a[i] = a[j]; + a[j] = x; + } + return a; +} + +Coloring.prototype.getObjectSelectedGroup = function(object) +{ + return (object.id in this.selectedObjects) ? this.selectedObjects[object.id] : 0; +} + +Coloring.prototype.getPriority = function() +{ + return -9.7; +} + + +// Factory for connected components. +function CreateColoring(graph, app) +{ + return new Coloring(graph) +} + +// Gerister connected component. +RegisterAlgorithm (CreateColoring); diff --git a/script/plugins/MaxFlow.js b/script/plugins/MaxFlow.js index 8bf7576..cac0d61 100644 --- a/script/plugins/MaxFlow.js +++ b/script/plugins/MaxFlow.js @@ -179,7 +179,7 @@ FindMaxFlow.prototype.getObjectSelectedGroup = function(object) FindMaxFlow.prototype.getPriority = function() { - return -9.7; + return -9.6; } // @return true, if you change resotry graph after use. diff --git a/tpl/home.php b/tpl/home.php index 0d966fa..7f7489c 100755 --- a/tpl/home.php +++ b/tpl/home.php @@ -10,7 +10,7 @@ - +