Пример #1
0
        public T RemoveMin()
        {
            FibonacciHeapNode <T, TKey> popped = Heap.RemoveMin();

            ObjectToHeapNodeMapping.Remove(popped.Data);

            return(popped.Data);
        }
        /// <summary>
        /// Implementation of Yen's algorithm which finds the shortest path between nodes, and then the
        /// K-1 shortest deviations from this path. Paths returned will be simple and loopless
        /// </summary>
        /// <param name="K">The number of shortest paths to find.</param>
        /// <param name="source">The node on which to start the search</param>
        /// <param name="destination">The node we try to find the shortest path to, starting from source</param>
        /// <returns></returns>
        public List <List <int> > KShortestPaths(int K, int source, int destination)
        {
            List <List <int> > ShortestPaths = new List <List <int> >();
            var PotentialPaths = new FibonacciHeap <List <int>, double>(0);

            ShortestPaths.Add(LeastCostPath(source, destination));

            //now find next K-1 shortest paths
            foreach (int k in Enumerable.Range(1, K - 1))
            {
                //The spur node ranges from the first node to the next to last node in the previous k-shortest path.
                int spurNodeCount = ShortestPaths[k - 1].Count - 1;
                foreach (int i in Enumerable.Range(0, spurNodeCount))
                {
                    int               spurNode     = ShortestPaths[k - 1][i];
                    List <int>        rootPath     = ShortestPaths[k - 1].GetRange(0, i + 1);
                    PSO_WeightedGraph AlteredGraph = this.Clone();

                    //temporarily remove edges to avoid retracing our steps
                    foreach (List <int> shortPath in ShortestPaths)
                    {
                        if (rootPath.SequenceEqual(shortPath.Take(i + 1)))
                        {
                            AlteredGraph.AdjacencyMatrix[shortPath[i], shortPath[i + 1]] = 0;
                        }
                    }

                    //To avoid looping back over a previous path, we disconnect nodes in the root path (except the spur node)
                    //by setting the weights of the edges that connect them to the graph to 0
                    foreach (int x in Enumerable.Range(0, Size).Where(a => a != spurNode & rootPath.Contains(a)))
                    {
                        var v = Vector <double> .Build.Sparse(Size);

                        AlteredGraph.AdjacencyMatrix.SetColumn(x, v);
                        AlteredGraph.AdjacencyMatrix.SetRow(x, v);
                    }

                    //build spur path and connect the spur path to the root
                    List <int> spurPath = new List <int>();
                    //finding the least cost path may fail due to removing the edges above; just ignore and continue
                    try { spurPath = AlteredGraph.LeastCostPath(spurNode, destination); }
                    catch (Exception ex) { break; }

                    List <int> totalPath = rootPath;
                    totalPath.AddRange(spurPath.Where(node => node != spurNode).ToList());
                    PotentialPaths.Insert(new FibonacciHeapNode <List <int>, double>(totalPath, this.PathCost(totalPath)));
                }

                if (PotentialPaths.IsEmpty())
                {
                    break;
                }

                ShortestPaths.Add(PotentialPaths.RemoveMin().Data);
            }

            return(ShortestPaths);
        }
        /// <summary>
        /// Implementation of uniform-cost search algorithm using a Fibonacci heap data structure to minimize computing times
        /// </summary>
        /// <param name="source">The node on which to start the search</param>
        /// <param name="destination">The node we try to find the shortest path to, starting from source</param>
        public List <int> LeastCostPath(int source, int destination)
        {
            var Predecessor = new Dictionary <int, int>();
            var Distance    = new Dictionary <int, double>();
            var Frontier    = new FibonacciHeap <int, double>(0);

            Frontier.Insert(new FibonacciHeapNode <int, double>(source, 0));
            var Explored = new List <int>();

            Predecessor.Add(source, -1); //value of -1 indicates this node has no predecessors

            while (true)
            {
                if (Frontier.IsEmpty())
                {
                    throw new Exception("LeastCostPath: Failed to find path between source (" + source + ") and destination (" + destination + ").");
                }

                var minNode = Frontier.RemoveMin();
                if (minNode.Data == destination)
                {
                    List <int> LCP = new List <int> {
                        minNode.Data
                    };
                    int pred = Predecessor[minNode.Data];
                    while (pred != -1)
                    {
                        LCP.Add(pred);
                        pred = Predecessor[pred];
                    }
                    LCP.Reverse();
                    return(LCP);
                }

                Explored.Add(minNode.Data);
                foreach (int neighbor in this.GetNeighbors(minNode.Data))
                {
                    if (!Explored.Contains(neighbor))
                    {
                        var neighborCost = minNode.Key + AdjacencyMatrix[minNode.Data, neighbor];
                        Frontier.Insert(new FibonacciHeapNode <int, double>(neighbor, neighborCost));
                        if (Distance.TryGetValue(neighbor, out double cost))
                        {
                            if (neighborCost < cost)
                            {
                                Predecessor[neighbor] = minNode.Data;
                                Distance[neighbor]    = neighborCost;
                            }
                        }
                        else
                        {
                            Predecessor.Add(neighbor, minNode.Data);
                            Distance.Add(neighbor, neighborCost);
                        }
                    }
                }
            }
        }
Пример #4
0
        public List <(TVertex Vertex, EdgeBase <TVertex> EdgeToParent)> FindShortestPathWithDijkstra(TVertex start, TVertex end)
        {
            var vertexInfoDict = Vertices.Select(vertex => new DijkstraVertexInfo(vertex, vertex == start ? 0 : double.PositiveInfinity))
                                 .Select(info => new FibonacciHeapNode <DijkstraVertexInfo>(info, info.Distance))
                                 .ToDictionary(node => node.Data.Vertex, node => node);

            var heap = new FibonacciHeap <DijkstraVertexInfo>();

            heap.InsertRange(vertexInfoDict.Values);


            DijkstraVertexInfo endInfo = null;

            while (vertexInfoDict.Count > 0)
            {
                var curVertexInfo = heap.RemoveMin().Data;
                if (curVertexInfo.Vertex == end)
                {
                    endInfo = curVertexInfo;
                    break;
                }

                var neighborsWithEdges = GetNeighborsWithEdges(curVertexInfo.Vertex, ignoreSelfLoops: true);
                foreach (var neighborsWithEdge in neighborsWithEdges)
                {
                    if (vertexInfoDict.TryGetValue(neighborsWithEdge.Vertex, out FibonacciHeapNode <DijkstraVertexInfo> neighborNode))
                    {
                        var alt          = curVertexInfo.Distance + neighborsWithEdge.Edge.Weight ?? 1;
                        var neighborInfo = neighborNode.Data;
                        if (alt < neighborInfo.Distance)
                        {
                            heap.DecreaseKey(neighborNode, alt);
                            neighborInfo.Distance   = alt;
                            neighborInfo.Parent     = curVertexInfo;
                            neighborInfo.ParentEdge = neighborsWithEdge.Edge;
                        }
                    }
                }
            }

            if (endInfo != null)
            {
                var reslut    = new List <(TVertex Vertex, EdgeBase <TVertex> EdgeToParent)>();
                var curVertex = endInfo;
                while (curVertex != null)
                {
                    reslut.Add((curVertex.Vertex, curVertex.ParentEdge));
                    curVertex = curVertex.Parent;
                }
                reslut.Reverse();
                return(reslut);
            }

            return(null);
        }
Пример #5
0
        public static DijkstraTile[,] Dijkstra(IEnumerable <Point> start, int width, int height, double maxDist, Func <Point, Point, double> length, Func <Point, IEnumerable <Point> > neighbors)
        {
            var dijkstraMap = new DijkstraTile[width, height];
            var nodeMap     = new FibonacciHeapNode <DijkstraTile, double> [width, height];
            var heap        = new FibonacciHeap <DijkstraTile, double>(0);

            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    Point        tile    = new Point(x, y);
                    bool         isStart = start.Contains(tile);
                    DijkstraTile dTile   = new DijkstraTile(tile, isStart ? 0 : double.PositiveInfinity, isStart ? 0 : double.PositiveInfinity);
                    var          node    = new FibonacciHeapNode <DijkstraTile, double>(dTile, dTile.Distance);
                    dijkstraMap[x, y] = dTile;
                    nodeMap[x, y]     = node;
                    heap.Insert(node);
                }
            }

            while (!heap.IsEmpty())
            {
                var node  = heap.RemoveMin();
                var dTile = node.Data;

                if (dTile.Distance >= maxDist)
                {
                    break;
                }

                foreach (var neighbor in neighbors(dTile.Tile))
                {
                    if (neighbor.X < 0 || neighbor.Y < 0 || neighbor.X >= width || neighbor.Y >= height)
                    {
                        continue;
                    }
                    var    nodeNeighbor = nodeMap[neighbor.X, neighbor.Y];
                    var    dNeighbor    = nodeNeighbor.Data;
                    double newDist      = dTile.Distance + length(dTile.Tile, dNeighbor.Tile);

                    if (newDist < dNeighbor.Distance)
                    {
                        dNeighbor.Distance     = newDist;
                        dNeighbor.Previous     = dTile;
                        dNeighbor.MoveDistance = dTile.MoveDistance + 1;
                        heap.DecreaseKey(nodeNeighbor, dNeighbor.Distance);
                    }
                }
            }

            return(dijkstraMap);
        }
Пример #6
0
        public static List <Node> Dijkstras(Graph graph, Vector2 sourceVect, Vector2 goalVect)
        {
            Node        source = null;
            Node        goal   = null;
            Node        expandedNode;
            List <Node> finalizedSet = new List <Node>();
            FibonacciHeap <Node, float> prioQueue = new FibonacciHeap <Node, float>(0);

            foreach (Node node in graph.Nodes)
            {
                node.Distance = 1f / 0f;
                node.SetPredecessor(graph.Nodes, null);
                if (node.MapPos == sourceVect)
                {
                    source = node;
                }
                else
                {
                    prioQueue.Insert(new FibonacciHeapNode <Node, float>(node, node.Distance));
                }
                if (node.MapPos == goalVect)
                {
                    goal = node;
                }
            }
            source.Distance = 0;
            prioQueue.Insert(new FibonacciHeapNode <Node, float>(source, source.Distance));

            while (prioQueue.Size() != 0)
            {
                expandedNode = prioQueue.RemoveMin().Data;
                finalizedSet.Add(expandedNode);
                foreach (Node node in graph.Adj[expandedNode])
                {
                    if (node.Distance > expandedNode.Distance + 1)
                    {
                        node.Distance = expandedNode.Distance + 1;
                        node.SetPredecessor(graph.Nodes, expandedNode);
                    }
                }
            }

            return(BuildPath(graph, source, goal));
        }
Пример #7
0
        public void min()
        {
            var heap = new FibonacciHeap <int, double>(0);
            var node = new FibonacciHeapNode <int, double>(-1, 0);

            heap.Insert(node);
            while (!heap.IsEmpty())
            {
                node = heap.Min();
                heap.RemoveMin();
                int    n     = node.Data;
                double timee = node.Key;
                if (n == -2)
                {
                    continue;
                }
                var con = parameter[n];


                foreach (var item in con)
                {
                    //ListValueData.Add(item);
                    int    n1 = item.Key;       // el node el connected beha
                    double t1 = item.Value.Key; // el weight 3ala el edge

                    double oldtime = ans[n1].Value.Key;
                    double dist    = item.Value.Value.Key;

                    if (t1 + timee < oldtime)
                    {
                        var vip = new
                                  KeyValuePair <int, KeyValuePair <double, double> >(n, new KeyValuePair <double, double>(t1 + timee, dist));
                        ans[n1] = vip;
                        var node2 = new FibonacciHeapNode <int, double>(n1, t1 + timee);
                        heap.Insert(node2);
                    }
                }
            }
        }
Пример #8
0
        public static IDijkstraMap Dijkstra(IEnumerable <Point> start, IEnumerable <Point> end, int width, int height, Rectangle activeArea, double maxDist, ICostMap costMap, IEnumerable <Point> neighbors)
        {
            Stopwatch stopwatch = Stopwatch.StartNew();

            bool            hasEnds = end.Any();
            HashSet <Point> ends    = new HashSet <Point>(end);
            FibonacciHeap <DijkstraTile, double> heap = new FibonacciHeap <DijkstraTile, double>(0);

            if (activeArea.X < 0)
            {
                activeArea.X = 0;
            }
            if (activeArea.Y < 0)
            {
                activeArea.Y = 0;
            }
            if (activeArea.Width > width - 1)
            {
                activeArea.Width = width - 1;
            }
            if (activeArea.Height > height - 1)
            {
                activeArea.Height = height - 1;
            }

            IDijkstraMap dijkstraMap = new DijkstraMap(width, height, heap, start);

            int i = 0;

            while (!heap.IsEmpty() && (!hasEnds || ends.Count > 0))
            {
                var node  = heap.RemoveMin();
                var dTile = node.Data;

                if (dTile.Distance >= maxDist)
                {
                    break;
                }

                if (ends.Contains(dTile.Tile))
                {
                    ends.Remove(dTile.Tile);
                }

                i++;

                foreach (var neighbor in neighbors.Select(o => dTile.Tile + o))
                {
                    if (!activeArea.Contains(neighbor.X, neighbor.Y) /*neighbor.X < 0 || neighbor.Y < 0 || neighbor.X >= width || neighbor.Y >= height*/)
                    {
                        continue;
                    }
                    var    nodeNeighbor = dijkstraMap.GetNode(neighbor.X, neighbor.Y);
                    var    dNeighbor    = nodeNeighbor.Data;
                    double newDist      = dTile.Distance + costMap.GetCost(dNeighbor.Tile);

                    if (newDist < dNeighbor.Distance)
                    {
                        dNeighbor.Distance     = newDist;
                        dNeighbor.Previous     = dTile;
                        dNeighbor.MoveDistance = dTile.MoveDistance + 1;
                        heap.DecreaseKey(nodeNeighbor, dNeighbor.Distance);
                    }
                }
            }

            Console.WriteLine($"Dijkstra ({i} iterations) took: {stopwatch.ElapsedTicks} ({(float)stopwatch.ElapsedTicks / i})");

            return(dijkstraMap);
        }
Пример #9
0
 public TElement Pop()
 {
     return(heap.RemoveMin().Data);
 }
Пример #10
0
 /// <summary>
 /// Removes and returns the cheapest element
 /// </summary>
 /// <returns></returns>
 public virtual Element Pop()
 {
     return(heap.RemoveMin().Data);
 }
Пример #11
0
 public TElement Pop()
 {
     fibonacciNodeDic.Remove(heap.Min().Data);
     return(heap.RemoveMin().Data);
 }
Пример #12
0
 public T RemoveMin()
 {
     return(Heap.RemoveMin().Data);
 }