mirror of https://gitee.com/bigwinds/arangodb
Passes the Neo4j 500 Length Test now.
This commit is contained in:
parent
4dd0306d0a
commit
a1cf1017c5
|
@ -768,61 +768,72 @@ Vertex.prototype.setProperty = function (name, value) {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Vertex.prototype.pathTo = function (target_node) {
|
||||
var pathes = {}, // {ID => [Node]}
|
||||
determined_list = [], // [ID]
|
||||
todo_list = [], // [ID]
|
||||
i, // Number
|
||||
current_node_id, // ID
|
||||
neighbor_list = [], // [ID]
|
||||
new_path = [], // [Node]
|
||||
current_neighbor; // ID
|
||||
var determined_list = [], // [ID]
|
||||
todo_list = [], // [ID]
|
||||
distances = {}, // { ID => Number }
|
||||
predecessors = {}, // { ID => [ID] }
|
||||
raw_neighborlist = [], // [ID]
|
||||
i, // Number
|
||||
current_distance = 0, // Number
|
||||
pathes = [], //
|
||||
current_node_id, // ID
|
||||
current_neighbor_id; // ID
|
||||
|
||||
this._pushNeigborsToArray(todo_list);
|
||||
|
||||
for (i = 0; i < todo_list.length; i++) {
|
||||
pathes[todo_list[i]] = [this, this._graph.getVertex(todo_list[i])];
|
||||
}
|
||||
todo_list.push(this.getId());
|
||||
distances[this.getId()] = 0;
|
||||
|
||||
while (todo_list.length > 0) {
|
||||
current_node_id = this._getShortestDistanceFor(todo_list, pathes);
|
||||
determined_list.push(current_node_id);
|
||||
current_node_id = this._getShortestDistance(todo_list, distances);
|
||||
|
||||
if (current_node_id === target_node) {
|
||||
break;
|
||||
}
|
||||
|
||||
todo_list.removeLastOccurrenceOf(current_node_id);
|
||||
determined_list.push(current_node_id);
|
||||
|
||||
neighbor_list = [];
|
||||
this._graph.getVertex(current_node_id)._pushNeigborsToArray(neighbor_list);
|
||||
for (i = 0; i < neighbor_list.length; i++) {
|
||||
current_neighbor = neighbor_list[i];
|
||||
raw_neighborlist = this._graph.getVertex(current_node_id).getNeighbors();
|
||||
for (i = 0; i < raw_neighborlist.length; i += 1) {
|
||||
current_neighbor_id = raw_neighborlist[i];
|
||||
|
||||
new_path = []
|
||||
.concat(pathes[current_node_id])
|
||||
.concat(this._graph.getVertex(current_neighbor));
|
||||
if (determined_list.lastIndexOf(current_neighbor_id) === -1) {
|
||||
current_distance = distances[current_node_id] + 1;
|
||||
|
||||
if (pathes[current_neighbor] === undefined || (new_path.length < pathes[current_neighbor].length)) {
|
||||
pathes[current_neighbor] = new_path;
|
||||
|
||||
if (determined_list.lastIndexOf(neighbor_list[i]) === -1) {
|
||||
todo_list.push(neighbor_list[i]);
|
||||
if (todo_list.lastIndexOf(current_neighbor_id) === -1) {
|
||||
todo_list.push(current_neighbor_id);
|
||||
predecessors[current_neighbor_id] = [current_node_id];
|
||||
distances[current_neighbor_id] = current_distance;
|
||||
} else if (distances[current_neighbor_id] > current_distance) {
|
||||
predecessors[current_neighbor_id] = [current_node_id];
|
||||
distances[current_neighbor_id] = current_distance;
|
||||
} else if (distances[current_neighbor_id] === current_distance) {
|
||||
predecessors[current_neighbor_id].push(current_node_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (current_node_id === target_node.getId()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return pathes[target_node.getId()];
|
||||
current_node_id = target_node.getId();
|
||||
if (determined_list.lastIndexOf(current_node_id) === -1) {
|
||||
pathes = [];
|
||||
} else {
|
||||
pathes[0] = [];
|
||||
while (current_node_id !== undefined) {
|
||||
pathes[0].push(current_node_id);
|
||||
current_node_id = predecessors[current_node_id];
|
||||
}
|
||||
pathes[0].reverse();
|
||||
}
|
||||
|
||||
return pathes;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief find the shortest path to a certain node
|
||||
///
|
||||
/// @FUN{@FA{vertex}._pushNeigborsToArray(@FA{target_array})}
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Vertex.prototype._pushNeigborsToArray = function (target_array) {
|
||||
var i, current_node_id;
|
||||
// Later: Take Inbound, Outbound, Both. Currently Both only
|
||||
// and: Only return neighbors with a certain label
|
||||
Vertex.prototype.getNeighbors = function () {
|
||||
var i,
|
||||
current_node_id,
|
||||
target_array = [];
|
||||
|
||||
for (i = 0; i < this.getOutEdges().length; i++) {
|
||||
current_node_id = this.getOutEdges()[i].getInVertex().getId();
|
||||
|
@ -833,8 +844,48 @@ Vertex.prototype._pushNeigborsToArray = function (target_array) {
|
|||
current_node_id = this.getInEdges()[i].getOutVertex().getId();
|
||||
target_array.push(current_node_id);
|
||||
}
|
||||
|
||||
return target_array;
|
||||
};
|
||||
|
||||
Vertex.prototype._getShortestDistance = function (todo_list, distances) {
|
||||
var shortest_distance = Infinity,
|
||||
node = null,
|
||||
i,
|
||||
distance;
|
||||
|
||||
for (i = 0; i < todo_list.length; i += 1) {
|
||||
distance = distances[todo_list[i]];
|
||||
if (distance < shortest_distance) {
|
||||
shortest_distance = distance;
|
||||
node = todo_list[i];
|
||||
}
|
||||
}
|
||||
|
||||
return node;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief find the shortest path to a certain node
|
||||
///
|
||||
/// @FUN{@FA{vertex}._pushNeigborsToArray(@FA{target_array})}
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Vertex.prototype._pushNeigborsToArray = function (target_array) {
|
||||
// var i, current_node_id;
|
||||
//
|
||||
// for (i = 0; i < this.getOutEdges().length; i++) {
|
||||
// current_node_id = this.getOutEdges()[i].getInVertex().getId();
|
||||
// target_array.push(current_node_id);
|
||||
// }
|
||||
//
|
||||
// for (i = 0; i < this.getInEdges().length; i++) {
|
||||
// current_node_id = this.getInEdges()[i].getOutVertex().getId();
|
||||
// target_array.push(current_node_id);
|
||||
// }
|
||||
// };
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Find the node with the shortest distance for a given list
|
||||
///
|
||||
|
@ -842,21 +893,21 @@ Vertex.prototype._pushNeigborsToArray = function (target_array) {
|
|||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Vertex.prototype._getShortestDistanceFor = function (todo_list, distances) {
|
||||
var current_node_id,
|
||||
shortest_distance = [null, Infinity],
|
||||
i;
|
||||
|
||||
for (i = 0; i < todo_list.length; i++) {
|
||||
current_node_id = todo_list[i];
|
||||
|
||||
if (distances[current_node_id].length < shortest_distance[1]) {
|
||||
shortest_distance = [current_node_id, distances[current_node_id].length];
|
||||
}
|
||||
}
|
||||
|
||||
return shortest_distance[0];
|
||||
};
|
||||
// Vertex.prototype._getShortestDistanceFor = function (todo_list, prede) {
|
||||
// var current_node_id,
|
||||
// shortest_distance = [null, Infinity],
|
||||
// i;
|
||||
//
|
||||
// for (i = 0; i < todo_list.length; i++) {
|
||||
// current_node_id = todo_list[i];
|
||||
//
|
||||
// if (distances[current_node_id].length < shortest_distance[1]) {
|
||||
// shortest_distance = [current_node_id, distances[current_node_id].length];
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return shortest_distance[0];
|
||||
// };
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
|
|
|
@ -93,52 +93,37 @@ function dijkstraSuite() {
|
|||
}
|
||||
},
|
||||
|
||||
testPushToNeighbors : function () {
|
||||
var v1 = graph.addVertex(1),
|
||||
v2 = graph.addVertex(2),
|
||||
v3 = graph.addVertex(3),
|
||||
test_array = [];
|
||||
|
||||
graph.addEdge(v1, v2);
|
||||
graph.addEdge(v1, v3);
|
||||
|
||||
v1._pushNeigborsToArray(test_array);
|
||||
|
||||
assertEqual(test_array[0], 2);
|
||||
assertEqual(test_array[1], 3);
|
||||
},
|
||||
|
||||
testShortestDistanceFor : function () {
|
||||
var v1 = graph.addVertex(1),
|
||||
v2 = graph.addVertex(2),
|
||||
v3 = graph.addVertex(3),
|
||||
todo_list = [v1.getId(), v2.getId()], // [ID]
|
||||
distances = {}, // {ID => [Node]}
|
||||
node_id_found; // Node
|
||||
|
||||
distances[v1.getId()] = [v1, v2, v3];
|
||||
distances[v2.getId()] = [v2, v3];
|
||||
distances[v3.getId()] = [v3];
|
||||
|
||||
node_id_found = v1._getShortestDistanceFor(todo_list, distances);
|
||||
assertEqual(node_id_found, v2.getId());
|
||||
},
|
||||
// testPushToNeighbors : function () {
|
||||
// var v1 = graph.addVertex(1),
|
||||
// v2 = graph.addVertex(2),
|
||||
// v3 = graph.addVertex(3),
|
||||
// test_array = [];
|
||||
//
|
||||
// graph.addEdge(v1, v2);
|
||||
// graph.addEdge(v1, v3);
|
||||
//
|
||||
// v1._pushNeigborsToArray(test_array);
|
||||
//
|
||||
// assertEqual(test_array[0], 2);
|
||||
// assertEqual(test_array[1], 3);
|
||||
// },
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief get a short, distinct path
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testGetAShortDistinctPath : function () {
|
||||
var v1, v2, e1;
|
||||
var v1, v2, e1, path;
|
||||
|
||||
v1 = graph.addVertex(1);
|
||||
v2 = graph.addVertex(2);
|
||||
|
||||
e1 = graph.addEdge(v1, v2);
|
||||
|
||||
assertEqual(v1.pathTo(v2).length, 2);
|
||||
assertEqual(v1.pathTo(v2)[0].getId(), v1.getId());
|
||||
assertEqual(v1.pathTo(v2)[1].getId(), v2.getId());
|
||||
path = v1.pathTo(v2)[0];
|
||||
assertEqual(path.length, 2);
|
||||
assertEqual(path[0].toString(), v1.getId());
|
||||
assertEqual(path[1].toString(), v2.getId());
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -146,7 +131,7 @@ function dijkstraSuite() {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testGetALongerDistinctPath : function () {
|
||||
var v1, v2, v3, e1, e2;
|
||||
var v1, v2, v3, e1, e2, path;
|
||||
|
||||
v1 = graph.addVertex(1);
|
||||
v2 = graph.addVertex(2);
|
||||
|
@ -155,23 +140,26 @@ function dijkstraSuite() {
|
|||
e1 = graph.addEdge(v1, v2);
|
||||
e2 = graph.addEdge(v2, v3);
|
||||
|
||||
assertEqual(v1.pathTo(v3).length, 3);
|
||||
assertEqual(v1.pathTo(v3)[0].getId(), v1.getId());
|
||||
assertEqual(v1.pathTo(v3)[1].getId(), v2.getId());
|
||||
assertEqual(v1.pathTo(v3)[2].getId(), v3.getId());
|
||||
path = v1.pathTo(v3)[0];
|
||||
assertEqual(path.length, 3);
|
||||
assertEqual(path[0].toString(), v1.getId());
|
||||
assertEqual(path[1].toString(), v2.getId());
|
||||
assertEqual(path[2].toString(), v3.getId());
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief compare with Neo4j on a random network of size 500
|
||||
/// @brief compare with Neo4j on a network of size 500
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testComparisonWithNeo4j500 : function () {
|
||||
testComparisonWithNeo4j500LengthOnly : function () {
|
||||
var base_path = "js/common/test-data/random500/",
|
||||
v1,
|
||||
v2,
|
||||
e,
|
||||
path,
|
||||
pathes,
|
||||
results = [],
|
||||
neo4j_results = [],
|
||||
single_result = {},
|
||||
counter;
|
||||
|
||||
Helper.process(base_path + "generated_edges.csv", function (row) {
|
||||
|
@ -184,8 +172,13 @@ function dijkstraSuite() {
|
|||
v1 = graph.getVertex(row[0]);
|
||||
v2 = graph.getVertex(row[1]);
|
||||
if (v1 !== null && v2 !== null) {
|
||||
path = v1.pathTo(v2);
|
||||
results.push(path);
|
||||
pathes = v1.pathTo(v2);
|
||||
single_result = {
|
||||
'from' : v1.getId(),
|
||||
'to' : v2.getId(),
|
||||
'path_length' : pathes[0].length
|
||||
};
|
||||
results.push(single_result);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -198,18 +191,26 @@ function dijkstraSuite() {
|
|||
if (!(v1 === row[0] && v2 === row[row.length - 1])) {
|
||||
v1 = row[0];
|
||||
v2 = row[row.length - 1];
|
||||
result = results[counter];
|
||||
|
||||
assertEqual(v1, result[0].getId());
|
||||
assertEqual(v2, result[result.length - 1].getId());
|
||||
|
||||
if (result.length !== row.length) {
|
||||
console.log("Neo4j: Path from " + v1 + " to " + v2 + " has length " + result.length + " (should be " + row.length + ")");
|
||||
}
|
||||
counter += 1;
|
||||
single_result = {
|
||||
'from' : v1,
|
||||
'to' : v2,
|
||||
'path_length' : row.length
|
||||
};
|
||||
neo4j_results.push(single_result);
|
||||
}
|
||||
//assertEqual(raw_row, results[index]);
|
||||
});
|
||||
|
||||
for (counter = 0; counter < neo4j_results.results; counter += 1) {
|
||||
assertEqual(results[counter].from,
|
||||
neo4j_results[counter].from);
|
||||
|
||||
assertEqual(results[counter].to,
|
||||
neo4j_results[counter].to);
|
||||
|
||||
assertEqual(results[counter].path_length,
|
||||
neo4j_results[counter].path_length);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue