Data update
This commit is contained in:
parent
8e4e15fa56
commit
72eb4943cb
1853 changed files with 35514 additions and 9441 deletions
140
Task/Dijkstras-algorithm/FreeBASIC/dijkstras-algorithm.basic
Normal file
140
Task/Dijkstras-algorithm/FreeBASIC/dijkstras-algorithm.basic
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
Const INFINITY As Integer = &h7FFFFFFF
|
||||
|
||||
Type Edge
|
||||
src As String * 1
|
||||
dst As String * 1
|
||||
cost As Integer
|
||||
End Type
|
||||
|
||||
Type Vertex
|
||||
nom As String * 1
|
||||
dist As Integer
|
||||
prev As String * 1
|
||||
End Type
|
||||
|
||||
Type Graph
|
||||
edges(100) As Edge
|
||||
edgeCount As Integer
|
||||
verts(100) As Vertex
|
||||
vertCount As Integer
|
||||
End Type
|
||||
|
||||
Function createGraph(edges() As Edge, cnt As Integer) As Graph
|
||||
Dim As Graph g
|
||||
Dim As String names(100)
|
||||
Dim As Integer i, j, nCount = 0
|
||||
|
||||
g.edgeCount = cnt
|
||||
|
||||
' Copy edges and collect unique vertices
|
||||
For i = 0 To cnt - 1
|
||||
g.edges(i) = edges(i)
|
||||
|
||||
' Check source vertex
|
||||
Dim As Boolean found = False
|
||||
For j = 0 To nCount - 1
|
||||
If names(j) = edges(i).src Then
|
||||
found = True
|
||||
Exit For
|
||||
End If
|
||||
Next
|
||||
If Not found Then
|
||||
names(nCount) = edges(i).src
|
||||
nCount += 1
|
||||
End If
|
||||
|
||||
' Check destination vertex
|
||||
found = False
|
||||
For j = 0 To nCount - 1
|
||||
If names(j) = edges(i).dst Then
|
||||
found = True
|
||||
Exit For
|
||||
End If
|
||||
Next
|
||||
If Not found Then
|
||||
names(nCount) = edges(i).dst
|
||||
nCount += 1
|
||||
End If
|
||||
Next
|
||||
|
||||
' Initialize vertices
|
||||
g.vertCount = nCount
|
||||
For i = 0 To nCount - 1
|
||||
With g.verts(i)
|
||||
.nom = names(i)
|
||||
.dist = INFINITY
|
||||
.prev = names(i)
|
||||
End With
|
||||
Next
|
||||
|
||||
Return g
|
||||
End Function
|
||||
|
||||
Function findVertex(g As Graph, nombre As String) As Integer
|
||||
For i As Integer = 0 To g.vertCount - 1
|
||||
If g.verts(i).nom = nombre Then Return i
|
||||
Next
|
||||
Return -1
|
||||
End Function
|
||||
|
||||
Function dijkstraPath(g As Graph, source As String, dest As String) As Integer
|
||||
Dim As Integer changed, i, srcIdx, dstIdx, newDist, destIdx
|
||||
srcIdx = findVertex(g, source)
|
||||
If srcIdx >= 0 Then g.verts(srcIdx).dist = 0
|
||||
|
||||
Do
|
||||
changed = 0
|
||||
For i = 0 To g.edgeCount - 1
|
||||
With g.edges(i)
|
||||
srcIdx = findVertex(g, .src)
|
||||
dstIdx = findVertex(g, .dst)
|
||||
|
||||
If srcIdx >= 0 Andalso g.verts(srcIdx).dist <> INFINITY Then
|
||||
newDist = g.verts(srcIdx).dist + .cost
|
||||
If newDist < g.verts(dstIdx).dist Then
|
||||
g.verts(dstIdx).dist = newDist
|
||||
g.verts(dstIdx).prev = .src
|
||||
changed = 1
|
||||
End If
|
||||
End If
|
||||
End With
|
||||
Next
|
||||
Loop While changed
|
||||
|
||||
destIdx = findVertex(g, dest)
|
||||
Return Iif(destIdx >= 0, g.verts(destIdx).dist, INFINITY)
|
||||
End Function
|
||||
|
||||
Function getPath(g As Graph, source As String, dest As String) As String
|
||||
Dim As String path = "", current = dest
|
||||
Dim As Integer idx, destIdx, cost
|
||||
|
||||
' Build path backwards
|
||||
While current <> source
|
||||
idx = findVertex(g, current)
|
||||
If idx >= 0 Then
|
||||
path = " -> " & current & path
|
||||
current = g.verts(idx).prev
|
||||
End If
|
||||
Wend
|
||||
|
||||
' Get final cost
|
||||
destIdx = findVertex(g, dest)
|
||||
cost = Iif(destIdx >= 0, g.verts(destIdx).dist, INFINITY)
|
||||
|
||||
Return source & " " & dest & " : " & source & path & " cost : " & cost
|
||||
End Function
|
||||
|
||||
' Test program
|
||||
Dim As Edge testGraph(8) => {_
|
||||
("a", "b", 7), ("a", "c", 9), ("a", "f", 14), _
|
||||
("b", "c", 10), ("b", "d", 15), ("c", "d", 11), _
|
||||
("c", "f", 2), ("d", "e", 6), ("e", "f", 9)}
|
||||
|
||||
Dim As Graph g = createGraph(testGraph(), 9)
|
||||
Dim As String source = "a", dest = "e"
|
||||
|
||||
dijkstraPath(g, source, dest)
|
||||
Print getPath(g, source, dest)
|
||||
|
||||
Sleep
|
||||
|
|
@ -4,18 +4,25 @@ Module Dijkstra`s_algorithm {
|
|||
dim d(n)=val
|
||||
=d()
|
||||
}
|
||||
FillList=lambda (n) -> {
|
||||
m=list
|
||||
for i=1 to n: append m, i: next
|
||||
=m
|
||||
}
|
||||
// tree
|
||||
term=("",0)
|
||||
Edges=(("a", ("b",7),("c",9),("f",14)),("b",("c",10),("d",15)),("c",("d",11),("f",2)),("d",("e",6)),("e",("f", 9)),("f",term))
|
||||
//
|
||||
Document Doc$="Graph:"+{
|
||||
}
|
||||
ShowGraph()
|
||||
Doc$="Paths"+{
|
||||
}
|
||||
Print "Paths"
|
||||
For from_here=0 to 5
|
||||
For from_here=0 to Len(Edges)-1
|
||||
pa=GetArr(len(Edges), -1)
|
||||
d=GetArr(len(Edges), max_number)
|
||||
Inventory S=1,2,3,4,5,6
|
||||
S=FillList(len(Edges))
|
||||
return d, from_here:=0
|
||||
RemoveMin=Lambda S, d, max_number-> {
|
||||
ss=each(S)
|
||||
|
|
@ -0,0 +1,132 @@
|
|||
Module Dijkstra`s_algorithm {
|
||||
const max_number=1.E+306
|
||||
GetArr=lambda (n, val)->{
|
||||
dim d(n)=val
|
||||
=d()
|
||||
}
|
||||
FillList=lambda (n) -> {
|
||||
m=list
|
||||
for i=1 to n : append m, i :next
|
||||
=m
|
||||
}
|
||||
// tree
|
||||
class node {
|
||||
name$, val as long
|
||||
remove {
|
||||
created--
|
||||
print "Node removed, left: "+created
|
||||
}
|
||||
class:
|
||||
module node (.name$, .val) {
|
||||
created++
|
||||
print "New node, total: "+created
|
||||
}
|
||||
}
|
||||
global long created
|
||||
pNode = lambda ->{
|
||||
->node(![])
|
||||
}
|
||||
Class EdgeList {
|
||||
object Node[0]
|
||||
name$
|
||||
class:
|
||||
module EdgeList (.name$) {
|
||||
n=0
|
||||
while not empty
|
||||
read .Node[n]
|
||||
n++
|
||||
end while
|
||||
}
|
||||
}
|
||||
Node_A=EdgeList("a", pNode("b",7), pNode("c", 9), pNode("f",14) )
|
||||
Node_B=EdgeList("b",pNode("c",10),pNode("d",15))
|
||||
Node_C=EdgeList("c",pNode("d",11),pNode("f",2))
|
||||
Node_D=EdgeList("d",pNode("e",6))
|
||||
Node_E=EdgeList("e",pNode("f", 9))
|
||||
Node_F=EdgeList("f",pNode())
|
||||
Dim Edges(6)
|
||||
Edges(0)=Node_A, Node_B, Node_C, Node_D, Node_E, Node_F
|
||||
Document Doc$="Graph:"+{
|
||||
}
|
||||
ShowGraph()
|
||||
Doc$="Paths"+{
|
||||
}
|
||||
Print "Paths"
|
||||
For from_here=0 to Len(Edges())-1
|
||||
pa=GetArr(len(Edges()), -1)
|
||||
d=GetArr(len(Edges()), max_number)
|
||||
S=FillList(len(Edges()))
|
||||
return d, from_here:=0
|
||||
RemoveMin=Lambda S, d, max_number-> {
|
||||
ss=each(S)
|
||||
min=max_number
|
||||
p=0
|
||||
while ss
|
||||
val=d#val(eval(S,ss^)-1)
|
||||
if min>val then let min=val : p=ss^
|
||||
end while
|
||||
=s(p!) ' use p as index not key
|
||||
Delete S, eval(s,p)
|
||||
}
|
||||
Show_Distance_and_Path$=lambda$ d, pa, from_here, max_number (n) -> {
|
||||
ret1$=chr$(from_here+asc("a"))+" to "+chr$(n+asc("a"))
|
||||
if d#val(n) =max_number then =ret1$+ " No Path" :exit
|
||||
let ret$="", mm=n, m=n
|
||||
repeat
|
||||
n=m
|
||||
ret$+=chr$(asc("a")+n)
|
||||
m=pa#val(n)
|
||||
until from_here=n
|
||||
=ret1$+format$("{0::-4} {1}",d#val(mm),strrev$(ret$))
|
||||
}
|
||||
while len(s)>0
|
||||
u=RemoveMin()
|
||||
rem Print u, chr$(u-1+asc("a"))
|
||||
Relaxed()
|
||||
end while
|
||||
For i=0 to len(d)-1
|
||||
line$=Show_Distance_and_Path$(i)
|
||||
Print line$
|
||||
doc$=line$+{
|
||||
}
|
||||
next
|
||||
next
|
||||
Clipboard Doc$
|
||||
End
|
||||
Sub Relaxed()
|
||||
local vertex=Edges(u-1).node, i
|
||||
local e=Len(vertex)-1, val
|
||||
for i=0 to e
|
||||
for vertex[i] {
|
||||
if .name$<>"" then
|
||||
val=Asc(.name$)-Asc("a")
|
||||
if d#val(val)>.val+d#val(u-1) then return d, val:=.val+d#val(u-1) : Return Pa, val:=u-1
|
||||
end if
|
||||
}
|
||||
next
|
||||
end sub
|
||||
Sub ShowGraph()
|
||||
Print "Graph"
|
||||
local i
|
||||
for i=1 to len(Edges())
|
||||
show_edges(i)
|
||||
next
|
||||
end sub
|
||||
Sub show_edges(n)
|
||||
n--
|
||||
local line$, j
|
||||
for Edges(n) {
|
||||
for j=0 to len(.node)-1
|
||||
Print .name$;
|
||||
for .node[j] {
|
||||
if ..name$>"" then
|
||||
print "->"+..name$+" "+format$(" {0::-2}",..val)
|
||||
else
|
||||
print
|
||||
end if
|
||||
}
|
||||
next
|
||||
}
|
||||
end sub
|
||||
}
|
||||
Dijkstra`s_algorithm
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
type
|
||||
Edge = auto class
|
||||
start, &end: char;
|
||||
cost: real;
|
||||
end;
|
||||
|
||||
Graph = auto class
|
||||
edges: array of Edge;
|
||||
vertices: HashSet<char>;
|
||||
|
||||
constructor(params edges: array of (char, char, real));
|
||||
begin
|
||||
Self.edges := edges.Select(e -> new Edge(e[0], e[1], e[2])).ToArray;
|
||||
Self.vertices := new HashSet<char>(
|
||||
Self.edges.Select(e -> e.start) + Self.edges.Select(e -> e.end)
|
||||
);
|
||||
end;
|
||||
|
||||
function Dijkstra(source, dest: char): sequence of char;
|
||||
begin
|
||||
assert(vertices.Contains(source));
|
||||
|
||||
var inf := real.MaxValue;
|
||||
var dist := Dict(vertices.Select(v -> (v, inf)));
|
||||
var previous := Dict(vertices.Select(v -> (v, ' ')));
|
||||
dist[source] := 0;
|
||||
|
||||
var q := vertices.ToHashSet;
|
||||
var neighbours := Dict(vertices.Select(v -> (v, new HashSet<(char, real)>)));
|
||||
|
||||
foreach var edge in edges do
|
||||
begin
|
||||
neighbours[edge.start].Add((edge.end, edge.cost));
|
||||
neighbours[edge.end].Add((edge.start, edge.cost));
|
||||
end;
|
||||
|
||||
while q.Count > 0 do
|
||||
begin
|
||||
var u := q.MinBy(v -> dist[v]);
|
||||
q.Remove(u);
|
||||
|
||||
if (dist[u] = inf) or (u = dest) then
|
||||
break;
|
||||
|
||||
foreach var (v, cost) in neighbours[u] do
|
||||
begin
|
||||
var alt := dist[u] + cost;
|
||||
if alt < dist[v] then
|
||||
begin
|
||||
dist[v] := alt;
|
||||
previous[v] := u;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
var s := new List<char>;
|
||||
var u := dest;
|
||||
|
||||
while previous[u] <> ' ' do
|
||||
begin
|
||||
s.Insert(0, u);
|
||||
u := previous[u];
|
||||
end;
|
||||
|
||||
s.Insert(0, u);
|
||||
Result := s;
|
||||
end;
|
||||
end;
|
||||
|
||||
begin
|
||||
var gr := new Graph(
|
||||
('a', 'b', 7.0), ('a', 'c', 9.0), ('a', 'f', 14.0),
|
||||
('b', 'c', 10.0), ('b', 'd', 15.0), ('c', 'd', 11.0),
|
||||
('c', 'f', 2.0), ('d', 'e', 6.0), ('e', 'f', 9.0)
|
||||
);
|
||||
|
||||
gr.Dijkstra('a', 'e').Println;
|
||||
end.
|
||||
Loading…
Add table
Add a link
Reference in a new issue