mirror of https://gitee.com/bigwinds/arangodb
First version of Measurements and Shortest Path Executor
This commit is contained in:
parent
17fd5f6afe
commit
0b0df398d0
|
@ -1623,9 +1623,9 @@ Graph.prototype.geodesics = function (options) {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief calculate a measurement
|
||||
///
|
||||
/// @FUN{@FA{vertex}.measurement(@FA{measurement})}
|
||||
/// @FUN{@FA{graph}.measurement(@FA{measurement})}
|
||||
///
|
||||
/// Calculates the eccentricity or closeness of the vertex
|
||||
/// Calculates the diameter or radius of a graph
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -1661,6 +1661,56 @@ Graph.prototype.measurement = function (measurement) {
|
|||
}, start_value);
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief calculate a normalized measurement
|
||||
///
|
||||
/// @FUN{@FA{graph}.normalizedMeasurement(@FA{measurement})}
|
||||
///
|
||||
/// Calculates the normalized degree, closeness, betweenness or eccentricity
|
||||
/// of all vertices in a graph
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Graph.prototype.normalizedMeasurement = function (measurement) {
|
||||
var graph = this,
|
||||
vertices = graph._vertices.toArray(),
|
||||
vertex_map,
|
||||
max = 0;
|
||||
|
||||
vertex_map = vertices.reduce(function (map, raw_vertex) {
|
||||
var vertex = graph.constructVertex(raw_vertex._id),
|
||||
measured;
|
||||
|
||||
switch(measurement) {
|
||||
case "closeness":
|
||||
measured = 1 / vertex.measurement("closeness");
|
||||
break;
|
||||
case "betweenness":
|
||||
measured = vertex.measurement("betweenness");
|
||||
break;
|
||||
case "eccentricity":
|
||||
measured = 1 / vertex.measurement("eccentricity");
|
||||
break;
|
||||
default:
|
||||
throw "Unknown measurement";
|
||||
}
|
||||
|
||||
if (measured > max) {
|
||||
max = measured;
|
||||
}
|
||||
|
||||
map[vertex.getId()] = measured;
|
||||
|
||||
return map;
|
||||
}, {});
|
||||
|
||||
Object.keys(vertex_map).forEach(function(key) {
|
||||
vertex_map[key] = vertex_map[key] / max;
|
||||
});
|
||||
|
||||
return vertex_map;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
Id,Source,Target
|
||||
1,1,26
|
||||
2,3,17
|
||||
3,3,39
|
||||
4,4,8
|
||||
5,4,17
|
||||
6,4,43
|
||||
7,4,44
|
||||
8,5,17
|
||||
9,5,27
|
||||
10,6,38
|
||||
11,7,50
|
||||
12,8,32
|
||||
13,8,35
|
||||
14,8,48
|
||||
15,9,42
|
||||
16,10,19
|
||||
17,10,20
|
||||
18,10,39
|
||||
19,10,50
|
||||
20,11,16
|
||||
21,12,24
|
||||
22,12,28
|
||||
23,12,37
|
||||
24,14,24
|
||||
25,14,26
|
||||
26,14,36
|
||||
27,14,48
|
||||
28,15,21
|
||||
29,15,38
|
||||
30,15,50
|
||||
31,16,37
|
||||
32,16,49
|
||||
33,17,30
|
||||
34,17,40
|
||||
35,17,47
|
||||
36,18,28
|
||||
37,19,37
|
||||
38,20,38
|
||||
39,20,42
|
||||
40,20,45
|
||||
41,21,26
|
||||
42,21,48
|
||||
43,22,31
|
||||
44,23,37
|
||||
45,23,40
|
||||
46,24,27
|
||||
47,24,46
|
||||
48,25,29
|
||||
49,26,31
|
||||
50,27,50
|
||||
51,28,45
|
||||
52,28,48
|
||||
53,29,36
|
||||
54,29,49
|
||||
55,30,46
|
||||
56,32,44
|
||||
57,33,43
|
||||
58,34,49
|
||||
59,37,47
|
||||
60,38,45
|
||||
61,40,50
|
||||
62,42,47
|
|
Binary file not shown.
|
@ -0,0 +1,51 @@
|
|||
Id,In-Degree,Out-Degree,Degree,Eccentricity,Closeness Centrality,Betweenness Centrality
|
||||
1,0,1,1,2.0,0.6666666666666666,0.0
|
||||
2,0,0,0,0.0,0.0,0.0
|
||||
3,0,2,2,3.0,0.5,0.0
|
||||
4,0,4,4,3.0,0.5454545454545455,0.0
|
||||
5,0,2,2,3.0,0.5384615384615384,0.0
|
||||
6,0,1,1,2.0,0.6666666666666666,0.0
|
||||
7,0,1,1,1.0,1.0,0.0
|
||||
8,1,3,4,2.0,0.8,0.0012755102040816326
|
||||
9,0,1,1,2.0,0.6666666666666666,0.0
|
||||
10,0,4,4,3.0,0.6,0.0
|
||||
11,0,1,1,3.0,0.5,0.0
|
||||
12,0,3,3,3.0,0.5625,0.0
|
||||
13,0,0,0,0.0,0.0,0.0
|
||||
14,0,4,4,3.0,0.6153846153846154,0.0
|
||||
15,0,3,3,3.0,0.5833333333333334,0.0
|
||||
16,1,2,3,2.0,0.75,0.0012755102040816326
|
||||
17,3,3,6,2.0,0.7142857142857143,0.005952380952380952
|
||||
18,0,1,1,2.0,0.6,0.0
|
||||
19,1,1,2,2.0,0.6666666666666666,6.377551020408163E-4
|
||||
20,1,3,4,2.0,0.8,0.001488095238095238
|
||||
21,1,2,3,2.0,0.75,0.0012755102040816326
|
||||
22,0,1,1,1.0,1.0,0.0
|
||||
23,0,2,2,2.0,0.6666666666666666,0.0
|
||||
24,2,2,4,2.0,0.75,0.002551020408163265
|
||||
25,0,1,1,2.0,0.6,0.0
|
||||
26,3,1,4,1.0,1.0,0.0017006802721088435
|
||||
27,2,1,3,1.0,1.0,0.0017006802721088435
|
||||
28,2,2,4,1.0,1.0,0.0017006802721088435
|
||||
29,1,2,3,1.0,1.0,8.503401360544217E-4
|
||||
30,1,1,2,1.0,1.0,0.0017006802721088435
|
||||
31,2,0,2,0.0,0.0,0.0
|
||||
32,1,1,2,1.0,1.0,4.2517006802721087E-4
|
||||
33,0,1,1,1.0,1.0,0.0
|
||||
34,0,1,1,1.0,1.0,0.0
|
||||
35,1,0,1,0.0,0.0,0.0
|
||||
36,2,0,2,0.0,0.0,0.0
|
||||
37,4,1,5,1.0,1.0,0.00233843537414966
|
||||
38,3,1,4,1.0,1.0,8.503401360544217E-4
|
||||
39,2,0,2,0.0,0.0,0.0
|
||||
40,2,1,3,1.0,1.0,0.0017006802721088435
|
||||
41,0,0,0,0.0,0.0,0.0
|
||||
42,2,1,3,1.0,1.0,0.0010629251700680273
|
||||
43,2,0,2,0.0,0.0,0.0
|
||||
44,2,0,2,0.0,0.0,0.0
|
||||
45,3,0,3,0.0,0.0,0.0
|
||||
46,2,0,2,0.0,0.0,0.0
|
||||
47,3,0,3,0.0,0.0,0.0
|
||||
48,4,0,4,0.0,0.0,0.0
|
||||
49,3,0,3,0.0,0.0,0.0
|
||||
50,5,0,5,0.0,0.0,0.0
|
|
|
@ -0,0 +1,124 @@
|
|||
/*jslint indent: 2,
|
||||
nomen: true,
|
||||
maxlen: 80,
|
||||
sloppy: true */
|
||||
/*global require,
|
||||
db,
|
||||
assertEqual, assertTrue,
|
||||
print,
|
||||
PRINT_OBJECT,
|
||||
console,
|
||||
AvocadoCollection, AvocadoEdgesCollection,
|
||||
processCsvFile */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test the graph class
|
||||
///
|
||||
/// @file
|
||||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2010-2012 triagens GmbH, Cologne, Germany
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
/// You may obtain a copy of the License at
|
||||
///
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
///
|
||||
/// Unless required by applicable law or agreed to in writing, software
|
||||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Lucas Dohmen
|
||||
/// @author Copyright 2012, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function main(args) {
|
||||
var Graph = require("graph").Graph,
|
||||
graph_name = "UnitTestsCollectionGraph",
|
||||
vertex = "UnitTestsCollectionVertex",
|
||||
edge = "UnitTestsCollectionEdge",
|
||||
graph = null,
|
||||
base_path = args[1] + "/",
|
||||
v1,
|
||||
v2,
|
||||
e,
|
||||
pathes,
|
||||
results = [],
|
||||
neo4j_results = [],
|
||||
single_result = {},
|
||||
console = require("console"),
|
||||
Helper = require("test-helper").Helper,
|
||||
counter,
|
||||
i,
|
||||
caching = false,
|
||||
times = parseInt(args[3], 10);
|
||||
|
||||
if (args[2] === "true") {
|
||||
caching = true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// set up
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
try {
|
||||
try {
|
||||
// Drop the graph if it exsits
|
||||
graph = new Graph(graph_name);
|
||||
print("FOUND: ");
|
||||
PRINT_OBJECT(graph);
|
||||
graph.drop();
|
||||
} catch (err1) {
|
||||
}
|
||||
|
||||
graph = new Graph(graph_name, vertex, edge);
|
||||
} catch (err2) {
|
||||
console.error("[FAILED] setup failed:" + err2);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// compare with Neo4j on a given network
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
console.log("Importing");
|
||||
|
||||
Helper.process(base_path + "generated_edges.csv", function (row) {
|
||||
v1 = graph.getOrAddVertex(row[1]);
|
||||
v2 = graph.getOrAddVertex(row[2]);
|
||||
e = graph.addEdge(v1, v2);
|
||||
});
|
||||
|
||||
console.log("Starting Tests");
|
||||
|
||||
start_time = new Date();
|
||||
Helper.process(base_path + "generated_testcases.csv", function (row) {
|
||||
v1 = graph.getVertex(row[0]);
|
||||
v2 = graph.getVertex(row[1]);
|
||||
|
||||
for (i = 0; i < times; i += 1) {
|
||||
if (v1 !== null && v2 !== null) {
|
||||
pathes = v1.pathTo(v2, { cached: caching });
|
||||
}
|
||||
}
|
||||
});
|
||||
end_time = new Date();
|
||||
console.log((end_time - start_time) + " ms");
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// tear down
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
try {
|
||||
if (graph !== null) {
|
||||
graph.drop();
|
||||
}
|
||||
} catch (err) {
|
||||
console.error("[FAILED] tear-down failed:" + err);
|
||||
}
|
||||
}
|
|
@ -381,11 +381,146 @@ function geodesicSuite() {
|
|||
};
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test suite: Normalized Measurements on Graphs
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function normalizedSuite() {
|
||||
var Graph = require("graph").Graph,
|
||||
graph_name = "UnitTestsCollectionGraph",
|
||||
vertex = "UnitTestsCollectionVertex",
|
||||
edge = "UnitTestsCollectionEdge",
|
||||
graph = null;
|
||||
|
||||
return {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief set up
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
setUp : function () {
|
||||
try {
|
||||
try {
|
||||
// Drop the graph if it exsits
|
||||
graph = new Graph(graph_name);
|
||||
print("FOUND: ");
|
||||
PRINT_OBJECT(graph);
|
||||
graph.drop();
|
||||
} catch (err1) {
|
||||
}
|
||||
|
||||
graph = new Graph(graph_name, vertex, edge);
|
||||
} catch (err2) {
|
||||
console.error("[FAILED] setup failed:" + err2);
|
||||
}
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief tear down
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
tearDown : function () {
|
||||
try {
|
||||
if (graph !== null) {
|
||||
graph.drop();
|
||||
}
|
||||
} catch (err) {
|
||||
console.error("[FAILED] tear-down failed:" + err);
|
||||
}
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test the normalized closeness of a graph
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testCloseness: function () {
|
||||
var v1 = graph.addVertex(1),
|
||||
v2 = graph.addVertex(2),
|
||||
v3 = graph.addVertex(3),
|
||||
v4 = graph.addVertex(4),
|
||||
v5 = graph.addVertex(5),
|
||||
closeness;
|
||||
|
||||
graph.addEdge(v1, v2);
|
||||
graph.addEdge(v2, v3);
|
||||
graph.addEdge(v2, v4);
|
||||
graph.addEdge(v3, v4);
|
||||
graph.addEdge(v3, v5);
|
||||
graph.addEdge(v4, v5);
|
||||
|
||||
closeness = graph.normalizedMeasurement("closeness");
|
||||
|
||||
assertEqual(closeness[v1.getId()].toPrecision(1), '0.6');
|
||||
assertEqual(closeness[v2.getId()].toPrecision(1), '1');
|
||||
assertEqual(closeness[v3.getId()].toPrecision(1), '1');
|
||||
assertEqual(closeness[v4.getId()].toPrecision(1), '1');
|
||||
assertEqual(closeness[v5.getId()].toPrecision(1), '0.7');
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test the normalized betweenness of a graph
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testBetweenness: function () {
|
||||
var v1 = graph.addVertex(1),
|
||||
v2 = graph.addVertex(2),
|
||||
v3 = graph.addVertex(3),
|
||||
v4 = graph.addVertex(4),
|
||||
v5 = graph.addVertex(5),
|
||||
betweenness;
|
||||
|
||||
graph.addEdge(v1, v2);
|
||||
graph.addEdge(v2, v3);
|
||||
graph.addEdge(v2, v4);
|
||||
graph.addEdge(v3, v4);
|
||||
graph.addEdge(v3, v5);
|
||||
graph.addEdge(v4, v5);
|
||||
|
||||
betweenness = graph.normalizedMeasurement("betweenness");
|
||||
|
||||
assertEqual(betweenness[v1.getId()].toPrecision(1), '0');
|
||||
assertEqual(betweenness[v2.getId()].toPrecision(1), '1');
|
||||
assertEqual(betweenness[v3.getId()].toPrecision(1), '0.3');
|
||||
assertEqual(betweenness[v4.getId()].toPrecision(1), '0.3');
|
||||
assertEqual(betweenness[v5.getId()].toPrecision(1), '0');
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test the normalized eccentricity of a graph
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testEccentricity: function () {
|
||||
var v1 = graph.addVertex(1),
|
||||
v2 = graph.addVertex(2),
|
||||
v3 = graph.addVertex(3),
|
||||
v4 = graph.addVertex(4),
|
||||
v5 = graph.addVertex(5),
|
||||
eccentricity;
|
||||
|
||||
graph.addEdge(v1, v2);
|
||||
graph.addEdge(v2, v3);
|
||||
graph.addEdge(v2, v4);
|
||||
graph.addEdge(v3, v4);
|
||||
graph.addEdge(v3, v5);
|
||||
graph.addEdge(v4, v5);
|
||||
|
||||
eccentricity = graph.normalizedMeasurement("eccentricity");
|
||||
|
||||
assertEqual(eccentricity[v1.getId()].toPrecision(1), '0.67');
|
||||
assertEqual(eccentricity[v2.getId()].toPrecision(1), '1');
|
||||
assertEqual(eccentricity[v3.getId()].toPrecision(1), '1');
|
||||
assertEqual(eccentricity[v4.getId()].toPrecision(1), '1');
|
||||
assertEqual(eccentricity[v5.getId()].toPrecision(1), '0.67');
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief executes the test suites
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
jsunity.run(measurementSuite);
|
||||
jsunity.run(geodesicSuite);
|
||||
jsunity.run(normalizedSuite);
|
||||
|
||||
return jsunity.done();
|
||||
return jsunity.done();
|
||||
|
|
|
@ -46,7 +46,7 @@ var jsunity = require("jsunity"),
|
|||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test suite: Dijkstra
|
||||
/// @brief test suite: Dijkstra (Comparison with Data from Neo4j)
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function dijkstraSuite() {
|
||||
|
@ -169,9 +169,109 @@ function dijkstraSuite() {
|
|||
};
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test suite: Measurements (Comparison with Gephi)
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function measurementSuite() {
|
||||
var Graph = require("graph").Graph,
|
||||
graph_name = "UnitTestsCollectionGraph",
|
||||
vertex = "UnitTestsCollectionVertex",
|
||||
edge = "UnitTestsCollectionEdge",
|
||||
graph = null;
|
||||
|
||||
return {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief set up
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
setUp : function () {
|
||||
try {
|
||||
try {
|
||||
// Drop the graph if it exsits
|
||||
graph = new Graph(graph_name);
|
||||
print("FOUND: ");
|
||||
PRINT_OBJECT(graph);
|
||||
graph.drop();
|
||||
} catch (err1) {
|
||||
}
|
||||
|
||||
graph = new Graph(graph_name, vertex, edge);
|
||||
} catch (err2) {
|
||||
console.error("[FAILED] setup failed:" + err2);
|
||||
}
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief tear down
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
tearDown : function () {
|
||||
try {
|
||||
if (graph !== null) {
|
||||
graph.drop();
|
||||
}
|
||||
} catch (err) {
|
||||
console.error("[FAILED] tear-down failed:" + err);
|
||||
}
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief compare with Gephi on a network of 50
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testComparisonWithGephi50 : function () {
|
||||
var base_path = "js/common/test-data/gephi50/",
|
||||
console = require("console");
|
||||
|
||||
Helper.process(base_path + "vertices.csv", function (row) {
|
||||
var vertex = graph.addVertex(row[0], {
|
||||
in_degree: row[1],
|
||||
out_degree: row[2],
|
||||
degree: row[3],
|
||||
eccentricity: row[4],
|
||||
closeness: row[5],
|
||||
betweenness: row[6]
|
||||
});
|
||||
});
|
||||
|
||||
Helper.process(base_path + "edges.csv", function (row) {
|
||||
v1 = graph.getVertex(row[1]);
|
||||
v2 = graph.getVertex(row[2]);
|
||||
e = graph.addEdge(v1, v2, row[0]);
|
||||
});
|
||||
|
||||
assertEqual(graph.order(), 50);
|
||||
assertEqual(graph.size(), 62);
|
||||
|
||||
graph._vertices.toArray().forEach(function (raw_vertex) {
|
||||
var vertex = graph.getVertex(raw_vertex._id);
|
||||
|
||||
assertEqual(vertex.getProperty("degree"), vertex.degree());
|
||||
assertEqual(vertex.getProperty("in_degree"), vertex.inDegree());
|
||||
assertEqual(vertex.getProperty("out_degree"), vertex.outDegree());
|
||||
//assertEqual(parseFloat(vertex.getProperty("eccentricity")).toPrecision(21),
|
||||
//vertex.measurement("eccentricity").toPrecision(21));
|
||||
// console.log(vertex.getProperty("closeness"));
|
||||
console.log("Reference: " + vertex.getProperty("closeness"));
|
||||
console.log("Implementation: " + vertex.measurement("closeness"));
|
||||
});
|
||||
|
||||
graph.normalizedMeasurement()
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief executes the test suites
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
jsunity.run(dijkstraSuite);
|
||||
//jsunity.run(dijkstraSuite);
|
||||
jsunity.run(measurementSuite);
|
||||
|
||||
return jsunity.done();
|
||||
|
|
Loading…
Reference in New Issue