Initial data commit
This commit is contained in:
parent
72d218235f
commit
f23f22d71c
199087 changed files with 3378941 additions and 0 deletions
152
Task/Dijkstras-algorithm/Wren/dijkstras-algorithm.wren
Normal file
152
Task/Dijkstras-algorithm/Wren/dijkstras-algorithm.wren
Normal file
|
|
@ -0,0 +1,152 @@
|
|||
import "/dynamic" for Tuple
|
||||
import "/trait" for Comparable
|
||||
import "/sort" for Cmp, Sort
|
||||
import "/set" for Set
|
||||
|
||||
var Edge = Tuple.create("Edge", ["v1", "v2", "dist"])
|
||||
|
||||
// One vertex of the graph, complete with mappings to neighboring vertices
|
||||
class Vertex is Comparable {
|
||||
static map { __map } // maps a name to its corresponding Vertex
|
||||
|
||||
construct new(name) {
|
||||
_name = name
|
||||
_dist = Num.maxSafeInteger // assumed to be infinity
|
||||
_prev = null
|
||||
_neighbors = {}
|
||||
if (!__map) __map = {}
|
||||
__map[name] = this
|
||||
}
|
||||
|
||||
name { _name }
|
||||
dist { _dist }
|
||||
dist=(d) { _dist = d }
|
||||
prev { _prev }
|
||||
prev=(v) { _prev = v }
|
||||
neighbors { _neighbors }
|
||||
|
||||
printPath() {
|
||||
if (this == _prev) {
|
||||
System.write(_name)
|
||||
} else if (!_prev) {
|
||||
System.write("%(_name)(unreached)")
|
||||
} else {
|
||||
_prev.printPath()
|
||||
System.write(" -> %(_name)(%(_dist))")
|
||||
}
|
||||
}
|
||||
|
||||
compare(other) {
|
||||
if (_dist == other.dist) return Cmp.string.call(_name, other.name)
|
||||
return Cmp.num.call(_dist, other.dist)
|
||||
}
|
||||
|
||||
toString { "(%(_name), %(_dist))" }
|
||||
}
|
||||
|
||||
class Graph {
|
||||
construct new(edges, directed, showAllPaths) {
|
||||
_graph = {}
|
||||
// one pass to find all vertices
|
||||
for (e in edges) {
|
||||
if (!_graph.containsKey(e.v1)) _graph[e.v1] = Vertex.new(e.v1)
|
||||
if (!_graph.containsKey(e.v2)) _graph[e.v2] = Vertex.new(e.v2)
|
||||
}
|
||||
|
||||
// another pass to set neighboring vertices
|
||||
for (e in edges) {
|
||||
_graph[e.v1].neighbors[_graph[e.v2].name] = e.dist
|
||||
// also do this for an undirected graph if applicable
|
||||
if (!directed) _graph[e.v2].neighbors[_graph[e.v1].name] = e.dist
|
||||
}
|
||||
_showAllPaths = showAllPaths
|
||||
_directed = directed
|
||||
}
|
||||
|
||||
// Runs dijkstra using a specified source vertex
|
||||
dijkstra(startName) {
|
||||
if (!_graph.containsKey(startName)) {
|
||||
System.print("Graph doesn't contain start vertex '%(startName)'")
|
||||
return
|
||||
}
|
||||
var source = _graph[startName]
|
||||
var q = Set.new()
|
||||
|
||||
// set-up vertices
|
||||
for (v in _graph.values) {
|
||||
v.prev = (v == source) ? source : null
|
||||
v.dist = (v == source) ? 0 : Num.maxSafeInteger
|
||||
q.add(v.name)
|
||||
}
|
||||
dijkstra_(q)
|
||||
}
|
||||
|
||||
// Implementation of dijkstra's algorithm using a (simulated) tree set
|
||||
dijkstra_(q) {
|
||||
while (!q.isEmpty) {
|
||||
var qq = q.toList
|
||||
Sort.heap(qq)
|
||||
// vertex with shortest distance (first iteration will return source)
|
||||
var u = Vertex.map[qq[0]]
|
||||
q.remove(qq[0])
|
||||
// if distance is infinite we can ignore 'u'
|
||||
// (and any other remaining vertices) since they are unreachable
|
||||
if (u.dist == Num.maxSafeInteger) break
|
||||
|
||||
// look at distances to each neighbor
|
||||
for (a in u.neighbors) {
|
||||
var v = Vertex.map[a.key] // the neighbor in this iteration
|
||||
var alternateDist = u.dist + a.value
|
||||
if (alternateDist < v.dist) { // shorter path to neighbor found
|
||||
v.dist = alternateDist
|
||||
v.prev = u
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Prints the path from the source to every vertex
|
||||
// (output order is not guaranteed)
|
||||
printAllPaths_() {
|
||||
for (v in _graph.values) {
|
||||
v.printPath()
|
||||
System.print()
|
||||
}
|
||||
System.print()
|
||||
}
|
||||
|
||||
// Prints a path from the source to the specified vertex
|
||||
printPath(endName) {
|
||||
if (!_graph.containsKey(endName)) {
|
||||
System.print("Graph doesn't contain end vertex '%(endName)'")
|
||||
return
|
||||
}
|
||||
System.write(_directed ? "Directed : " : "Undirected : ")
|
||||
_graph[endName].printPath()
|
||||
System.print()
|
||||
if (_showAllPaths) printAllPaths_() else System.print()
|
||||
}
|
||||
}
|
||||
|
||||
var GRAPH = [
|
||||
Edge.new("a", "b", 7),
|
||||
Edge.new("a", "c", 9),
|
||||
Edge.new("a", "f", 14),
|
||||
Edge.new("b", "c", 10),
|
||||
Edge.new("b", "d", 15),
|
||||
Edge.new("c", "d", 11),
|
||||
Edge.new("c", "f", 2),
|
||||
Edge.new("d", "e", 6),
|
||||
Edge.new("e", "f", 9)
|
||||
]
|
||||
|
||||
var START = "a"
|
||||
var END = "e"
|
||||
|
||||
var g = Graph.new(GRAPH, true, false) // directed
|
||||
g.dijkstra(START)
|
||||
g.printPath(END)
|
||||
|
||||
g = Graph.new(GRAPH, false, false) // undirected
|
||||
g.dijkstra(START)
|
||||
g.printPath(END)
|
||||
Loading…
Add table
Add a link
Reference in a new issue