public static int Dijkstra(Vertex from, Vertex to, Graph graph) { HashSet<Vertex> visited = new HashSet<Vertex>(); Dictionary<Vertex, FibonacciHeap<int, Vertex>.Node> nodes = new Dictionary<Vertex, FibonacciHeap<int, Vertex>.Node>(); FibonacciHeap<int, Vertex> labels = new FibonacciHeap<int, Vertex>(); // Initialize labels. foreach (var vertex in graph.Vertices) { var n = labels.Add(vertex == from ? 0 : int.MaxValue, vertex); nodes.Add(vertex, n); } int currentLabel = int.MaxValue; while (!visited.Contains(to)) { var currentNode = labels.ExtractMin(); var current = currentNode.Value; currentLabel = currentNode.Key; // Consider all edges ending in unvisited neighbours var edges = graph.GetEdgesForVertex(current).Where(x => !visited.Contains(x.Other(current))); // Update labels on the other end. foreach (var edge in edges) { if (currentNode.Key + edge.Cost < nodes[edge.Other(current)].Key) labels.DecreaseKey(nodes[edge.Other(current)], currentNode.Key + edge.Cost); } visited.Add(current); } return currentLabel; }
public static Path DijkstraPath(Vertex from, Vertex to, Graph graph) { HashSet<Vertex> visited = new HashSet<Vertex>(); Dictionary<Vertex, FibonacciHeap<int, Vertex>.Node> nodes = new Dictionary<Vertex, FibonacciHeap<int, Vertex>.Node>(); Dictionary<Vertex, Edge> comingFrom = new Dictionary<Vertex, Edge>(); FibonacciHeap<int, Vertex> labels = new FibonacciHeap<int, Vertex>(); // Initialize labels. foreach (var vertex in graph.Vertices) { var n = labels.Add(vertex == from ? 0 : int.MaxValue, vertex); nodes.Add(vertex, n); comingFrom.Add(vertex, null); } while (!visited.Contains(to)) { var currentNode = labels.ExtractMin(); var current = currentNode.Value; // Consider all edges ending in unvisited neighbours var edges = graph.GetEdgesForVertex(current).Where(x => !visited.Contains(x.Other(current))); // Update labels on the other end. foreach (var edge in edges) { if (currentNode.Key + edge.Cost < nodes[edge.Other(current)].Key) { labels.DecreaseKey(nodes[edge.Other(current)], currentNode.Key + edge.Cost); comingFrom[edge.Other(current)] = edge; } } visited.Add(current); } // Now travel back, to find the actual path List<Edge> pathEdges = new List<Edge>(); Vertex pathVertex = to; while (pathVertex != from) { pathEdges.Add(comingFrom[pathVertex]); pathVertex = comingFrom[pathVertex].Other(pathVertex); } pathEdges.Reverse(); Path path = new Path(from); path.Edges.AddRange(pathEdges); return path; }
public static Dictionary<Vertex, Path> DijkstraPathToAll(Vertex from, Graph graph, bool onlyTerminals) { Dictionary<Vertex, Edge> comingFrom = new Dictionary<Vertex, Edge>(); HashSet<Vertex> visited = new HashSet<Vertex>(); Dictionary<Vertex, FibonacciHeap<int, Vertex>.Node> nodes = new Dictionary<Vertex, FibonacciHeap<int, Vertex>.Node>(); Dictionary<Vertex, Path> paths = new Dictionary<Vertex, Path>(); FibonacciHeap<int, Vertex> labels = new FibonacciHeap<int, Vertex>(); // Initialize labels. foreach (var vertex in graph.Vertices) { var n = labels.Add(vertex == from ? 0 : int.MaxValue, vertex); nodes.Add(vertex, n); } while (paths.Count < (onlyTerminals ? graph.Terminals.Count - 1 : graph.NumberOfVertices - 1)) { var currentNode = labels.ExtractMin(); var current = currentNode.Value; // Consider all edges ending in unvisited neighbours var edges = graph.GetEdgesForVertex(current).Where(x => !visited.Contains(x.Other(current))); // Update labels on the other end. foreach (var edge in edges) { if (currentNode.Key + edge.Cost < nodes[edge.Other(current)].Key) { labels.DecreaseKey(nodes[edge.Other(current)], currentNode.Key + edge.Cost); comingFrom[edge.Other(current)] = edge; } } visited.Add(current); if (current != from && (!onlyTerminals || graph.Terminals.Contains(current))) { // Travel back the path List<Edge> pathEdges = new List<Edge>(); Vertex pathVertex = current; while (pathVertex != from) { pathEdges.Add(comingFrom[pathVertex]); pathVertex = comingFrom[pathVertex].Other(pathVertex); } pathEdges.Reverse(); Path path = new Path(from); path.Edges.AddRange(pathEdges); paths[current] = path; } } return paths; }
public static List<Path> NearestTerminals(Vertex from, Graph graph, int n) { List<Path> foundPaths = new List<Path>(); HashSet<Vertex> visited = new HashSet<Vertex>(); Dictionary<Vertex, FibonacciHeap<int, Vertex>.Node> nodes = new Dictionary<Vertex, FibonacciHeap<int, Vertex>.Node>(); FibonacciHeap<int, Vertex> labels = new FibonacciHeap<int, Vertex>(); Dictionary<Vertex, Edge> comingFrom = new Dictionary<Vertex, Edge>(); if (graph.Terminals.Contains(from)) foundPaths.Add(new Path(from)); // Initialize labels. foreach (var vertex in graph.Vertices) { var node = labels.Add(vertex == from ? 0 : int.MaxValue, vertex); nodes.Add(vertex, node); comingFrom.Add(vertex, null); } while (!labels.IsEmpty() && foundPaths.Count < n) { var currentNode = labels.ExtractMin(); var current = currentNode.Value; // Consider all edges ending in unvisited neighbours var edges = graph.GetEdgesForVertex(current).Where(x => !visited.Contains(x.Other(current))); // Update labels on the other end. foreach (var edge in edges) { if (currentNode.Key + edge.Cost < nodes[edge.Other(current)].Key) { labels.DecreaseKey(nodes[edge.Other(current)], currentNode.Key + edge.Cost); comingFrom[edge.Other(current)] = edge; } } visited.Add(current); if (graph.Terminals.Contains(current) && current != from) { // Now travel back, to find the actual path List<Edge> pathEdges = new List<Edge>(); Vertex pathVertex = current; while (pathVertex != from) { pathEdges.Add(comingFrom[pathVertex]); pathVertex = comingFrom[pathVertex].Other(pathVertex); } pathEdges.Reverse(); Path path = new Path(from); path.Edges.AddRange(pathEdges); foundPaths.Add(path); } } return foundPaths; }
private void ProcessData(Tuple <Stack <byte>, Stack <Stack <int> > > data) { var sw = Stopwatch.StartNew(); var commands = data.Item1; var arguments = data.Item2; int argOffset = 0; int listOffset = 0; // Prepare the heap var heap = new FibonacciHeap <int, int>(); int insertCount = GetNextArg(ref argOffset, arguments, ref listOffset); NodeItem <int, int>[] insertedNodes = new NodeItem <int, int> [insertCount]; int deleteDepthCount = 0; int deleteCount = 0; // Do insert commands int id = 0, key = 0; NodeItem <int, int> node; foreach (byte command in commands) { if (command != DelKey) { id = GetNextArg(ref argOffset, arguments, ref listOffset); key = GetNextArg(ref argOffset, arguments, ref listOffset); } switch (command) { case InsKey: node = heap.Add(key, id); Debug.Assert(insertedNodes[id] == null); insertedNodes[id] = node; break; case DelKey: node = heap.PeekMin(); Debug.Assert(insertedNodes[node.Value] != null); insertedNodes[node.Value] = null; heap.DeleteMin(); deleteDepthCount += heap.LastConsolidateDepth; deleteCount++; break; case DecKey: node = insertedNodes[id]; if (node == null || key > node.Key) { break; } heap.DecreaseKey(node, key); break; } } // Cleanup and store the measurements //heap.Clear(); // Disassembles tree node pointers .... not a good idea with a GC... sw.Stop(); float avgDeleteDepthCount = 0; if (deleteCount > 0) { avgDeleteDepthCount = deleteDepthCount / (float)deleteCount; } lock (_results) _results.Add(deleteCount, avgDeleteDepthCount); Interlocked.Increment(ref _currentJobsDone); Log("{0}/{1} done/waiting :: {2:F} sec :: {3} inserts :: {4}/{5:F} deletes/delete depth average", _currentJobsDone, Buffer.WaitingItemCount, sw.ElapsedMilliseconds * 0.001, insertCount, deleteCount, avgDeleteDepthCount); }
public void AddVertexToInterleavingDijkstra(Vertex vertex, Graph graph) { if (_verticesInSearch.Contains(vertex)) throw new InvalidOperationException("Can not add the vertex, because it is already added."); _verticesInSearch.Add(vertex); var labels = new FibonacciHeap<int, Vertex>(); var nodes = new Dictionary<Vertex, FibonacciHeap<int, Vertex>.Node>(); // Initialize labels. foreach (var v in graph.Vertices) { var node = labels.Add(v == vertex ? 0 : int.MaxValue, v); nodes.Add(v, node); } _dictLabels.Add(vertex, labels); _dictNodes.Add(vertex, nodes); _dictVisited.Add(vertex, new HashSet<Vertex>()); _dictPathsfound.Add(vertex, new Dictionary<Vertex, Path>()); _dictComingFrom.Add(vertex, new Dictionary<Vertex, Edge>()); _dictComponent.Add(vertex, ++_internalNewComponentCount); // All vertices start in a different component. }
private List <TraceEvent> Sort1007(IDictionary <int, List <TraceEvent> > rawBatches) { var pending = 0; Span <EventBatch> batches = new EventBatch[rawBatches.Count]; var result = new List <TraceEvent>(); foreach (var(i, eventList) in rawBatches.Values.Select((val, i) => (i, val))) { pending += eventList.Count; batches[i] = new EventBatch(eventList, false); } using var totalProgress = _registry?.Start("Sort Events", "Sort events based on states transition"); var gs = new Dictionary <ulong, GState>(); var frontier = new FibonacciHeap <OrderEvent>(); var totalCount = pending; using (var progress = _registry?.Start("Reorganize events", "Reorganize events based on relationship", totalProgress)) { for (; pending != 0; pending--) { if (!(progress is null)) { progress.PercentComplete = (totalCount - pending) / (float)totalCount; } for (var i = 0; i < rawBatches.Count; i++) { ref var b = ref batches[i]; if (b.Selected || !b.HasMore()) { continue; } var ev = b.Head; var(g, init, next) = StateTransition(ev); if (!TransitionReady(g, gs.GetValueOrDefault(g), init)) { continue; } frontier.Add(new OrderEvent(ev, i, g, init, next)); b.MoveNext(); b.Selected = true; switch (ev.Type) { case EventType.GoStartLocal: ev.Type = EventType.GoStart; break; case EventType.GoUnblockLocal: ev.Type = EventType.GoUnblock; break; case EventType.GoSysExitLocal: ev.Type = EventType.GoSysExit; break; } } if (frontier.Count == 0) { throw new InvalidTraceException("no consistent ordering of events possible"); } var f = frontier.Pop(); Transition(gs, f.G, f.Init, f.Next); result.Add(f.Event); if (!batches[f.Batch].Selected) { throw new Exception("frontier batch is not selected"); } batches[f.Batch].Selected = false; } }