Graph database Analysis of the Steam Network
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

134 lines
3.8 KiB

(function() {
'use strict';
if (typeof sigma === 'undefined') {
throw 'sigma is not declared';
}
// Default function to compute path length between two nodes:
// the euclidian
var defaultPathLengthFunction = function(node1, node2, previousPathLength) {
var isEverythingDefined =
node1 != undefined &&
node2 != undefined &&
node1.x != undefined &&
node1.y != undefined &&
node2.x != undefined &&
node2.y != undefined;
if(!isEverythingDefined) {
return undefined;
}
return (previousPathLength || 0) + Math.sqrt(
Math.pow((node2.y - node1.y), 2) + Math.pow((node2.x - node1.x), 2)
);
};
sigma.classes.graph.addMethod(
'astar',
function(srcId, destId, settings) {
var currentSettings = new sigma.classes.configurable(
// Default settings
{
// Graph is directed, affects which edges are taken into account
undirected: false,
// Function to compute the distance between two connected node
pathLengthFunction: defaultPathLengthFunction,
// Function to compute an distance between two nodes
// if undefined, uses pathLengthFunction
heuristicLengthFunction: undefined
},
settings || {});
var pathLengthFunction = currentSettings("pathLengthFunction"),
heuristicLengthFunction = currentSettings("heuristicLengthFunction") || pathLengthFunction;
var srcNode = this.nodes(srcId),
destNode = this.nodes(destId);
var closedList = {},
openList = [];
var addToLists = function(node, previousNode, pathLength, heuristicLength) {
var nodeId = node.id;
var newItem = {
pathLength: pathLength,
heuristicLength: heuristicLength,
node: node,
nodeId: nodeId,
previousNode: previousNode
};
if(closedList[nodeId] == undefined || closedList[nodeId].pathLength > pathLength) {
closedList[nodeId] = newItem;
var item;
var i;
for(i = 0; i < openList.length; i++) {
item = openList[i];
if(item.heuristicLength > heuristicLength) {
break;
}
}
openList.splice(i, 0, newItem);
}
};
addToLists(srcNode, null, 0, 0);
var pathFound = false;
// Depending of the type of graph (directed or not),
// the neighbors are either the out neighbors or all.
var allNeighbors;
if(currentSettings("undirected")) {
allNeighbors = this.allNeighborsIndex;
}
else {
allNeighbors = this.outNeighborsIndex;
}
var inspectedItem,
neighbors,
neighbor,
pathLength,
heuristicLength,
i;
while(openList.length > 0) {
inspectedItem = openList.shift();
// We reached the destination node
if(inspectedItem.nodeId == destId) {
pathFound = true;
break;
}
neighbors = Object.keys(allNeighbors[inspectedItem.nodeId]);
for(i = 0; i < neighbors.length; i++) {
neighbor = this.nodes(neighbors[i]);
pathLength = pathLengthFunction(inspectedItem.node, neighbor, inspectedItem.pathLength);
heuristicLength = heuristicLengthFunction(neighbor, destNode);
addToLists(neighbor, inspectedItem.node, pathLength, heuristicLength);
}
}
if(pathFound) {
// Rebuilding path
var path = [],
currentNode = destNode;
while(currentNode) {
path.unshift(currentNode);
currentNode = closedList[currentNode.id].previousNode;
}
return path;
}
else {
return undefined;
}
}
);
}).call(window);