public void MSAGLAstarSSSP(Vertex[] vList, Edge[,] eList, int[] degList, int source, Dictionary <Node, int> 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) { Debug.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 static void MsaglShortcutShortEdges(Tiling g, Dictionary <int, Node> idToNodes, LgLayoutSettings _lgLayoutSettings) { int unit = (int)_lgLayoutSettings.NodeSeparation; int shortcutcount = 1; int iteration = 10; //Console.WriteLine(); //Console.WriteLine("Minimize the number of railes for quick interaction? (Y/N)"); //string input = Console.ReadLine(); if (_lgLayoutSettings.hugeGraph) { iteration = 1; unit *= 5; } while (shortcutcount > 0 && iteration > 0) { iteration--; //for all vertices that are not real vertices for (int index = g.N; index < g.NumOfnodesBeforeDetour; index++) { //current vertex is w Vertex w = g.VList[index]; //for each neighbor of w for (int k = 0; k < g.DegList[w.Id]; k++) { Vertex neighbor = g.VList[g.EList[w.Id, k].NodeId]; //if neighbor is a real vertex then continue if (neighbor.Id < g.N) { continue; } //else check whether the edge is short double l = g.GetEucledianDist(w.Id, neighbor.Id); //if the length is short engough then short-cut if (l < unit) { //shortcut this edge //take all the neighbors of the 'neighbor' into the modification list List <int> modificationList = new List <int>(); for (int j = 0; j < g.DegList[neighbor.Id]; j++) { int id = g.EList[neighbor.Id, j].NodeId; if (id != w.Id) { modificationList.Add(id); } } //check whether it is safe to modify the graph bool safetomodify = true; if (g.DegList[w.Id] + modificationList.Count >= g.maxDeg) { continue; } foreach (var x in modificationList) { if (g.DegList[x] + 1 >= g.maxDeg) { safetomodify = false; } } foreach (var x in modificationList) { if (g.Crossings(w.Id, x)) { safetomodify = false; } } if (!safetomodify) { continue; } //add edges between w and the neighbor's neighbor foreach (var x in modificationList) { g.AddEdge(w.Id, x); } g.RemoveEdge(w.Id, neighbor.Id); shortcutcount++; } } } unit *= 2; } Console.WriteLine("Shortcut made for " + shortcutcount + " edges"); }