예제 #1
0
        static State AStar(State initial)
        {
            Console.WriteLine("Finding best path using A*...");
            HashSet <State> closed = new HashSet <State>();

            C5.IntervalHeap <State> open = new C5.IntervalHeap <State>(new HeuristicComparer(new Point(0, 0)));
            open.Add(initial);
            State goal = null;

            while (open.Count > 0)
            {
                var current = open.DeleteMax();
                if (current.IsGoal())
                {
                    goal = current;
                    break;
                }
                closed.Add(current);
                List <State> nextStates = current.GetSuccessors();
                foreach (var next in nextStates)
                {
                    if (closed.Contains(next))
                    {
                        continue;
                    }
                    else
                    {
                        open.Add(next);
                    }
                }
            }

            Console.WriteLine("Steps to goal: {0}", goal.GetStepsFromStart());
            return(goal);
        }
예제 #2
0
        public static Network Bfs(Network start, int target)
        {
            Network solution = null;
            var     fringe   = new C5.IntervalHeap <Network>(
                // Use this heuristic for picking the next
                // item to process
                new NetworkHeuristic(),
                C5.MemoryType.Normal
                );

            var discovered = new HashSet <string>();

            fringe.Add(start);
            while (solution == null && fringe.Count > 0)
            {
                // Find network with lowest heuristic value
                var network = fringe.FindMin();
                fringe.DeleteMin();
                if (network == null)
                {
                    continue;
                }

#if VERBOSE
                Console.WriteLine(network.GetInvariant());
                if (fringe.Count % 100 == 0)
                {
                    Console.WriteLine($"Progress Report:\n    FringeSize: {fringe.Count}\n    Discovered: {discovered.Count}");
                }
#endif

                // Solution is found when network is solved
                // (e.g. has one node) and meets target depth
                if (network.Solved)
                {
                    if (network.Depth <= target)
                    {
                        solution = network;
                    }
                }

                // Seen this, store invariant
                discovered.Add(network.GetInvariant());

                foreach (var child in network.GetChildren())
                {
                    var childinv = child.GetInvariant();
                    // Dont process if
                    //  - seen already
                    //  - cannot meet target because of constraints
                    if (!discovered.Contains(childinv) &&
                        child.CanReachTarget(target))
                    {
                        fringe.Add(child);
                    }
                }
            }

            return(solution);
        }
예제 #3
0
        /// <summary>
        /// Get line path without care obstacle.
        /// </summary>
        /// <param name="startTile">Start tile positon</param>
        /// <param name="endTile">End tile positon</param>
        /// <param name="maxTry">Max strep</param>
        /// <param name="tilePositon">If true, path position in path list is tile position.Otherwise is postion in world.</param>
        /// <returns>Path positition in world list.</returns>
        public static LinkedList <Vector2> GetLinePath(Vector2 startTile, Vector2 endTile, int maxTry, bool tilePositon = false)
        {
            if (startTile == endTile)
            {
                return(null);
            }

            var path     = new LinkedList <Vector2>();
            var frontier = new C5.IntervalHeap <Node <Vector2> >();

            frontier.Add(new Node <Vector2>(startTile, 0f));
            while (!frontier.IsEmpty)
            {
                if (maxTry-- < 0)
                {
                    break;
                }
                var current = frontier.DeleteMin().Location;
                path.AddLast(tilePositon? current : MapBase.ToPixelPosition(current));
                if (current == endTile)
                {
                    break;
                }
                foreach (var neighbor in FindAllNeighbors(current))
                {
                    frontier.Add(new Node <Vector2>(neighbor, GetTilePositionCost(neighbor, endTile)));
                }
            }
            return(path);
        }
예제 #4
0
        private static void KhoiTaoKhoangCach()
        {
            for (int index = 0; index < dothi.dsDinh.Count; index++)
            {
                int cs = IndexOf(dothi.dsDinh[index].ID);
                if (cs != S)
                {
                    d[index] = oo;
                }
                else
                {
                    d[index] = 0;
                }
                kt[index]    = true;
                trace[index] = -1;
            }

            for (int i = 0; i < dothi.dsCanh.Count; i++)
            {
                flag[i] = false;
            }

            /// thêm đỉnh đầu tiên vào Heap
            p z = new p();

            z.v = S;
            z.w = 0;
            Heap.Add(z);
        }
예제 #5
0
        void AddImageToQueue(J2KImage image)
        {
            image.PriorityQueueHandle = null;

            lock (m_syncRoot)
                try { m_priorityQueue.Add(ref image.PriorityQueueHandle, image); }
                catch (Exception) { }
        }
예제 #6
0
파일: Graph.cs 프로젝트: Yud07/Pax-Infinium
        public List <Vector3> AStar(Vector3 goal)
        {
            ClearNodeData();
            foreach (Node n in nodes)
            {
                n.SetCostToGo(goal);
            }
            Node startN = GetNode(start);
            Node endN   = GetNode(goal);

            if (startN == null || endN == null)
            {
                return(null);
            }

            var leafsPQueue = new C5.IntervalHeap <Node>(); // Priority Queue

            startN.costSoFar = 0;
            leafsPQueue.Add(startN);

            while (!leafsPQueue.IsEmpty)
            {
                Node leaf = leafsPQueue.FindMin();
                leafsPQueue.DeleteMin();

                if (leaf == endN)
                {
                    break;
                }
                foreach (Node neighbor in leaf.neighbors)
                {
                    int newCostSoFar = leaf.costSoFar + Game1.world.cubeDist(leaf.pos, neighbor.pos);
                    if (neighbor.costSoFar > newCostSoFar)
                    {
                        neighbor.prev      = leaf;
                        neighbor.costSoFar = newCostSoFar;
                        leafsPQueue.Add(neighbor);
                    }
                }
            }

            if (endN.prev != null)
            {
                List <Vector3> result = new List <Vector3>();
                Node           node   = endN;
                while (node.prev != null)
                {
                    result.Add(node.prev.cube.gridPos);
                    node = node.prev;
                }
                result.Reverse();
                return(result);
            }
            else
            {
                return(null);
            }
        }
예제 #7
0
        public static void DijstraSPA(int[,] Graph, int startNode, int EndNode)
        {
            char[] Color = new char[size];
            Distance = new int[size];
            Parent   = new int?[size];

            for (int v = 0; v < size; v++)
            {
                Color[v]    = 'w';
                Distance[v] = big;
            }

            var minHeap = new C5.IntervalHeap <Tuple <int, int> >();

            Distance[startNode - 1] = 0;
            Parent[startNode - 1]   = null;
            Color[startNode - 1]    = 'g';
            minHeap.Add(new Tuple <int, int>(Distance[startNode - 1], startNode));

            while (!minHeap.IsEmpty)
            {
                int selMin = minHeap.FindMin().Item2;
                minHeap.DeleteMin();

                // Black node = out of the heap for examination
                Color[selMin - 1] = 'b';

                //if (selMin == EndNode)
                //{
                //     return Parent;
                //}

                for (int i = 0; i < size; i++)
                {
                    if (Color[i] == 'b')
                    {
                        continue;
                    }

                    int currentNodeDist = Distance[selMin - 1];
                    int selectionDist   = Distance[i];
                    int potentialDist   = EdgeWeight[selMin - 1, i].Value;

                    if (potentialDist == big)
                    {
                        continue;
                    }

                    if (currentNodeDist + potentialDist < selectionDist)
                    {
                        Distance[i] = currentNodeDist + potentialDist;
                        Parent[i]   = selMin;
                        minHeap.Add(new Tuple <int, int>(Distance[i], i + 1));
                        Color[i] = 'g';
                    }
                } // for
            }     // while
        }         // DijstraSPA
예제 #8
0
        public IEnumerable <Board> Neighbors()
        {
            int[,] temp;
            var result = new C5.IntervalHeap <Board>(100, new BoardComparer(Program.ManhattanHeuristic));

            if (zeroX > 0)
            {
                var nextPath = new List <Directions>(Path)
                {
                    Directions.Right
                };

                temp = (int[, ])tiles.Clone();
                temp[zeroY, zeroX]     = temp[zeroY, zeroX - 1];
                temp[zeroY, zeroX - 1] = 0;
                result.Add(new Board(temp, nextPath, zeroX - 1, zeroY));
            }
            if (zeroX + 1 < size)
            {
                var nextPath = new List <Directions>(Path)
                {
                    Directions.Left
                };

                temp = (int[, ])tiles.Clone();
                temp[zeroY, zeroX]     = temp[zeroY, zeroX + 1];
                temp[zeroY, zeroX + 1] = 0;
                result.Add(new Board(temp, nextPath, zeroX + 1, zeroY));
            }

            if (zeroY > 0)
            {
                var nextPath = new List <Directions>(Path)
                {
                    Directions.Down
                };

                temp = (int[, ])tiles.Clone();
                temp[zeroY, zeroX]     = temp[zeroY - 1, zeroX];
                temp[zeroY - 1, zeroX] = 0;
                result.Add(new Board(temp, nextPath, zeroX, zeroY - 1));
            }

            if (zeroY + 1 < size)
            {
                var nextPath = new List <Directions>(Path)
                {
                    Directions.Up
                };

                temp = (int[, ])tiles.Clone();
                temp[zeroY, zeroX]     = temp[zeroY + 1, zeroX];
                temp[zeroY + 1, zeroX] = 0;
                result.Add(new Board(temp, nextPath, zeroX, zeroY + 1));
            }

            return(result);
        }
예제 #9
0
파일: Map.cs 프로젝트: w1r2p1/unitrpg
        public List <Vector2> FindPath(Vector2 start, Vector2 goal, Predicate <Tile> blockedFilter)
        {
            if (start == goal || !IsOnMap(goal) || !blockedFilter(GetTileByPosition(goal)))
            {
                return(null);
            }

            var exactCosts = new Dictionary <Vector2, double>();
            var estimates  = new Dictionary <Vector2, double>();
            var openNodes  = new C5.IntervalHeap <Vector2>(new AStarComparer(estimates));

            var closedNodes = new HashSet <Vector2>();
            var path        = new Dictionary <Vector2, Vector2>();

            openNodes.Add(start);
            exactCosts[start] = 0d;

            while (!openNodes.IsEmpty)
            {
                var currentCheapest = openNodes.DeleteMin();
                if (currentCheapest == goal)
                {
                    return(ReconstructPath(path, currentCheapest));
                }

                closedNodes.Add(currentCheapest);
                var neighbors = MathUtils.GetAdjacentPoints(currentCheapest);
                foreach (var neighbor in neighbors)
                {
                    var neighborTile = GetTileByPosition(neighbor);
                    if (closedNodes.Contains(neighbor) || IsOnMap(neighbor) && neighborTile.Obstructed)
                    {
                        continue;
                    }

                    var tentativeScore = exactCosts[currentCheapest] + CalculateDistance(currentCheapest, neighbor);
                    if (!estimates.ContainsKey(neighbor))
                    {
                        openNodes.Add(neighbor);
                    }
                    else if (tentativeScore >= exactCosts[neighbor])
                    {
                        continue;
                    }

                    var heuristicScore = tentativeScore + EstimateDistance(neighbor, goal);
                    estimates[neighbor]  = heuristicScore;
                    exactCosts[neighbor] = tentativeScore;
                    path[neighbor]       = currentCheapest;
                }
            }

            return(null);
        }
예제 #10
0
        public static LinkedList<Node> BuildNodePathUsingAStarWithoutSystem(Node Start, Node Goal, HeuristicCalculator Calculator, NextStatesProvider Provider)
        {
            int expandedNodesCount = 0;
            bool found = false;
            TreeNode start = new TreeNode(Start);
            TreeNode goal = new TreeNode(null);
            var toExpand = new C5.IntervalHeap<TreeNode>(new TreeNodeCostComparer());
            var discoveredTreeNodes = new Dictionary<int, TreeNode>();

            start.Cost = Calculator.Calculate(Start.State, Goal.State);
            toExpand.Add(start);
            discoveredTreeNodes.Add(start.Node.State.GetHashCode(), start);

            while (toExpand.Count > 0)
            {
                TreeNode Current = toExpand.FindMin();
                toExpand.DeleteMin();

                if (Current.Node.State.Equals(Goal.State))
                {
                    goal = Current;
                    found = true;
                    break;
                }

                expandedNodesCount++;
                foreach (var nextNode in Provider.GetNodesWithNextStates(Current.Node))
                {
                    double Cost = Calculator.Calculate(nextNode.State, Goal.State);
                    if (!discoveredTreeNodes.ContainsKey(nextNode.State.GetHashCode()))
                    {
                        TreeNode Tem = new TreeNode(nextNode, Current, Current.Cost + Cost);
                        Current.Children.AddLast(Tem);
                        discoveredTreeNodes.Add(nextNode.State.GetHashCode(), Tem);
                        toExpand.Add(Tem);
                    }
                    else
                    {
                        CheckIfBetterPathWasFound(discoveredTreeNodes, Current, nextNode, Cost);
                    }
                }
            }

            Console.WriteLine("Expanded {0} nodes", expandedNodesCount);

            if (!found)
                throw new PathNotFoundException("Path not found!");

            return createPath(goal, start);
        }
예제 #11
0
        public int GetShortestDistance(string from, string to)
        {
            // Dijkstra Algorithm
            var distances     = new Dictionary <Node, int>();
            var previousNodes = new Dictionary <Node, Node>();
            var queue         = new C5.IntervalHeap <NodeEntry>(new NodeComp()); // Priority Queue
            var visited       = new HashSet <Node>();
            var fromNode      = GetNode(from);
            var fromNodeEntry = new NodeEntry(fromNode, 0);
            var toNode        = GetNode(to);

            foreach (var node in itemsMap.Values)
            {
                distances[node]     = int.MaxValue;
                previousNodes[node] = null;
            }

            distances[fromNode] = 0;

            if (fromNode == null || toNode == null)
            {
                throw new System.InvalidOperationException("Input nodes are invalid");
            }

            queue.Add(fromNodeEntry);

            while (queue.Count > 0)
            {
                var currentNode = queue.DeleteMax().GetNode();
                visited.Add(currentNode);

                foreach (var edge in currentNode.GetEdges())
                {
                    if (visited.Contains(edge.to))
                    {
                        continue;
                    }
                    var oldDistance     = distances[edge.to];
                    var currentDistance = distances[currentNode] + edge.weight;
                    if (currentDistance < oldDistance)
                    {
                        distances[edge.to]     = currentDistance;
                        previousNodes[edge.to] = currentNode;
                        queue.Add(new NodeEntry(edge.to, currentDistance));
                    }
                }
            }

            return(distances[toNode]);
        }
예제 #12
0
        private (Point3D, Point3D) FindClosestPointNearNotVoidedVoxels(List <Point3D> points)
        {
            var bot       = _scene.GetFirstBot();
            var pointsSet = new C5.IntervalHeap <Vector3D>(
                new PriorityQueueComparer(Vector3D.FromPoint(bot.Current))
                );
            var map      = new Dictionary <Point3D, Point3D>();
            var boundBox = _scene.PadBoundBox;

            foreach (var pointToFill in points)
            {
                foreach (var candidatePoint in EnumeratePointsToVoidFrom(pointToFill))
                {
                    if (!boundBox.Contains(candidatePoint))
                    {
                        continue;
                    }
                    if (_scene.SceneState.Matrix[candidatePoint] == VoxelStatus.Full)
                    {
                        continue;
                    }

                    map[candidatePoint] = pointToFill;
                    pointsSet.Add(Vector3D.FromPoint(candidatePoint));
                }
            }

            var pointToMove = pointsSet.DeleteMin().ToPoint();

            return(map[pointToMove], pointToMove);
        }
예제 #13
0
        public static List <Directions> AStar(Board board, Func <Board, int> heuristic)
        {
            if (board.IsGoal())
            {
                return(new List <Directions>());
            }

            var queue = new C5.IntervalHeap <Board>(100, new BoardComparer(heuristic))
            {
                board
            };


            HashSet <string> memo = new HashSet <string>();

            while (!queue.IsEmpty)
            {
                Board current = queue.DeleteMin();
                foreach (var element in current.Neighbors())
                {
                    if (element.IsGoal())
                    {
                        return(element.Path);
                    }
                    if (!memo.Contains(element.BoardToString))
                    {
                        queue.Add(element);
                        memo.Add(element.BoardToString);
                    }
                }
            }
            return(null);
        }
예제 #14
0
파일: Graph.cs 프로젝트: junian/NeoGraph
        //private void Triangulate()
        //{
        //    List<TriangulationPoint> points = new List<TriangulationPoint>();
        //    foreach (Vertex data in VertexList)
        //        points.Add(new TriangulationPoint(data.X, data.Y));
        //    PointSet set = new PointSet(points);

        //    IList<PolygonPoint> ppoint = new List<PolygonPoint>();
        //    foreach (Vertex data in VertexList)
        //        ppoint.Add(new PolygonPoint(data.X, data.Y));
        //    Polygon pol = new Polygon(ppoint);
        //    try
        //    {

        //        P2T.Triangulate(set);

        //        IList<DelaunayTriangle> triangles = set.Triangles;
        //        foreach (DelaunayTriangle angle in triangles)
        //        {
        //            FixedArray3<TriangulationPoint> point = angle.Points;
        //            EdgeList.Add(new Edge(new Vertex((int) point[0].X, (int) point[0].Y), new Vertex((int) point[1].X, (int) point[1].Y)));
        //            EdgeList.Add(new Edge(new Vertex((int) point[2].X, (int) point[2].Y), new Vertex((int) point[1].X, (int) point[1].Y)));
        //            EdgeList.Add(new Edge(new Vertex((int) point[0].X, (int) point[0].Y), new Vertex((int) point[2].X, (int) point[2].Y)));
        //            Debug.WriteLine(String.Format("X:{0}, Y:{0}", point[0].X, point[0].Y));
        //            //if (VertexList.Contains(aaa))
        //            //    Debug.WriteLine("ada yang sama");
        //        }
        //    }
        //    catch (Exception ex)
        //    {
        //        Debug.WriteLine(ex.StackTrace);
        //    }

        //}

        //public int Distance(Vertex a, Vertex b)
        //{
        //    return (int)(Math.Sqrt(Math.Pow(a.X - b.X, 2) + Math.Pow(a.Y - b.Y, 2)));
        //}
        #endregion

        #region MST With Edge

        public void GenerateKruskalMST()
        {
            ClearSolution();
            if (VertexList.Count == 0)
            {
                return;
            }

            DisjointSet <Vertex> disjointSet = new DisjointSet <Vertex>(VertexList);

            C5.IPriorityQueue <Edge> heap = new C5.IntervalHeap <Edge>(new EdgeComparer());

            foreach (Edge e in EdgeList)
            {
                heap.Add(e);
            }

            while (heap.Count > 0 && disjointSet.Count > 0)
            {
                Edge s = heap.DeleteMin();
                if (!disjointSet.IsSameSet(s.VertexFirst, s.VertexSecond))
                {
                    disjointSet.Union(s.VertexFirst, s.VertexSecond);
                    EdgeSolution.Add(s);
                }
            }
        }
예제 #15
0
        /// <summary>
        /// Adds an event to the interest list
        /// </summary>
        /// <param name="eventData">Event to add</param>
        /// <param name="handler">Collection of callbacks that will handle this
        /// event</param>
        public void EnqueueEvent(InterestListEvent eventData, InterestListEventHandler handler)
        {
            double?priority = handler.PriorityCallback(eventData, m_presence);

            // If this event has a non-null priority for this presence, enqueue it
            if (priority.HasValue)
            {
                QueuedInterestListEvent qile = new QueuedInterestListEvent(eventData, priority.Value, handler);

                lock (m_syncRoot)
                {
                    C5.PriorityQueueHandle handle;
                    if (m_eventIDs.TryGetValue(eventData.ID, out handle))
                    {
                        // An event with the same ID already exists in the priority queue. Combine this update with the previous one
                        qile = handler.CombineCallback(m_eventHeap[handle], qile);
                        m_eventHeap.Replace(handle, qile);
                    }
                    else
                    {
                        // This event ID is new
                        m_eventHeap.Add(ref handle, qile);
                        m_eventIDs.Add(eventData.ID, handle);
                    }
                }
            }
        }
예제 #16
0
        public override IList <Node> Solve()
        {
            C5.IntervalHeap <Node>      heap = new C5.IntervalHeap <Node>(Comparer <Node> .Create((Node f, Node s) => (f.TotalCost).CompareTo(s.TotalCost)));
            HashSet <Tuple <int, int> > set  = new HashSet <Tuple <int, int> >();

            for (int i = 0; i < Initial.GetLength(0); i++)
            {
                for (int j = 0; j < Initial.GetLength(1); j++)
                {
                    set.Add(new Tuple <int, int>(i, j));
                }
            }
            var ini = new Node(set)
            {
                Board = Initial
            };

            heap.Add(ini);
            ISet <Node> visited = new HashSet <Node>();

            while (!heap.IsEmpty)
            {
                var n = heap.DeleteMin();
                if (n.IsFinal)
                {
                    return(n.Parents);
                }
                visited.Add(n);
                n.GenerateChildren().Where(e => !visited.Contains(e)).ToList().ForEach(e => heap.Add(e));
            }
            return(new List <Node>());
        }
예제 #17
0
        //Returned path is in pixel position
        public static LinkedList <Vector2> FindPathSimple(Character finder, Vector2 startTile, Vector2 endTile, int maxTry)
        {
            if (startTile == endTile)
            {
                return(null);
            }

            if (MapBase.Instance.IsObstacleForCharacter(endTile))
            {
                return(null);
            }

            var cameFrom = new Dictionary <Vector2, Vector2>();
            var frontier = new C5.IntervalHeap <Node <Vector2> >();

            frontier.Add(new Node <Vector2>(startTile, 0f));
            var tryCount = 0;

            while (!frontier.IsEmpty)
            {
                if (tryCount++ > maxTry)
                {
                    break;
                }
                var current = frontier.DeleteMin().Location;
                if (current == endTile)
                {
                    break;
                }
                if (finder.HasObstacle(current) && current != startTile)
                {
                    continue;
                }
                foreach (var neighbor in FindNeighbors(current, finder.CanMoveDirCount))
                {
                    if (!cameFrom.ContainsKey(neighbor))
                    {
                        var priority = GetTilePositionCost(neighbor, endTile);
                        frontier.Add(new Node <Vector2>(neighbor, priority));
                        cameFrom[neighbor] = current;
                    }
                }
            }
            return(GetPath(cameFrom, startTile, endTile));
        }
예제 #18
0
        /// <summary>
        /// Test whether can view target within vision radius.
        /// </summary>
        /// <param name="startTile">Viewer tile position.</param>
        /// <param name="endTile">Target tile position.</param>
        /// <param name="visionRadius">Viewr vision radius</param>
        /// <returns>True if can view target without map obstacle.Otherwise false.</returns>
        public static bool CanViewTarget(Vector2 startTile, Vector2 endTile, int visionRadius)
        {
            const int maxVisionRadious = 80;

            if (visionRadius > maxVisionRadious)
            {
                //Vision radius is too big, for performace reason return false.
                return(false);
            }

            if (startTile != endTile)
            {
                if (MapBase.Instance.IsObstacleForMagic(endTile))
                {
                    return(false);
                }

                var path     = new LinkedList <Vector2>();
                var frontier = new C5.IntervalHeap <Node <Vector2> >();
                frontier.Add(new Node <Vector2>(startTile, 0f));
                while (!frontier.IsEmpty)
                {
                    var current = frontier.DeleteMin().Location;
                    if (current == endTile)
                    {
                        return(true);
                    }

                    if (MapBase.Instance.IsObstacle(current) || visionRadius < 0)
                    {
                        return(false);
                    }

                    path.AddLast(current);
                    foreach (var neighbor in FindAllNeighbors(current))
                    {
                        frontier.Add(new Node <Vector2>(neighbor, GetTilePositionCost(neighbor, endTile)));
                    }
                    visionRadius--;
                }
                return(false);
            }

            return(true);
        }
예제 #19
0
        public static IEnumerable <IPathNode <N> > GetReachableNodes <N>(N start, float maxCost) where N : INode <N>
        {
            C5.IDictionary <N, PathNode <N> > nodeDictionary = new C5.HashDictionary <N, PathNode <N> >();
            C5.IPriorityQueue <PathNode <N> > openSet        = new C5.IntervalHeap <PathNode <N> >(new PathNodeComparer <N>(), C5.MemoryType.Normal);
            C5.ICollection <N>            closedSet          = new C5.HashSet <N>();
            C5.ArrayList <IPathNode <N> > res = new C5.ArrayList <IPathNode <N> >(C5.MemoryType.Normal);


            PathNode <N> curNode = new PathNode <N>(start);

            curNode.g = 0;
            nodeDictionary.Add(start, curNode);
            while (true)
            {
                res.Add(curNode);
                foreach (IEdge <N> edge in curNode.node)
                {
                    N other = edge.GetEnd();
                    if (!closedSet.Contains(other))
                    {
                        PathNode <N> otherNode = null;
                        if (!nodeDictionary.Find(ref other, out otherNode))
                        {
                            otherNode = new PathNode <N>(other);
                            nodeDictionary.Add(other, otherNode);
                        }
                        float newG = edge.GetCost() + curNode.g;
                        if (otherNode.g > newG)
                        {
                            otherNode.g = newG;
                            if (otherNode.queueHandle != null)
                            {
                                openSet.Replace(otherNode.queueHandle, otherNode);
                            }
                            otherNode.prev = curNode;
                        }
                        if (otherNode.queueHandle == null)
                        {
                            C5.IPriorityQueueHandle <PathNode <N> > handle = null;
                            openSet.Add(ref handle, otherNode);
                            otherNode.queueHandle = handle;
                        }
                    }
                }
                if (openSet.IsEmpty)
                {
                    return(res);
                }
                closedSet.Add(curNode.node);
                curNode = openSet.DeleteMin();
                if (curNode.g > maxCost)
                {
                    return(res);
                }
            }
        }
예제 #20
0
        /// <summary>
        /// Schedules the given mutation to be re-executed at a time in the future based on its retry count
        /// </summary>
        /// <param name="mut">The mutation to reschedule</param>
        private void ScheduleMutationRetry(DelayedMutation mut)
        {
            mut.ReadyOn = DateTime.Now + RETRY_DELAYS[mut.RetryCount];
            _log.InfoFormat("[Inworldz.Data.Inventory.Cassandra] Mutation {0} will be retried at {1}", mut.Identifier, mut.ReadyOn);

            lock (_delayedMutations)
            {
                _delayedMutations.Add(mut);
            }
        }
예제 #21
0
        internal static IReadOnlyList <T> KnnSearch <T>(this RBush <T> tree, object query, int n,
                                                        Func <T, bool> predicate = null, double maxDist = -1) where T : ISpatialData
        {
            var distCalculator = new DistanceToSpatialCalculator();

            if (maxDist > 0)
            {
                maxDist = maxDist * maxDist;                //compare quadratic distances
            }
            List <T> result = new List <T>();

            //priority queue
            var queue = new C5.IntervalHeap <IDistanceToSpatial>(new DistComparer());

            RBush <T> .Node node = tree.Root;

            while (node != null)
            {
                foreach (ISpatialData child in node.Children)                                    //for each child
                {
                    var childDistData = distCalculator.CalculateDistanceToSpatial(query, child); //calc distance to box
                    if (maxDist < 0 || childDistData.SquaredDistanceToBox <= maxDist)            //check if distance less than max distance
                    {
                        queue.Add(childDistData);                                                //add to queue
                    }
                }

                //dequeue all objects that are items stored in RBush
                while (queue.Count > 0 && queue.FindMin().SpatialData is T)
                {
                    var candidateWr = queue.DeleteMin();                  //this item goes to result
                    T   candidate   = (T)candidateWr.SpatialData;
                    if (predicate == null || predicate.Invoke(candidate)) //if element satisfy the condition
                    {
                        result.Add(candidate);                            //add to result
                    }
                    if (n > 0 && result.Count == n)                       //if the desired amount is already in the result
                    {
                        return(result);                                   //return result
                    }
                }

                //process next element in queue
                if (queue.Count > 0)
                {
                    node = queue.DeleteMin().SpatialData as RBush <T> .Node;
                }
                else
                {
                    node = null;
                }
            }

            return(result);
        }
예제 #22
0
        public void MergeChunks(string outputFilePath, string[] chunkFiles)
        {
            Console.WriteLine(nameof(PriorityQueueMergeStrategy));
            using (var writer = File.CreateText(outputFilePath))
            {
                List<StreamReader> readers = chunkFiles.Select(s => new StreamReader(s, Encoding.UTF8)).ToList();

                var priorityQueue = new C5.IntervalHeap<string>(_comparer);
                var readerForHandle = new Dictionary<C5.IPriorityQueueHandle<string>, StreamReader>();

                // Fill priority queue with initial strings. Each string is associated with reader it came from
                readers.ForEach(reader => {
                    C5.IPriorityQueueHandle<string> handle = null;
                    priorityQueue.Add(ref handle, reader.ReadLine());
                    readerForHandle[handle] = reader;
                });

                // Get minimal element from queue and read the next line from respective stream
                // repeat until all streams are exhausted
                while (!priorityQueue.IsEmpty)
                {
                    C5.IPriorityQueueHandle<string> handleMin;
                    string line = priorityQueue.DeleteMin(out handleMin);
                    StreamReader reader = readerForHandle[handleMin];
                    readerForHandle.Remove(handleMin);

                    writer.WriteLine(line);

                    string nextLine = reader.ReadLine();
                    if (nextLine != null)
                    {
                        C5.IPriorityQueueHandle<string> handle = null;
                        priorityQueue.Add(ref handle, nextLine);
                        readerForHandle[handle] = reader;
                    }
                }

                readers.ForEach(r => r.Dispose());
            }

            chunkFiles.ForEach(f => File.Delete(f));
        }
예제 #23
0
파일: Graph.cs 프로젝트: junian/NeoGraph
        public void GenerateEuclideanKruskalMST()
        {
            if (VertexList.Count == 0)
            {
                return;
            }

            DateTime             start       = DateTime.Now;
            DisjointSet <Vertex> disjointSet = new DisjointSet <Vertex>(VertexList);

            EdgeSolution.Clear();

            C5.IPriorityQueue <Edge> heap = new C5.IntervalHeap <Edge>(new EdgeComparer());

            //Triangulate();
            //DelaunayTriangulation2d triangulator = new DelaunayTriangulation2d();
            //IList<Triangle> triangles = triangulator.Triangulate(new List<Vertex>(VertexList));

            //foreach (Triangle triangle in triangles)
            //{
            //    Edge e = new Edge(triangle.Vertex1, triangle.Vertex2);
            //    heap.Add(e);
            //    EdgeList.Add(e);
            //    e = new Edge(triangle.Vertex1, triangle.Vertex3);
            //    heap.Add(e);
            //    EdgeList.Add(e);
            //    e = new Edge(triangle.Vertex3, triangle.Vertex2);
            //    heap.Add(e);
            //    EdgeList.Add(e);

            //}
            //this.VisitedVertex = VertexList.Count;
            for (int i = 0; i < VertexList.Count - 1; i++)
            {
                for (int j = i + 1; j < VertexList.Count; j++)
                {
                    Edge e = new Edge(VertexList[i], VertexList[j]);
                    heap.Add(e);
                }
            }

            while (heap.Count > 0 && disjointSet.Count > 0)
            {
                Edge s = heap.DeleteMin();
                if (!disjointSet.IsSameSet(s.VertexFirst, s.VertexSecond))
                {
                    disjointSet.Union(s.VertexFirst, s.VertexSecond);
                    EdgeSolution.Add(s);
                }
            }

            Debug.WriteLine((DateTime.Now - start).TotalMilliseconds + " ms");
            //this.VisitedVertex = VertexList.Count;
        }
예제 #24
0
        protected virtual void ProcessNeighbor(GraphNodeMetaData <T> neighborMetaData)
        {
            if (neighborMetaData.Status != NodeStatus.New)
            {
                return;
            }
            neighborMetaData.Status = NodeStatus.Open;
            var didAdd = OpenNodes.Add(ref neighborMetaData.Handle, neighborMetaData);

            Debug.Assert(didAdd, "Failed to add neighborNode to open nodes list. The comparer is probably invalid.");
        }
예제 #25
0
파일: Graph.cs 프로젝트: junian/NeoGraph
        public void GenerateEuclideanOurNeoKruskalMST(int bucket)
        {
            if (VertexList.Count == 0)
            {
                return;
            }

            DateTime start = DateTime.Now;
            NeoDisjointSet <Vertex> disjointSet = new NeoDisjointSet <Vertex>(VertexList);

            EdgeSolution.Clear();
            C5.IPriorityQueue <Edge>[] heap2 = new C5.IntervalHeap <Edge> [bucket];
            C5.IPriorityQueue <Edge>   heap  = new C5.IntervalHeap <Edge>(new EdgeComparer());
            for (int i = 0; i < heap2.Length; i++)
            {
                heap2[i] = new C5.IntervalHeap <Edge>(new EdgeComparer());
            }


            //this.VisitedVertex = VertexList.Count;
            for (int i = 0; i < VertexList.Count - 1; i++)
            {
                for (int j = i + 1; j < VertexList.Count; j++)
                {
                    Edge e = new Edge(VertexList[i], VertexList[j]);
                    heap.Add(e);
                }
            }

            double max = heap.FindMax().Length;
            double min = heap.FindMin().Length;

            while (heap.Count > 0)
            {
                Edge s = heap.DeleteMin();
                heap2[(int)Math.Floor((((s.Length - min) / (max - min)) * (bucket - 1)))].Add(s);
            }

            for (int i = 0; i < bucket && disjointSet.Count > 0; i++)
            {
                while (heap2[i].Count > 0 && disjointSet.Count > 0)
                {
                    Edge s = heap2[i].DeleteMin();
                    if (!disjointSet.IsSameSet(s.VertexFirst, s.VertexSecond))
                    {
                        disjointSet.Union(s.VertexFirst, s.VertexSecond);
                        EdgeSolution.Add(s);
                    }
                }
            }

            Debug.WriteLine((DateTime.Now - start).TotalMilliseconds + " ms");
            //this.VisitedVertex = VertexList.Count;
        }
예제 #26
0
        public static ImageNode CropFrameInTiles(Bitmap bp)
        {
            int[] ymax = new int[bp.Width];
            int[] ymin = new int[bp.Width];
            getMinMaxH(bp, ymax, ymin);

            LinkedList <ImageNode> imns =
                ImageNode.GetNodes(ymin, ymax);

            C5.IntervalHeap <ImageNode> ih = new C5.IntervalHeap <ImageNode>();

            foreach (ImageNode imn in imns)
            {
                ih.Add(imn);
            }

            List <ImageNode>       close = new List <ImageNode>();
            ImageNode              imnaux;
            LinkedList <ImageNode> newnodes;

            while (ih.Count > 0)
            {
                imnaux = ih.DeleteMin();

                close.Add(imnaux);

                newnodes = ImageNode.GetNodes(imnaux);
                if (newnodes == null)
                {
                    return(imnaux);
                }
                else
                {
                    foreach (ImageNode imn in newnodes)
                    {
                        ih.Add(imn);
                    }
                }
            }
            return(null);
        }
예제 #27
0
        /// <summary>
        /// Search k nearest neighbors to given point or to to given line segment
        /// </summary>
        /// <typeparam name="T">type of RBush items</typeparam>
        /// <param name="tree">RBush object</param>
        /// <param name="x1">x coordinate of query point.
        /// Or if x2 and y2 not null, x coordinate of first endpoint of query line segment</param>
        /// <param name="y1">y coordinate of query point.
        /// Or if x2 and y2 not null, y coordinate of first endpoint of query line segment</param>
        /// <param name="n">number of nearest neighbors to get</param>
        /// <param name="predicate">condition for neighbors</param>
        /// <param name="maxDist">max distance for nearest neighbors</param>
        /// <param name="x2">if not null is x coordinate of second endpoint of query line segment</param>
        /// <param name="y2">if not null is y coordinate of second endpoint of query line segment</param>
        /// <returns></returns>
        public static IReadOnlyList <T> KnnSearch <T>(this RBush <T> tree, double x1, double y1, int n,
                                                      Func <T, bool> predicate = null, double maxDist = -1, double?x2 = null, double?y2 = null) where T : ISpatialData
        {
            if (maxDist > 0)
            {
                maxDist = maxDist * maxDist;                //All distances are quadratic!!!
            }
            List <T> result = new List <T>();

            //priority queue
            C5.IntervalHeap <SpatialDataWrapper> queue = new C5.IntervalHeap <SpatialDataWrapper>(new DistComparer());

            RBush <T> .Node node = tree.Root;

            while (node != null)
            {
                foreach (ISpatialData child in node.Children)                                         //for each child
                {
                    SpatialDataWrapper childDistData = new SpatialDataWrapper(child, x1, y1, x2, y2); //calc distance to box
                    if (maxDist < 0 || childDistData.SquaredDistanceToBox <= maxDist)                 //check if distance less than max distance
                    {
                        queue.Add(childDistData);                                                     //add to queue
                    }
                }

                //dequeue all objects that are items stored in RBush
                while (queue.Count > 0 && queue.FindMin().SpatialData is T)
                {
                    SpatialDataWrapper candidate = queue.DeleteMin();      //this item goes to result
                    T _candidate = (T)candidate.SpatialData;
                    if (predicate == null || predicate.Invoke(_candidate)) //if element satisfy the condition
                    {
                        result.Add(_candidate);                            //add to result
                    }
                    if (n > 0 && result.Count == n)                        //if the desired amount is already in the result
                    {
                        return(result);                                    //return result
                    }
                }

                //process next element in queue
                if (queue.Count > 0)
                {
                    node = queue.DeleteMin().SpatialData as RBush <T> .Node;
                }
                else
                {
                    node = null;
                }
            }

            return(result);
        }
예제 #28
0
        public override void Solve(State state)
        {
            var visited = new HashSet <Board>();
            var queue   = new C5.IntervalHeap <State>();

            queue.Add(state);
            visited.Add(state.CurrentBoard);

            while (queue.Count > 0)
            {
                if (queue.Count > this.MaxFringeSize)
                {
                    this.MaxFringeSize = queue.Count;
                }

                state = queue.DeleteMax();

                if (state.CurrentBoard.IsEqual(this.GoalState))
                {
                    this.PrintResults(state, queue.Count);
                    break;
                }


                var zeroXAndY = state.CurrentBoard.IndexOfZero();
                var zeroX     = zeroXAndY.Item1;
                var zeroY     = zeroXAndY.Item2;
                var children  = this.GenerateChildrenStates(state, zeroX, zeroY);

                for (var i = children.Count - 1; i >= 0; i--)
                {
                    var currentChild = children[i];
                    if (!visited.Contains(currentChild.CurrentBoard))
                    {
                        queue.Add(currentChild);
                        visited.Add(currentChild.CurrentBoard);
                    }
                }
            }
        }
예제 #29
0
        static void AStar()
        {
            Console.WriteLine("Finding best path using A*...");
            Space           start  = new Space(1, 1);
            Space           goal   = new Space(31, 39);
            HashSet <Space> closed = new HashSet <Space>();

            C5.IntervalHeap <Space> open = new C5.IntervalHeap <Space>(new HeuristicComparer(goal));
            open.Add(start);

            while (open.Count > 0)
            {
                var current = open.DeleteMax();
                if (current.Equals(goal))
                {
                    goal = current;
                    break;
                }
                closed.Add(current);
                List <Space> points = current.GetPointsAround();
                foreach (var p in points)
                {
                    if (closed.Contains(p))
                    {
                        continue;
                    }
                    else if (p.IsWall)
                    {
                        closed.Add(p);
                    }
                    else
                    {
                        open.Add(p);
                    }
                }
            }

            Console.WriteLine("Steps to goal: {0}", goal.GetStepsFromStart());
        }
        /// <summary>
        /// Add a new deferred event
        /// </summary>
        /// <param name="itemId"></param>
        /// <param name="eventInfo"></param>
        public void AddEvent(UUID itemId, VM.PostedEvent eventInfo)
        {
            DeferredEventList eventList;

            if (_eventsByScript.TryGetValue(itemId, out eventList))
            {
                if (eventList.EvtList.Count < MAX_DEFERRED_EVENTS)
                {
                    eventList.EvtList.Add(eventInfo);
                }
            }
            else
            {
                eventList = new DeferredEventList(itemId);
                eventList.EvtList.Add(eventInfo);
                _eventsByScript.Add(itemId, eventList);

                C5.IPriorityQueueHandle <DeferredEventList> handle = null;
                _sortedEvents.Add(ref handle, eventList);
                eventList.Handle = handle;
            }
        }
        public int minDeletionsToMakeFrequencyOfEachLetterUnique(string s)
        {
            // counter of characters to delete
            int count = 0;
            // array of counters of occurrences for all possible characters
            Dictionary <char, int> freq = new Dictionary <char, int>();

            foreach (char c in s)
            {
                if (freq.ContainsKey(c))
                {
                    freq[c]++;
                }
                else
                {
                    freq.Add(c, 1);
                }
            }

            var heap = new C5.IntervalHeap <int>();

            heap.AddAll(freq.Select(i => i.Value));

            while (heap.Count > 0)
            {
                // take the biggest frequency of a character
                int most_frequent = heap.FindMax();

                heap.DeleteMax();

                if (heap.Count == 0)
                {
                    return(count);
                }
                // if this frequency is equal to the next one
                // and bigger than 1 decrease it to 1 and put
                // back to the queue
                if (most_frequent == heap.FindMax())
                {
                    if (most_frequent > 1)
                    {
                        heap.Add(most_frequent - 1);
                    }
                    count++;
                }
                // all frequencies which are bigger than
                // the next one are removed from the queue
                // because they are unique
            }
            return(count);
        }
예제 #32
0
파일: Graph.cs 프로젝트: junian/NeoGraph
        public void GenerateKruskalMST()
        {
            ClearSolution();
            if (VertexList.Count == 0)
                return;

            DisjointSet<Vertex> disjointSet = new DisjointSet<Vertex>(VertexList);
            C5.IPriorityQueue<Edge> heap = new C5.IntervalHeap<Edge>(new EdgeComparer());

            foreach(Edge e in EdgeList)
                    heap.Add(e);

            while (heap.Count > 0 && disjointSet.Count > 0)
            {
                Edge s = heap.DeleteMin();
                if (!disjointSet.IsSameSet(s.VertexFirst, s.VertexSecond))
                {
                    disjointSet.Union(s.VertexFirst, s.VertexSecond);
                    EdgeSolution.Add(s);
                }
            }
        }
예제 #33
0
        /// <summary>
        /// Finds a path between startPoint and endPoint.
        /// </summary>
        /// <param name="startPoint">Starting point</param>
        /// <param name="endPoint">Ending point</param>
        /// <returns>Path that connects start and end point</returns>
        public Path FindPath(Point startPoint, Point endPoint)
        {
            if (this.Collides(startPoint) || this.Collides(endPoint))
             {
            return null;
             }

             this.StartPoint = startPoint;
             this.EndPoint = endPoint;

             // initialize the open set of nodes with start point
             C5.IPriorityQueue<State> openSet = new C5.IntervalHeap<State>();

             // associate handles with points
             var handles = new Dictionary<Point, C5.IPriorityQueueHandle<State>>();

             // add start point to queue and associate point with handle
             C5.IPriorityQueueHandle<State> handle = null;
             openSet.Add(ref handle, new State {Point = startPoint, Heuristic = 0});
             handles.Add(this.StartPoint, handle);

             var closedSet = new HashSet<Point>();

             // the g-score is the distance from start point to the current point
             var gScore = new Dictionary<Point, double> {{startPoint, 0}};

             // the f-score is the g-score plus heuristic
             var fScore = new Dictionary<Point, double> {{startPoint, Utils.Distance(startPoint, this.EndPoint)}};

             // cameFrom is used to reconstruct path when target is found
             var cameFrom = new Dictionary<Point, Point>();

             // process nodes in the open set...
             while (!openSet.IsEmpty)
             {
            // fetch highest priority node, i.e. the one with
            // lowest heuristic value
            State minState = openSet.DeleteMin();
            Point x = minState.Point;
            handles.Remove(x);

            if (x == this.EndPoint)
            {
               // we found a solution
               return this.ReconstructPath(cameFrom);
            }

            closedSet.Add(x);
            var neighbours = this.GetNeighbours(x);

            // for each neighbour...
            foreach (var y in neighbours)
            {
               if (closedSet.Contains(y))
               {
                  continue;
               }

               // total cost from start
               var tentativeGScore = gScore[x] + Utils.Distance(x, y);

               bool tentativeIsBetter;
               Point point = y;
               handle = null;
               if (!openSet.Exists(s => s.Point == point) && !closedSet.Contains(y))
               {
                  // will get priority adjusted further down
                  openSet.Add(ref handle, new State {Point = point});
                  handles.Add(point, handle);
                  tentativeIsBetter = true;
               }
               else if (tentativeGScore < gScore[y])
               {
                  tentativeIsBetter = true;
               }
               else
               {
                  tentativeIsBetter = false;
               }

               if (tentativeIsBetter)
               {
                  // update f-score of y
                  cameFrom[y] = x;
                  gScore[y] = tentativeGScore;
                  fScore[y] = gScore[y] + Utils.Distance(y, this.EndPoint);
                  var heuristic = fScore[y];

                  // set priority of y
                  if (handle == null)
                  {
                     handle = handles[point];
                  }

                  openSet.Replace(handle, new State {Heuristic = heuristic, Point = y});
               }
            }
             }

             return null;
        }
예제 #34
0
파일: Graph.cs 프로젝트: junian/NeoGraph
        public void GenerateEuclideanKruskalMST()
        {
            if (VertexList.Count == 0)
                return;

            DateTime start = DateTime.Now;
            DisjointSet<Vertex> disjointSet = new DisjointSet<Vertex>(VertexList);
            EdgeSolution.Clear();

            C5.IPriorityQueue<Edge> heap = new C5.IntervalHeap<Edge>(new EdgeComparer());

            //Triangulate();
            //DelaunayTriangulation2d triangulator = new DelaunayTriangulation2d();
            //IList<Triangle> triangles = triangulator.Triangulate(new List<Vertex>(VertexList));

            //foreach (Triangle triangle in triangles)
            //{
            //    Edge e = new Edge(triangle.Vertex1, triangle.Vertex2);
            //    heap.Add(e);
            //    EdgeList.Add(e);
            //    e = new Edge(triangle.Vertex1, triangle.Vertex3);
            //    heap.Add(e);
            //    EdgeList.Add(e);
            //    e = new Edge(triangle.Vertex3, triangle.Vertex2);
            //    heap.Add(e);
            //    EdgeList.Add(e);

            //}
            //this.VisitedVertex = VertexList.Count;
            for (int i = 0; i < VertexList.Count - 1; i++)
                for (int j = i + 1; j < VertexList.Count; j++)
                {
                    Edge e = new Edge(VertexList[i], VertexList[j]);
                    heap.Add(e);
                }

            while (heap.Count > 0 && disjointSet.Count > 0)
            {
                Edge s = heap.DeleteMin();
                if (!disjointSet.IsSameSet(s.VertexFirst, s.VertexSecond))
                {

                    disjointSet.Union(s.VertexFirst, s.VertexSecond);
                    EdgeSolution.Add(s);
                }
            }

            Debug.WriteLine((DateTime.Now - start).TotalMilliseconds + " ms");
            //this.VisitedVertex = VertexList.Count;
        }
예제 #35
0
파일: Graph.cs 프로젝트: junian/NeoGraph
        public void GenerateEuclideanOurNeoKruskalMST(int bucket)
        {
            if (VertexList.Count == 0)
                return;

            DateTime start = DateTime.Now;
            NeoDisjointSet<Vertex> disjointSet = new NeoDisjointSet<Vertex>(VertexList);
            EdgeSolution.Clear();
            C5.IPriorityQueue<Edge>[] heap2 = new C5.IntervalHeap<Edge>[bucket];
            C5.IPriorityQueue<Edge> heap = new C5.IntervalHeap<Edge>(new EdgeComparer());
            for (int i = 0; i < heap2.Length; i++)
            {
                heap2[i] = new C5.IntervalHeap<Edge>(new EdgeComparer());
            }

            //this.VisitedVertex = VertexList.Count;
            for (int i = 0; i < VertexList.Count - 1; i++)
                for (int j = i + 1; j < VertexList.Count; j++)
                {
                    Edge e = new Edge(VertexList[i], VertexList[j]);
                    heap.Add(e);
                }

            double max = heap.FindMax().Length;
            double min = heap.FindMin().Length;

            while (heap.Count > 0)
            {
                Edge s = heap.DeleteMin();
                heap2[(int)Math.Floor((((s.Length - min) / (max - min)) * (bucket - 1)))].Add(s);
            }

            for (int i = 0; i < bucket && disjointSet.Count > 0; i++)
            {
                while (heap2[i].Count > 0 && disjointSet.Count > 0)
                {
                    Edge s = heap2[i].DeleteMin();
                    if (!disjointSet.IsSameSet(s.VertexFirst, s.VertexSecond))
                    {

                        disjointSet.Union(s.VertexFirst, s.VertexSecond);
                        EdgeSolution.Add(s);
                    }
                }
            }

            Debug.WriteLine((DateTime.Now - start).TotalMilliseconds + " ms");
            //this.VisitedVertex = VertexList.Count;
        }
예제 #36
0
        private bool VertexGuidedSearch(int iv, int iw)
        {
            var v = _nodes[iv];
            var w = _nodes[iw];

            f.Clear();
            b.Clear();

            f.Add(w);
            w.Value.InF = true;
            b.Add(v);
            v.Value.InB = true;

            w.Value.OutEnum = w.Value.Outgoing.GetEnumerator();
            w.Value.OutEnum.MoveNext();
            v.Value.InEnum = v.Value.Incoming.GetEnumerator();
            v.Value.InEnum.MoveNext();

            var fl = new C5.IntervalHeap<SGTNode<HKMSTNode>>();
            var bl = new C5.IntervalHeap<SGTNode<HKMSTNode>>();

            if (w.Value.OutEnum.Current != null)
                fl.Add(w);
            if (v.Value.InEnum.Current != null)
                bl.Add(v);

            // For ease of notation, we adopt the convention that the
            // minimum of an empty set is bigger than any other value and the maximum of an empty
            // set is smaller than any other value.
            SGTNode<HKMSTNode> u = null;
            SGTNode<HKMSTNode> z = null;
            if(fl.Count > 0)
                u = fl.FindMin();
            if(bl.Count > 0)
                z = bl.FindMax();

            while (fl.Count > 0 && bl.Count > 0 && (u == z || _nodeOrder.Query(z, u)))
            {
                // SEARCH-STEP(vertex u, vertex z)
                var x = u.Value.OutEnum.Current;
                var y = z.Value.InEnum.Current;
                u.Value.OutEnum.MoveNext();
                z.Value.InEnum.MoveNext();

                if (u.Value.OutEnum.Current == null)
                    fl.DeleteMin();
                if (z.Value.InEnum.Current == null)
                    bl.DeleteMax();

                if(x.Value.InB)
                {
                    f.ForEach(item => item.Value.InF = false);
                    b.ForEach(item => item.Value.InB = false);
                    return false; // Pair(uz.from, x.Current);
                }
                else if (y.Value.InF)
                {
                    f.ForEach(item => item.Value.InF = false);
                    b.ForEach(item => item.Value.InB = false);
                    return false; // Pair(y.Current, uz.to);
                }

                if (!x.Value.InF)
                {
                    f.Add(x);
                    x.Value.InF = true;
                    x.Value.OutEnum = x.Value.Outgoing.GetEnumerator();
                    x.Value.OutEnum.MoveNext();
                    if (x.Value.OutEnum.Current != null)
                        fl.Add(x);
                }
                if (!y.Value.InB)
                {
                    b.Add(y);
                    y.Value.InB = true;
                    y.Value.InEnum = y.Value.Incoming.GetEnumerator();
                    y.Value.InEnum.MoveNext();
                    if (y.Value.InEnum.Current != null)
                        bl.Add(y);
                }

                // End of SEARCH-STEP(vertex u, vertex z)
                if (fl.Count > 0)
                    u = fl.FindMin();
                if (bl.Count > 0)
                    z = bl.FindMax();

            }

            // let t = min({v}∪{x ∈ F|out(x) = null} and reorder the vertices in F< and B> as discussed previously.
            var vAndf = f.FindAll(item => item.Value.OutEnum.Current != null);
            vAndf.Add(v);
            var t = vAndf.Min();
            // Let F< = { x ∈ F | x < t} and
            var fb = f.FindAll(item => item.Label < t.Label);
            // B > = { y ∈ B | y > t}.
            var bf = b.FindAll(item => item.Label > t.Label);

            if(t == v)
            {
                // move all vertices in fb just after t ... bf is empty
                foreach (var node in fb)
                    _nodeOrder.Remove(node);

                if(fb.Count > 1)
                    fb = TopoSort(fb);

                if (fb.Count > 0)
                {
                    var prev = _nodeOrder.insertAfter(t, fb[0]);
                    for (int i = 1; i < fb.Count; i++)
                        prev = _nodeOrder.insertAfter(prev, fb[i]);
                }
            }
            if (t.Label < v.Label)
            {
                // move all vertices in fb just before t and all vertices in bf just before all vertices in fb

                // This is required as the articles states
                if (bf.Count > 1)
                    bf = TopoSort(bf);
                if (fb.Count > 1)
                    fb = TopoSort(fb);

                foreach (var node in bf)
                    _nodeOrder.Remove(node);
                foreach (var node in fb)
                    _nodeOrder.Remove(node);

                foreach (var item in fb)
                    bf.Add(item);

                if (bf.Count > 0)
                {
                    var prev = _nodeOrder.insertBefore(t, bf[bf.Count-1]);
                    if(bf.Count > 1)
                    {
                        for (int i = bf.Count - 2; i >= 0; i--)
                            prev = _nodeOrder.insertBefore(prev, bf[i]);
                    }
                }
            }

            // reset bools
            f.ForEach(item => item.Value.InF = false);
            b.ForEach(item => item.Value.InB = false);

            // all done add to Outgoing and Incoming
            _nodes[iv].Value.Outgoing.Add(_nodes[iw]);
            _nodes[iw].Value.Incoming.Add(_nodes[iv]);

            return true;
        }