-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathalgorithms.js
More file actions
102 lines (84 loc) · 3.73 KB
/
Copy pathalgorithms.js
File metadata and controls
102 lines (84 loc) · 3.73 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
var redraw;
window.onload = function() {
var width = $(document).width();
var height = $(document).height() - 100;
/* Showcase of the Bellman-Ford search algorithm finding shortest paths
from one point to every node */
/* */
/* We need to write a new node renderer function to display the computed
distance.
(the Raphael graph drawing implementation of Dracula can draw this shape,
please consult the RaphaelJS reference for details http://raphaeljs.com/) */
var render = function(r, n) {
/* the Raphael set is obligatory, containing all you want to display */
var set = r.set().push(
/* custom objects go here */
r.rect(n.point[0]-30, n.point[1]-13, 60, 44).attr({"fill": "#feb", r : "12px", "stroke-width" : n.distance == 0 ? "3px" : "1px" })).push(
r.text(n.point[0], n.point[1] + 10, (n.label || n.id) + "\n(" + (n.distance == undefined ? "Infinity" : n.distance) + ")"));
return set;
};
var g = new Graph();
/* modify the edge creation to attach random weights */
g.edgeFactory.build = function(source, target) {
var e = jQuery.extend(true, {}, this.template);
e.source = source;
e.target = target;
e.style.label = e.weight = Math.floor(Math.random() * 10) + 1;
return e;
}
/* creating nodes and passing the new renderer function to overwrite the default one */
g.addNode("New York", {render:render}); // TODO add currying support for nicer code
g.addNode("Berlin", {render:render});
g.addNode("Tel Aviv", {render:render});
g.addNode("Tokyo", {render:render});
g.addNode("Roma", {render:render});
g.addNode("Madrid", {render:render});
/* connections */
g.addEdge("Tokyo", "Tel Aviv"/*, {weight:9, directed: true, stroke : "#bfa"}*/); // also supports directed graphs, but currently doesn't look that nice
g.addEdge("Tokyo", "New York");
g.addEdge("Tokyo", "Berlin");
g.addEdge("Tel Aviv", "Berlin");
g.addEdge("Tel Aviv", "New York");
g.addEdge("Tel Aviv", "Roma");
g.addEdge("Roma", "New York");
g.addEdge("Berlin", "New York");
g.addEdge("Madrid", "New York");
g.addEdge("Madrid", "Roma");
g.addEdge("Madrid", "Tokyo");
/* random edge weights (our undirected graph is modelled as a bidirectional graph) */
/* for(e in g.edges)
if(g.edges[e].backedge != undefined) {
g.edges[e].weight = Math.floor(Math.random()*10) + 1;
g.edges[e].backedge.weight = g.edges[e].weight;
}
*/
/* layout the graph using the Spring layout implementation */
var layouter = new Graph.Layout.Spring(g);
/* draw the graph using the RaphaelJS draw implementation */
/* calculating the shortest paths via Bellman Ford */
// bellman_ford(g, g.nodes["Berlin"]);
/* calculating the shortest paths via Dijkstra */
dijkstra(g, g.nodes["Berlin"]);
/* calculating the shortest paths via Floyd-Warshall */
floyd_warshall(g, g.nodes["Berlin"]);
/* colourising the shortest paths and setting labels */
for(e in g.edges) {
if(g.edges[e].target.predecessor === g.edges[e].source || g.edges[e].source.predecessor === g.edges[e].target) {
g.edges[e].style.stroke = "red";
g.edges[e].style.fill = "red";
} else {
g.edges[e].style.stroke = "green";
}
}
var renderer = new Graph.Renderer.Raphael('canvas', g, width, height);
redraw = function() {
layouter.layout();
renderer.draw();
};
/* var pos=0;
step = function(dir) {
pos+=dir;
var renderer = new Graph.Renderer.Raphael('canvas', g.snapshots[pos], width, height);
renderer.draw();
};*/
};