1
0
Fork 0

Passes the Neo4j 500 Length Test now.

This commit is contained in:
Lucas Dohmen 2012-05-25 15:25:13 +02:00
parent 4dd0306d0a
commit a1cf1017c5
2 changed files with 161 additions and 109 deletions

View File

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

View File

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