示例#1
0
        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;
        }
示例#2
0
        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;
        }
示例#3
0
        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;
        }
示例#4
0
        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;
        }
示例#5
0
        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.
            }
示例#7
0
        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;
                }
            }