using System; using System.Collections.Generic; using Microsoft.Msagl.Core.DataStructures; using Microsoft.Msagl.Core.Layout; namespace Microsoft.Msagl.GraphmapsWithMesh { class DijkstraAlgo { public List Edgelist = new List(); public List ShortestPath = new List(); public double Distance; public bool PathExists = true; public Vertex getMin(List q) { double m = double.MaxValue; Vertex temp_vertex = null; foreach (Vertex w in q) { if (m > w.Dist) { m = w.Dist; temp_vertex = w; } } if (temp_vertex == null) { Console.WriteLine("Graph is disconnected"); return null; } foreach (Vertex w in q) { if (w.Id == temp_vertex.Id) { q.Remove(temp_vertex); break; } } return temp_vertex; } public void SelectShortestPath(Vertex[] vList, Edge[,] eList, int[] degList, int source, int target, int n) { List q = new List(); vList[source].Dist = 0; q.Add(vList[source]); for (int i = 1; i <= n; i++) { if (vList[i].Id != vList[source].Id) { vList[i].Dist = double.MaxValue; q.Add(vList[i]); } vList[i].Parent = null; vList[i].Visited = false; } Edgelist.Clear(); Distance = 0; while (q.Count > 0) { Vertex u = getMin(q); if (u.Visited) continue; else u.Visited = true; for (int neighb = 1; neighb <= degList[u.Id]; neighb++) { var neighbor = eList[u.Id, neighb].NodeId; int discourage = 0; if (eList[u.Id, neighb].Selected == 0) discourage = 1000;//continue; if (vList[eList[u.Id, neighb].NodeId].Weight > 0 && eList[u.Id, neighb].NodeId != vList[target].Id) continue; var temp = u.Dist + eList[u.Id, neighb].GetEDist(vList, u.Id, eList[u.Id, neighb].NodeId) + discourage; if (temp < vList[neighbor].Dist) { vList[neighbor].Dist = temp; vList[neighbor].Parent = u; //Update(q, vList[neighbor]); } } if (u.Id == vList[target].Id) break; } Vertex route = vList[target]; //Console.WriteLine(); //Console.WriteLine("Source,Target" + source + " " + target); while (route.Parent != null) { //Console.Write(route.Id+" "); for (int neighb = 1; neighb <= degList[route.Id]; neighb++) if (eList[route.Id, neighb].NodeId == route.Parent.Id) { Edgelist.Add(new VertexNeighbor(route.Id, neighb)); Distance += Math.Sqrt((route.XLoc - route.Parent.XLoc) * (route.XLoc - route.Parent.XLoc) + (route.YLoc - route.Parent.YLoc) * (route.YLoc - route.Parent.YLoc)); break; } for (int neighb = 1; neighb <= degList[route.Parent.Id]; neighb++) if (eList[route.Parent.Id, neighb].NodeId == route.Id) { Edgelist.Add(new VertexNeighbor(route.Parent.Id, neighb)); break; } route = route.Parent; } //Console.Write(route.Id + " "); if (route.Id != vList[source].Id) Console.WriteLine("path not found"); } public List MSAGLAstarShortestPath(Vertex[] vList, Edge[,] eList, int[] degList, int source, int target, int n) { var q = new BinaryHeapPriorityQueue(n); vList[source].Dist = 0; vList[source].Weight = vList[source].Dist + MsaglUtilities.EucledianDistance( vList[source].XLoc, vList[source].YLoc, vList[target].XLoc, vList[target].YLoc); q.Enqueue(source, vList[source].Weight); for (int i = 0; i < n; i++) { if (vList[i].Id != source) { vList[i].Dist = double.MaxValue; vList[i].Weight = double.MaxValue; q.Enqueue(i, vList[i].Weight); } vList[i].Parent = null; vList[i].Visited = false; } Edgelist.Clear(); ShortestPath.Clear(); Distance = 0; while (q.Count > 0) { var deq = q.Dequeue(); Vertex u = vList[deq]; u.Visited = true; if (u == null || u.Invalid) return new List(); for (int neighb = 0; neighb < degList[u.Id]; neighb++) { var neighborId = eList[u.Id, neighb].NodeId; int discourage = 0; if (eList[u.Id, neighb].Selected == 1) discourage = 1000;//continue; if (eList[u.Id, neighb].NodeId == source || eList[u.Id, neighb].NodeId == target) discourage = 0; if (u.Id == source || u.Id == target) discourage = 0; Vertex neighbor = vList[neighborId]; double edist = MsaglUtilities.EucledianDistance(u.XLoc, u.YLoc, neighbor.XLoc, neighbor.YLoc); var tempDist = u.Dist + edist + discourage; if (tempDist >= neighbor.Dist) continue; neighbor.Dist = tempDist; var tempWeight = neighbor.Dist + MsaglUtilities.EucledianDistance(vList[target].XLoc, vList[target].YLoc, neighbor.XLoc, neighbor.YLoc); neighbor.Weight = tempWeight; neighbor.Parent = u; if (neighbor.Visited) { neighbor.Visited = false; q.Enqueue(neighbor.Id, neighbor.Weight); } else q.DecreasePriority(neighbor.Id, neighbor.Weight); } if (u.Id == target) break; } Vertex route = vList[target]; int zoomlevel = Math.Max(vList[source].ZoomLevel, vList[target].ZoomLevel); while (route.Parent != null) { ShortestPath.Add(route.Id); for (int neighb = 0; neighb < degList[route.Id]; neighb++) if (eList[route.Id, neighb].NodeId == route.Parent.Id) { SetUsed(vList, eList, degList, route.Id, eList[route.Id, neighb].NodeId, zoomlevel); Edgelist.Add(new VertexNeighbor(route.Id, neighb)); Distance += Math.Sqrt((route.XLoc - route.Parent.XLoc) * (route.XLoc - route.Parent.XLoc) + (route.YLoc - route.Parent.YLoc) * (route.YLoc - route.Parent.YLoc)); break; } route = route.Parent; } ShortestPath.Add(route.Id); if (route.Id != source) Console.WriteLine("path not found"); return ShortestPath; } public void MSAGLGreedy(Vertex[] vList, Edge[,] eList, int[] degList, int source, int target, int n) { for (int i = 0; i < n; i++) { vList[i].Parent = null; vList[i].Visited = false; } Edgelist.Clear(); ShortestPath.Clear(); Distance = 0; Vertex currentVertex = vList[source]; int bestN; double bestD, temp, discourage=0; while (true) { if (currentVertex == null || currentVertex.Invalid) return; currentVertex.Visited = true; bestD = Double.MaxValue; bestN = -1; for (int neighb = 0; neighb < degList[currentVertex.Id]; neighb++) { var neighbor = eList[currentVertex.Id, neighb].NodeId; if (vList[neighbor].Visited) continue; if (eList[currentVertex.Id, neighb].Selected == 1) discourage = 1000; //continue; else discourage = 0; temp = MsaglUtilities.EucledianDistance(vList[neighbor].XLoc, vList[neighbor].YLoc, vList[target].XLoc, vList[target].YLoc) + discourage; if (temp < bestD) { bestD = temp; bestN = neighbor; } } if (currentVertex.Id == target) break; if (bestN == -1) { MSAGLAstarShortestPath(vList, eList, degList, source, target, n); //Console.Write('*'); return; } vList[bestN].Parent = currentVertex; currentVertex = vList[bestN]; } Vertex route = vList[target]; int zoomlevel = Math.Max(vList[source].ZoomLevel, vList[target].ZoomLevel); while (route.Parent != null) { ShortestPath.Add(route.Id); for (int neighb = 0; neighb < degList[route.Id]; neighb++) if (eList[route.Id, neighb].NodeId == route.Parent.Id) { SetUsed(vList, eList, degList, route.Id, eList[route.Id, neighb].NodeId, zoomlevel); Edgelist.Add(new VertexNeighbor(route.Id, neighb)); break; } route = route.Parent; } ShortestPath.Add(route.Id); if (route.Id != source) Console.WriteLine("path not found"); return; } public void MSAGLAstarSSSP(Vertex[] vList, Edge[,] eList, int[] degList, int source, Dictionary nodeId, GeometryGraph _mainGeometryGraph, int NofNodesBeforeDetour, int n, Tiling g, Tiling g1) { var q = new BinaryHeapPriorityQueue(n); vList[source].Dist = 0; q.Enqueue(source, vList[source].Dist); for (int i = 0; i < n; i++) { if (vList[i].Id != source) { vList[i].Dist = double.MaxValue; q.Enqueue(i, vList[i].Dist); } vList[i].Parent = null; vList[i].Visited = false; } Distance = 0; while (q.Count > 0) { var deq = q.Dequeue(); Vertex u = vList[deq]; u.Visited = true; if (u == null || u.Invalid) return; for (int neighb = 0; neighb < degList[u.Id]; neighb++) { var neighborId = eList[u.Id, neighb].NodeId; int discourage = 0; if (u.Id < NofNodesBeforeDetour && u.Id != source) discourage = 1000; Vertex neighbor = vList[neighborId]; double edist = MsaglUtilities.EucledianDistance(u.XLoc, u.YLoc, neighbor.XLoc, neighbor.YLoc); var tempDist = u.Dist + edist + discourage; if (tempDist >= neighbor.Dist) continue; neighbor.Dist = tempDist; neighbor.Parent = u; if (neighbor.Visited) { neighbor.Visited = false; q.Enqueue(neighbor.Id, neighbor.Dist); } else q.DecreasePriority(neighbor.Id, neighbor.Dist); } } foreach (var node in _mainGeometryGraph.Nodes) { int target = nodeId[node]; if (target == source) continue; Vertex route = vList[target]; int zoomlevel = Math.Max(vList[source].ZoomLevel, vList[target].ZoomLevel); Edgelist.Clear(); while (route.Parent != null) { ShortestPath.Add(route.Id); for (int neighb = 0; neighb < degList[route.Id]; neighb++) if (eList[route.Id, neighb].NodeId == route.Parent.Id) { SetUsed(vList, eList, degList, route.Id, eList[route.Id, neighb].NodeId, zoomlevel); Edgelist.Add(new VertexNeighbor(route.Id, neighb)); break; } route = route.Parent; } if (route.Id != source) Console.WriteLine("path not found"); foreach (VertexNeighbor vn in Edgelist) g1.AddEdge(vn.A, g.EList[vn.A, vn.Neighbor].NodeId, g.EList[vn.A, vn.Neighbor].Selected, g.EList[vn.A, vn.Neighbor].Used); } return; } public void MSAGLSelectShortestPath(Vertex[] vList, Edge[,] eList, int[] degList, int source, int target, int n) { List q = new List(); vList[source].Dist = 0; q.Add(vList[source]); for (int i = 0; i < n; i++) { if (vList[i].Id != source) { vList[i].Dist = double.MaxValue; q.Add(vList[i]); } vList[i].Parent = null; vList[i].Visited = false; } Edgelist.Clear(); Distance = 0; while (q.Count > 0) { Vertex u = getMin(q); if (u == null) return; if (u.Visited) continue; else u.Visited = true; for (int neighb = 0; neighb < degList[u.Id]; neighb++) { var neighbor = eList[u.Id, neighb].NodeId; if (vList[neighbor].Visited) continue; int discourage = 0; if (eList[u.Id, neighb].Selected == 1) discourage = 1000;//continue; if (eList[u.Id, neighb].NodeId == source || eList[u.Id, neighb].NodeId == target) discourage = 0; if (u.Id == source || u.Id == target) discourage = 0; var temp = u.Dist + eList[u.Id, neighb].GetEDist(vList, u.Id, eList[u.Id, neighb].NodeId) + discourage; if (temp < vList[neighbor].Dist) { vList[neighbor].Dist = temp; vList[neighbor].Parent = u; //Update(q, vList[neighbor]); } } if (u.Id == target) break; } Vertex route = vList[target]; //Console.WriteLine(); //Console.WriteLine("Source,Target" + source + " " + target); while (route.Parent != null) { //Console.Write(route.Id+" "); for (int neighb = 0; neighb < degList[route.Id]; neighb++) if (eList[route.Id, neighb].NodeId == route.Parent.Id) { SetUsed(vList, eList, degList, route.Id, eList[route.Id, neighb].NodeId, 1); Edgelist.Add(new VertexNeighbor(route.Id, neighb)); Distance += Math.Sqrt((route.XLoc - route.Parent.XLoc) * (route.XLoc - route.Parent.XLoc) + (route.YLoc - route.Parent.YLoc) * (route.YLoc - route.Parent.YLoc)); break; } /* for (int neighb = 0; neighb < degList[route.Parent.Id]; neighb++) if (eList[route.Parent.Id, neighb].NodeId == route.Id) { SetUsed(vList, eList, degList, route.Parent.Id, eList[route.Parent.Id, neighb].NodeId); Edgelist.Add(new VertexNeighbor(route.Parent.Id, neighb)); break; } * */ route = route.Parent; } //Console.Write(route.Id + " "); if (route.Id != source) Console.WriteLine("path not found"); } public void SetUsed(Vertex[] vList, Edge[,] eList, int[] degList, int a, int b, int zoomlevel) { for (int index = 0; index < degList[a]; index++) { if (eList[a, index].NodeId == b) { if (eList[a, index].Used > 0) return; else eList[a, index].Used = zoomlevel; } } for (int index = 0; index < degList[b]; index++) { if (eList[b, index].NodeId == a) { if (eList[b, index].Used > 0) return; else eList[b, index].Used = zoomlevel; } } } /* public void SelectShortestPath(Vertex [] vList, Edge [,] eList, int [] degList, int source, int target,int n){ PriorityQueue q = new PriorityQueue(); vList[source].Dist = 0; q.Enqueue(vList[source].Dist, vList[source]); for (int i = 1; i <= n; i++) { if ( vList[i].Id != vList[source].Id) { vList[i].Dist = double.MaxValue; q.Enqueue(vList[i].Dist, vList[i]); } vList[i].Parent = null; vList[i].Visited = false; } Edgelist.Clear(); Distance = 0; while (q.Count > 0) { Vertex u = q.Dequeue().Value; if (u.Visited) continue; else u.Visited = true; for (int neighb = 1; neighb <= degList[u.Id]; neighb++) { var neighbor = eList[u.Id,neighb].NodeId; int discourage = 0; if (eList[u.Id, neighb].Selected == 0) discourage = 10000;//continue; if (vList[eList[u.Id, neighb].NodeId].Weight> 0 && eList[u.Id, neighb].NodeId != target) continue; var temp = u.Dist + eList[u.Id, neighb].getEDist(vList, u.Id, eList[u.Id, neighb].NodeId) + discourage; if (temp < vList[neighbor].Dist) { vList[neighbor].Dist = temp; vList[neighbor].Parent = u; q.Enqueue(vList[neighbor].Dist, vList[neighbor]); } } if (u.Id ==vList[target].Id) break; } Vertex route = vList[target]; while (route.Parent != null) { for (int neighb = 1; neighb <= degList[route.Id]; neighb++) if (eList[route.Id, neighb].NodeId == route.Parent.Id){ //eList[route.ID, neighb].selected = 1; Edgelist.Add(new VertexNeighbor(route.Id, neighb)); Distance += Math.Sqrt((route.XLoc - route.Parent.XLoc) * (route.XLoc - route.Parent.XLoc) + (route.YLoc - route.Parent.YLoc) * (route.YLoc - route.Parent.YLoc)); //encourage reusing of path by decreasing weight //if (eList[route.ID, neighb].weight == 1) eList[route.ID, neighb].weight /= 2; break; } for (int neighb = 1; neighb <= degList[route.Parent.Id]; neighb++) if (eList[route.Parent.Id, neighb].NodeId == route.Id) { //eList[route.parent.ID, neighb].selected = 1; Edgelist.Add(new VertexNeighbor(route.Parent.Id, neighb)); //encourage reusing of path by decreasing weight //if (eList[route.parent.ID, neighb].weight == 1) eList[route.parent.ID, neighb].weight /= 2; break; } route = route.Parent; } if(route.Id != source) Console.WriteLine("path not found"); } */ } public class VertexNeighbor { public int A; public int Neighbor; public VertexNeighbor(int p, int q) { A = p; Neighbor = q; } } }