Exemplo n.º 1
0
        public virtual AstarNode <T> Solve(AstarNode <T> Root, params object[] args)
        {
            IntervalHeap <AstarNode <T> > ih = new IntervalHeap <AstarNode <T> >();

            ih.Add(Root);
            AstarNode <T> curNode;
            bool          add;

            while (ih.Count > 0)
            {
                curNode = ih.DeleteMin();
                curNode.Expand(args);

                if (curNode.Completed(args))
                {
                    return(curNode);
                }

                if (curNode.Children.Count > 0)
                {
                    foreach (var node in curNode.Children)
                    {
                        if (node.CanAdd())
                        {
                            ih.Add(node);
                            added++;
                        }
                        total++;
                    }
                }
            }
            return(null);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Sorts the vertices in topological order
        /// </summary>
        /// <returns>List of topological sorted vertices</returns>
        public List <Vertex> TopologicalSort(ColumnChanges columnChanges)
        {
            IPriorityQueue <Vertex> priorityQueue = new IntervalHeap <Vertex>(new VerticesComparer(Options, columnChanges));
            var sortedVertices = new List <Vertex>();

            var incomingEdges = new Dictionary <Vertex, int>();

            foreach (var v in Vertices)
            {
                incomingEdges[v] = v.IngoingEdges().Count;
                if (incomingEdges[v] == 0)
                {
                    priorityQueue.Add(v);
                }
            }

            while (!priorityQueue.IsEmpty)
            {
                Vertex v = priorityQueue.FindMin();
                sortedVertices.Add(v);
                priorityQueue.DeleteMin();

                foreach (var e in v.OutgoingEdges())
                {
                    incomingEdges[e.Destination]--;
                    if (incomingEdges[e.Destination] == 0)
                    {
                        priorityQueue.Add(e.Destination);
                    }
                }
            }

            return(sortedVertices);
        }
Exemplo n.º 3
0
        public void Replace5b()
        {
            for (var size = 0; size < 130; size++)
            {
                IPriorityQueue <double>       q       = new IntervalHeap <double>();
                IPriorityQueueHandle <double> handle1 = null;
                q.Add(ref handle1, -3.0);
                Assert.AreEqual(-3.0, q.FindMax());
                for (var i = 1; i < size; i++)
                {
                    q.Add(-i - 3.0);
                }
                Assert.AreEqual(-3.0, q.FindMax());
                for (var max = -2; max <= 10; max++)
                {
                    Assert.AreEqual(max - 1.0, q.Replace(handle1, max));
                    Assert.AreEqual(max, q.FindMax());
                }

                Assert.AreEqual(10.0, q.DeleteMax());
                for (var i = 1; i < size; i++)
                {
                    Assert.AreEqual(-i - 3.0, q.DeleteMax());
                }
                Assert.IsTrue(q.IsEmpty);
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// The Interval heap used in this method represents the min heap
        /// required form the last sub task of task 7.37.
        /// </summary>
        /// <param name="array"></param>
        /// <param name="kSmallestElement"></param>
        /// <returns></returns>
        public int FindKthSmallestElementUsingMinHeap(int[] array, int kSmallestElement)
        {
            var n = array.Length;

            if (n - 1 < kSmallestElement)
            {
                return(int.MinValue);
            }

            IntervalHeap <int> intervalHeap = new IntervalHeap <int>();

            for (int i = 0; i < n; i++)
            {
                if (intervalHeap.Count < kSmallestElement)
                {
                    intervalHeap.Add(array[i]);
                }
                else
                {
                    if (intervalHeap.FindMax() > array[i])
                    {
                        intervalHeap.DeleteMax();
                        intervalHeap.Add(array[i]);
                    }
                }
            }
            for (int i = 0; i < kSmallestElement - 1; i++)
            {
                intervalHeap.DeleteMin();
            }
            return(intervalHeap.FindMin());
        }
Exemplo n.º 5
0
        public void Bug20130208()
        {
            IPriorityQueue <double>       q = new IntervalHeap <double>();
            IPriorityQueueHandle <double> h0 = null, h2 = null, h4 = null, h7 = null, h5 = null;

            // Add(43, 0);
            q.Add(ref h0, 43);
            // Remove();
            q.DeleteMin();
            // XAddMaxReplace(9, 2);
            q.Add(ref h2, Double.MaxValue);
            q[h2] = 9;
            // XAddMaxReplace(32, 4);
            q.Add(ref h4, Double.MaxValue);
            q[h4] = 32;
            // XAddMaxReplace(44, 7);
            q.Add(ref h7, Double.MaxValue);
            q[h7] = 44;
            // Remove();
            q.DeleteMin();
            // XAddMaxReplace(0, 5);
            q.Add(ref h5, Double.MaxValue);
            q[h5] = 0;
            // Internally inconsistent data structure already now
            Assert.IsTrue(q.Check());
        }
        public ListNode mergeKLists(List <ListNode> a)
        {
            if (a == null || a.Count == 0)
            {
                return(null);
            }

            var pq = new IntervalHeap <ListNode>();

            foreach (var ln in a)
            {
                if (ln != null)
                {
                    pq.Add(ln);
                }
            }

            var head = new ListNode(0);
            var p    = head;

            while (pq.Count > 0)
            {
                var t = pq.DeleteMin();
                p.next = t;
                p      = p.next;

                if (t.next != null)
                {
                    pq.Add(t.next);
                }
            }
            return(head.next);
        }
Exemplo n.º 7
0
        private void GetTopDistances(IEnumerable <string> threadDictionary)
        {
            var comparer = new WordDistanceComparer();
            var heap     = new IntervalHeap <WordDistance>(HeapCapacity, comparer);

            foreach (var entry in threadDictionary)
            {
                var threshold = heap.Any() ? heap.FindMax().Distance : int.MaxValue;
                var distance  = Value.GetDistance(entry, threshold);

                if (heap.Count < HeapCapacity)
                {
                    heap.Add(new WordDistance(entry, distance));
                    continue;
                }

                if (distance >= threshold)
                {
                    continue;
                }

                heap.DeleteMax();
                heap.Add(new WordDistance(entry, distance));
            }

            foreach (var wordDistance in heap)
            {
                results.Add(wordDistance);
            }
        }
        public static List <Point> FindClosestPoints(Point[] points, int k)
        {
            IPriorityQueue <Point> maxHeap = new IntervalHeap <Point>();

            // new IPriorityQueueHandle<Point>((p1, p2) => p2.distFromOrigin() - p1.distFromOrigin());

            // put first 'k' points in the max heap
            for (int i = 0; i < k; i++)
            {
                maxHeap.Add(points[i]);
            }
            // go through the remaining points of the input array, if a point is closer to
            // the origin than the top point of the max-heap, remove the top point from
            // heap and add the point from the input array
            for (int i = k; i < points.Length; i++)
            {
                if (points[i].distFromOrigin() < maxHeap.Max().distFromOrigin())
                {
                    maxHeap.DeleteMax();
                    maxHeap.Add(points[i]);
                }
            }

            //Point x = new Point(k, 0);

            // the heap has 'k' points closest to the origin, return them in a list
            return(maxHeap.ToList <Point>());
        }
Exemplo n.º 9
0
        public void Replace5a()
        {
            for (var size = 0; size < 130; size++)
            {
                IPriorityQueue <double>       q       = new IntervalHeap <double>();
                IPriorityQueueHandle <double> handle1 = null;
                q.Add(ref handle1, 3.0);
                Assert.AreEqual(3.0, q.FindMin());
                for (var i = 1; i < size; i++)
                {
                    q.Add(i + 3.0);
                }
                Assert.AreEqual(3.0, q.FindMin());
                for (var min = 2; min >= -10; min--)
                {
                    Assert.AreEqual(min + 1.0, q.Replace(handle1, min));
                    Assert.AreEqual(min, q.FindMin());
                }

                Assert.AreEqual(-10.0, q.DeleteMin());
                for (var i = 1; i < size; i++)
                {
                    Assert.AreEqual(i + 3.0, q.DeleteMin());
                }
                Assert.IsTrue(q.IsEmpty);
            }
        }
Exemplo n.º 10
0
        private void HandleSiteEvent(SiteEvent siteEvent)
        {
            EventTree.TreeNode node = _eventTree.GetClosest(this, _eventTree.GetRoot(), siteEvent);


            if (node == null || node is EventTree.BreakpointNode)
            {
                return;
            }
            EventTree.LeafNode closest = (EventTree.LeafNode)node;

            if (closest.GetDisappearEvent() != null)
            {
                _eventQueue.Delete(closest.GetDisappearEvent().GetHandle());

                closest.SetDisappearEvent(null);
            }

            List <CircleEvent> circleEvents2 = _eventTree.InsertNewSiteEvent(closest, new TreeItem(siteEvent.V()));

            foreach (var ce in circleEvents2)
            {
                IPriorityQueueHandle <IEvent> h = null;
                _eventQueue.Add(ref h, ce);
                ce.SetHandle(h);
            }
        }
Exemplo n.º 11
0
        public override void Update(Pose goal)
        {
            bool[,] expanded = new bool[grid.NumColumns, grid.NumRows];
            LinkedList <GridCell>[,] memoized = new LinkedList <GridCell> [grid.NumColumns, grid.NumRows];
            GridCell startCell = grid.PointToCellPosition(goal.Position);
            IntervalHeap <GridCellValue> open = new IntervalHeap <GridCellValue>();

            for (int c = 0; c < grid.NumColumns; c++)
            {
                for (int r = 0; r < grid.NumRows; r++)
                {
                    heuristic[c, r] = float.PositiveInfinity;
                    expanded[c, r]  = false;
                }
            }

            heuristic[startCell.C, startCell.R] = 0f;
            open.Add(new GridCellValue(startCell, 0f));

            while (!open.IsEmpty)
            {
                GridCell cell = open.DeleteMin().Position;
                expanded[cell.C, cell.R] = true;

                LinkedList <GridCell> neighbors = memoized[cell.C, cell.R];
                if (neighbors == null)
                {
                    neighbors = grid.Get8Neighbors(cell);
                    memoized[cell.C, cell.R] = neighbors;
                }

                foreach (GridCell n in neighbors)
                {
                    if (expanded[n.C, n.R])
                    {
                        continue;
                    }

                    if (grid.OccupiedCells[n.C, n.R] > 0)
                    {
                        continue;
                    }

                    if (grid.GVD.GetObstacleDistance(n) <= Car.HALF_CAR_WIDTH)
                    {
                        continue;
                    }

                    float dist = cell.C == n.C || cell.R == n.R ? 1f : sqrt2;
                    dist += heuristic[cell.C, cell.R];

                    if (dist < heuristic[n.C, n.R])
                    {
                        heuristic[n.C, n.R] = dist;
                        open.Add(new GridCellValue(n, dist));
                    }
                }
            }
        }
Exemplo n.º 12
0
 /*
  *  This method creates the workers
  */
 public void CreateWorkers() // This method creates workers
 {
     for (int i = 0; i < numberOfWorkers; i++)
     {
         Worker worker = new Worker("Worker" + (i + 1));
         workersHeap.Add(worker);
     }
 }
Exemplo n.º 13
0
 private void setVoro(GridCell s)
 {
     nearestVoro[s.C, s.R]    = s;
     voroDist[s.C, s.R]       = 0;
     voroDistActual[s.C, s.R] = 0f;
     voroOpen.Add(new GridCellValue(s, 0));
     voroToProcess[s.C, s.R] = true;
 }
Exemplo n.º 14
0
    public void getMovementPaths(Vector2 startPosition, int moveDistance, bool highlight)
    {
        //Get no go areas from player controllers
        var unitPositions = Controller.getUnitPositions();
        // Pathfinding stuff
        IntervalHeap <PathfinderNode> frontier = new IntervalHeap <PathfinderNode>(new PathfinderNode(new Vector2(), 0));

        frontier.Add(new PathfinderNode(startPosition, 0));
        Dictionary <Vector2, Vector2> cameFrom  = new Dictionary <Vector2, Vector2>();
        Dictionary <Vector2, int>     costSoFar = new Dictionary <Vector2, int>();

        cameFrom.Add(startPosition, new Vector2(-1, -1));
        costSoFar.Add(startPosition, 0);

        while (frontier.Count > 0)
        {
            //Get current
            PathfinderNode current = frontier.FindMin();
            frontier.DeleteMin();

            // iterate through neighbours
            foreach (Vector2 next in map.getNeibour(current.position))
            {
                if (unitPositions.Contains(next))
                {
                    continue;
                }
                int newCost = map.tileTypes[map.tiles[(int)next.x, (int)next.y]].cost + costSoFar[current.position];
                if (newCost <= moveDistance && (!costSoFar.ContainsKey(next) || newCost < costSoFar[next]))
                {
                    int priority = newCost;
                    if (costSoFar.ContainsKey(next))
                    {
                        costSoFar[next] = newCost;

                        PathfinderNode newNode = new PathfinderNode(next, priority);
                        frontier.Add(newNode);

                        cameFrom[next] = current.position;
                    }
                    else
                    {
                        costSoFar.Add(next, newCost);
                        PathfinderNode newNode = new PathfinderNode(next, priority);
                        frontier.Add(newNode);

                        cameFrom.Add(next, current.position);
                    }
                }
            }
        }

        if (highlight)
        {
            map.highlightArea(new List <Vector2>(costSoFar.Keys), new Color(0, 1, 1));
        }
        pathingData = cameFrom;
    }
Exemplo n.º 15
0
        public void PriorityMinEdgeFindsFirst()
        {
            IPriorityQueue <WeightedEdge <int> > queue = new IntervalHeap <WeightedEdge <int> >();

            queue.Add(new WeightedEdge <int>(0, 1, 1));
            queue.Add(new WeightedEdge <int>(1, 2, Double.PositiveInfinity));

            Assert.AreEqual(new WeightedEdge <int>(0, 1, 1), queue.FindMin());
        }
Exemplo n.º 16
0
 public void SetObstacle(GridCell s, int obstId)
 {
     obst[s.C, s.R]       = s;
     comp[s.C, s.R]       = obstId;
     dist[s.C, s.R]       = 0;
     distActual[s.C, s.R] = 0f;
     open.Add(new GridCellValue(s, 0));
     toProcess[s.C, s.R] = true;
 }
Exemplo n.º 17
0
        public void SetObstacle(GridCell cell, int obstacleId)
        {
            distNew[cell.C, cell.R] = 0f;
            obst[cell.C, cell.R]    = obstacleId;
            parent[cell.C, cell.R]  = cell;
            valid.Add(obstacleId);

            open.Add(new GridCellValue(cell, 0f));
        }
Exemplo n.º 18
0
        private static List <string> BFSPhase3(string toFind, Dictionary <string, List <string> > newGraph, string startPoint)
        {
            var q      = new IntervalHeap <string>();
            var distTo = new Dictionary <string, int>();
            var edgeTo = new Dictionary <string, string>();
            var marked = new Dictionary <string, bool>();

            //We just start at the first node
            q.Add(startPoint);
            //We now just keep track of occurrences
            //Should be two consecutive nodes? This does not do that currently
            //Unsure of examples where this would fail
            distTo.Add(startPoint, 0);
            marked.Add(startPoint, true);
            var counter = 0;

            while (!q.IsEmpty)
            {
                var v = q.DeleteMin();
                foreach (var w in newGraph[v])
                {
                    if (w.Equals(toFind))
                    {
                        counter++;
                    }
                    var mark = false;
                    if (marked.ContainsKey(w))
                    {
                        mark = marked[w];
                    }
                    if (!mark)
                    {
                        marked[w] = true;
                        distTo[w] = distTo[v] + 1;
                        edgeTo[w] = v;
                        q.Add(w);
                    }
                }
            }


            var path     = new List <string>();
            var gotThere = marked[toFind];

            if (gotThere)
            {
                string x;
                for (x = toFind; distTo[x] != 0; x = edgeTo[x])
                {
                    path.Add(x);
                }
                path.Add(x);
            }
            //Now path should contain the shortest possible path;
            //Is not part of a cycle
            return(path);
        }
Exemplo n.º 19
0
        public void findGreatestDiff(State state)          //O(n^3)
        {
            int    chosenX      = 0;                       //city x to city y
            int    chosenY      = 0;
            double greatestDiff = double.NegativeInfinity; //initialize to -oo to find what the greatest
                                                           //difference is
            List <PointF> points = new List <PointF>();

            for (int i = 0; i < state.getMap().GetLength(0); i++)     //rows, O(n)
            {
                for (int j = 0; j < state.getMap().GetLength(1); j++) //columns
                {
                    if (state.getPoint(i, j) == 0)                    //if point is 0
                    {
                        points.Add(new PointF(i, j));                 //store all 0's in a point array
                    }
                }
            }
            for (int i = 0; i < points.Count; i++)                                                                            //loop through 0's to find the greatest difference
            {                                                                                                                 //O(n^3)                               there will be atmost n points, because the entire
             //matrix will be 0
                int possibleMax = findExcludeMinusInclude(Convert.ToInt32(points[i].X), Convert.ToInt32(points[i].Y), state); //O(n^2)
                if (possibleMax >= greatestDiff)                                                                              //set the point to point values, if it is 0 is covered by =
                {
                    chosenX      = Convert.ToInt32(points[i].X);
                    chosenY      = Convert.ToInt32(points[i].Y);
                    greatestDiff = possibleMax;
                }
            }
            State include = makeInclude(chosenX, chosenY, state); //O(n^2)

            if (BSSF > include.getLB())                           //if include's lowerbound is better than the BSSF
            {
                include.setEdge(chosenX, chosenY);                //set the edge in the dictionary
                checkCycles(include, chosenX, chosenY);           //O(n), make sure there are no potential cycles
                queue.Add(include);                               //add to the queue to be popped off later
            }

            if (isDictionaryFilled(include)) //O(n), have all of the edges been filled? then the include.LB is better
            {                                //than the current BSSF, set the BSSF
                BSSF      = include.getLB();
                bestState = include;         //save the "bestState"
            }

            State exclude = makeExclude(chosenX, chosenY, state); //O(n^2)

            if (BSSF > exclude.getLB())                           //if exclude's lowerbound is than the BSSF, add it to the queue
            {
                queue.Add(exclude);
            }
            if (isDictionaryFilled(exclude)) //O(n), have all of the edges been filled?
            {                                // then exclude's lowerbound is better, set the BSSF to exclude.LB
                BSSF      = exclude.getLB();
                bestState = exclude;
            }
        }
Exemplo n.º 20
0
        public CostCounter ExactSearch(double[] ts, out IndexFileDist bsf)
        {
            CostCounter meas = new CostCounter(0, 0);
            IntervalHeap <IndexEntryDist> pq = new IntervalHeap <IndexEntryDist>(NumIndexEntries);

            // approx search
            TermEntry approx = ApproximateSearch(ts);

            bsf = Index <DATAFORMAT> .MinFileEucDist(ts, approx.FileName);

            meas.IO++;
            meas.distance += approx.NumTimeSeries;

            // initalize pq with IndexEntries at root node
            foreach (IndexEntry e in index.Values)
            {
                pq.Add(new IndexEntryDist(e, Sax.MinDistPAAToiSAX(
                                              Sax.SaxStrToSaxVals(e.SaxWord), options.SaxOpts, ts)));
            }

            while (!pq.IsEmpty)
            {
                IndexEntryDist minInfo  = pq.DeleteMin();
                IndexEntry     minEntry = minInfo.entry;

                if (minInfo.dist >= bsf.distance)
                {
                    break;
                }

                if (minEntry is TermEntry)
                {
                    IndexFileDist posMin = Index <DATAFORMAT> .MinFileEucDist(ts, ((TermEntry)minEntry).FileName);

                    meas.IO++;
                    meas.distance += minEntry.NumTimeSeries;

                    // update bsf
                    if (posMin.distance < bsf.distance)
                    {
                        bsf = posMin;
                    }
                }
                else if (minEntry is SplitEntry <DATAFORMAT> )
                {
                    SplitEntry <DATAFORMAT> sEntry = minEntry as SplitEntry <DATAFORMAT>;
                    foreach (IndexEntry e in sEntry.GetIndexEntries())
                    {
                        pq.Add(new IndexEntryDist(e, Sax.MinDistPAAToiSAX(
                                                      Sax.SaxStrToSaxVals(e.SaxWord), sEntry.Options.SaxOpts, ts)));
                    }
                }
            }
            return(meas);
        }
Exemplo n.º 21
0
        public static PathfindingResult FindPath(this Unit unit, Field destination)
        {
            if (unit.Location == destination)
            {
                return(new PathfindingResult(null, false));
            }

            var  counter   = 0;
            bool success   = false;
            var  start     = unit.Location;
            var  frontier  = new IntervalHeap <FrontierElement>(new FrontierElement.Comparer());
            var  cameFrom  = new Dictionary <Field, Field>();
            var  costSoFar = new Dictionary <Field, int>();

            frontier.Add(new FrontierElement(0, start));
            cameFrom.Add(start, null);
            costSoFar.Add(start, 0);

            while (!frontier.IsEmpty && counter < 150)
            {
                counter++;
                var current = frontier.DeleteMin();
                if (current.Field == destination)
                {
                    success = true;
                    break;
                }

                foreach (var neighbour in current.Field.Neighbours)
                {
                    var movement = unit.MovementAvailability(current.Field, neighbour);
                    if (movement.Type != MovementType.Free)
                    {
                        continue;
                    }

                    var newCost = movement.Cost;
                    newCost += costSoFar[current.Field];

                    if (!costSoFar.ContainsKey(neighbour) || newCost < costSoFar[neighbour])
                    {
                        costSoFar[neighbour] = newCost;
                        var priority = neighbour.DistanceTo(destination) + newCost;
                        frontier.Add(new FrontierElement(priority, neighbour));
                        cameFrom[neighbour] = current.Field;
                    }
                }
            }

            return(new PathfindingResult(
                       path: success ? GetPath(cameFrom, destination) : null,
                       success: success
                       ));
        }
Exemplo n.º 22
0
        public void Bug20130208Case3()
        {
            // Case 3: only left.first
            IPriorityQueue <double>       q        = new IntervalHeap <double>();
            IPriorityQueueHandle <double> topRight = null;

            q.Add(20);
            q.Add(ref topRight, 30);
            q.Add(25);
            q[topRight] = 10;
            Assert.IsTrue(q.Check());
            Assert.IsTrue(q.FindMax() == 25);
        }
Exemplo n.º 23
0
        public Battle(IActor[] actors, int length = 180, int num_enemies = 1)
        {
            Actors      = actors;
            Friendlies  = actors;
            FightLength = length * 1000;
            _logger.Debug("Fight length: {0}", FightLength);

            Time       = 0;
            TickOffset = new Random().Next(0, 3000);
            _logger.Debug("Tick offset: {0}", TickOffset);

            foreach (IActor actor in actors)
            {
                _logger.Debug("Actor added: [{0}] {1}", actor.JobID.ToString(), actor.Name);
            }

            // Initialize enemies.
            Enemies = new ITarget[num_enemies];
            for (int i = 0; i < num_enemies; i++)
            {
                Enemies[i] = new StrikingDummy();
                _logger.Debug("Enemy added: {0}", Enemies[i].Name);
            }

            Targets = Friendlies.ToList().Concat(Enemies.ToList()).ToArray();

            EventQueue = new IntervalHeap <BattleEvent>();
            EventLog   = new ArrayList <CombatLogEvent>();

            // Add the inital Actor decisions to the queue.  These should drive the rest of the
            // simulation.
            foreach (IActor actor in Actors)
            {
                EventQueue.Add(new BattleEvent(BattleEventType.ACTOR_READY, Time, actor));
            }

            // Event to signal the end of the fight.
            EventQueue.Add(new BattleEvent(BattleEventType.FIGHT_COMPLETE, FightLength));

            // Event to signal the next Aura tick.
            EventQueue.Add(new BattleEvent(BattleEventType.AURA_TICK, Time + TickOffset));

            if (TickOffset > 1500)
            {
                EventQueue.Add(new BattleEvent(BattleEventType.REGEN_TICK, 1500 - TickOffset));
            }
            else
            {
                EventQueue.Add(new BattleEvent(BattleEventType.REGEN_TICK, TickOffset + 1500));
            }
        }
Exemplo n.º 24
0
    private static void addNodeToMap(Node node)
    {
        //implement Dijkstra alghoritm:
        IntervalHeap <NodeEntry>         sortedNodes = new IntervalHeap <NodeEntry>();
        HashDictionary <Node, NodeEntry> hashedNodes = new HashDictionary <Node, NodeEntry>();
        NodeEntry thisNode = new NodeEntry();

        thisNode.Node = node;
        bool firstAdded = sortedNodes.Add(ref thisNode.Handle, thisNode);

        Debug.Assert(firstAdded);
        hashedNodes.Add(node, thisNode);
        while (sortedNodes.Count != 0)
        {
            NodeEntry currentNode = sortedNodes.DeleteMin();
            foreach (Link link in currentNode.Node.NetworkInterfaces.Interfaces.Keys)
            {
                //get the node from the second side of link
                Node   secondNode = (link.LinkSides[0].ConnectedNode == currentNode.Node) ? link.LinkSides[1].ConnectedNode : link.LinkSides[0].ConnectedNode;
                double distance   = link.Metric + currentNode.Distance;
                if (hashedNodes.Contains(secondNode))
                {
                    NodeEntry entry = hashedNodes[secondNode];
                    if (entry.Distance > distance)
                    {
                        entry.Distance = distance;
                        sortedNodes.Replace(entry.Handle, entry);
                    }
                }
                else
                {
                    NodeEntry newEntry = new NodeEntry();
                    newEntry.Node     = secondNode;
                    newEntry.Distance = distance;
                    hashedNodes.Add(secondNode, newEntry);
                    bool added = sortedNodes.Add(ref newEntry.Handle, newEntry);
                    Debug.Assert(added);
                }
            }
        }
        //hashedNodes.Remove(node);
        HashDictionary <Node, double> finalDistances = new HashDictionary <Node, double>();

        foreach (NodeEntry entry in hashedNodes.Values)
        {
            finalDistances.Add(entry.Node, entry.Distance);
        }
        distances.Add(node, finalDistances);
    }
 static void Main()
 {
     var people = new IntervalHeap<Person>();
     people.Add(new Person("Nakov", 25));
     people.Add(new Person("Petya", 24));
     people.Add(new Person("Pesho", 25));
     people.Add(new Person("Maria", 22));
     people.Add(new Person("Ivan", -1));
     Console.WriteLine("Min: {0}", people.FindMin());
     Console.WriteLine("Max: {0}", people.FindMax());
     while (people.Count > 0)
     {
         Console.WriteLine(people.DeleteMin());
     }
 }
Exemplo n.º 26
0
        public void Bug20130208Case5b()
        {
            // Case 5b: only right.first, not max
            IPriorityQueue <double>       q        = new IntervalHeap <double>();
            IPriorityQueueHandle <double> topRight = null;

            q.Add(20);
            q.Add(ref topRight, 30);
            q.Add(24);
            q.Add(28);
            q.Add(26);
            q[topRight] = 10;
            Assert.IsTrue(q.Check());
            Assert.IsTrue(q.FindMax() == 28);
        }
Exemplo n.º 27
0
 public void Add(CompositeFactor cf)
 {
     if (hashes.Add(cf.GetLongHashCode()))
     {
         items.Add(cf);
     }
 }
Exemplo n.º 28
0
//HELPERS
    protected override NetworkInterface getRoute(Node destination)
    {
        IntervalHeap <NodeEntry>         sortedNodes = new IntervalHeap <NodeEntry>();
        HashDictionary <Node, NodeEntry> hashedNodes = new HashDictionary <Node, NodeEntry>();
        NodeEntry thisNode = new NodeEntry();

        thisNode.Node = node;
        thisNode.Time = Timer.CurrentTime;
        bool      added = sortedNodes.Add(ref thisNode.Handle, thisNode);
        NodeEntry temp;
        bool      found = sortedNodes.Find(thisNode.Handle, out temp);

        Debug.Assert(found);
        Debug.Assert(added);
        hashedNodes.Add(node, thisNode);
        double currentTime = -1;

        while (sortedNodes.Count > 0)
        {
            NodeEntry current = sortedNodes.DeleteMin();
            Debug.Assert(current.Time >= currentTime);
            currentTime = current.Time;
            if (current.Node == destination)
            {
                return(extractInterface(current, hashedNodes));
            }
            nextMove(current, sortedNodes, hashedNodes);
            Debug.Assert(sortedNodes.Check());
        }

        //route not found
        return(null);
    }
Exemplo n.º 29
0
        private static void addToFrontier(CytoscapeMap map, IntervalHeap <CytoscapeNode> frontier, CytoscapeNode node)
        {
            CytoscapeNode tempNode;

            foreach (CytoscapeConnection connection in node.connections)
            {
                int undirectedTargetID = connection.undirectedTarget(node);
                tempNode = map.getNode(undirectedTargetID);
                // Discard cyclic paths
                if (!node.hasVisitedNode(undirectedTargetID))
                {
                    // Keep track of the path taken
                    if (node.path == null || !node.path.Any())
                    {
                        node.path = new List <CytoscapeNode>();
                        node.path.Add(node);
                    }
                    // Make sure to be duplicating the path instead of pointing at node's path field
                    tempNode.path = new List <CytoscapeNode>(node.path);
                    tempNode.path.Add(tempNode);
                    // f is the heuristic plus the distance traveled so far
                    tempNode.distance = node.distance + connection.distance;
                    tempNode.f        = tempNode.heuristic + tempNode.distance;
                    frontier.Add(tempNode);
                }
            }
        }
Exemplo n.º 30
0
        public static void DikstrasSearch(Node[] nodes, Node source)
        {
            var table = new HashDictionary <Node, Entry>();

            foreach (var node in nodes)
            {
                table.Add(node, new Entry(false, float.MaxValue, null));
            }

            var sourceEntry = table[source];

            sourceEntry.cost = 0;
            table[source]    = sourceEntry;

            var priorityQueue =
                new IntervalHeap <NodeAndCost>(
                    new DelegateComparer <NodeAndCost>(
                        (nodeAndCost1, nodeAndCost2) => nodeAndCost1.cost.CompareTo(nodeAndCost2.cost)))
            {
                new NodeAndCost(source, 0)
            };


            while (!priorityQueue.IsEmpty)
            {
                var nodeAndCost = priorityQueue.DeleteMin();

                var currentNode = nodeAndCost.node;

                if (table[currentNode].known)
                {
                    continue;
                }
                var currentNodeEntry = table[currentNode];
                currentNodeEntry.known = true;
                table[currentNode]     = currentNodeEntry;

                foreach (var edge in currentNode.outEdges)
                {
                    var toNode     = edge.ToNode;
                    var toNodeCost = table[currentNode].cost + edge.Cost;

                    if (!(table[toNode].cost > toNodeCost))
                    {
                        continue;
                    }
                    var toNodeEntry = table[toNode];
                    toNodeEntry.cost        = toNodeCost;
                    toNodeEntry.predecessor = currentNode;
                    table[toNode]           = toNodeEntry;
                    priorityQueue.Add(new NodeAndCost(toNode, toNodeCost));
                }
            }

            foreach (var node in nodes)
            {
                _NEXT_NODE_AND_COST_TABLE[new NodePair(source, node)] =
                    ExtractNextNodeFromTable(table, source, node);
            }
        }
Exemplo n.º 31
0
        /// <summary>
        /// Dijkstra. Attempts to find the shortest path from start to end, only using pixels inside the "border pixel" collection that was discovered in FloodFill() <see cref="FloodFill"/>
        /// </summary>
        /// <param name="start"></param>
        /// <param name="end"></param>
        /// <returns></returns>
        private System.Collections.Generic.IList <Point> LeastCostPath(Point start, Point end)
        {
            var h = new IntervalHeap <Node>(new NodeCmpr());
            var n = new Node
            {
                Back  = null,
                Cost  = 0,
                Point = start
            };

            h.Add(n);
            _considered = new PixelTracker(_image.Width, _image.Height)
            {
                OutsideDefault = true
            };
            while (!h.IsEmpty)
            {
                var node = h.DeleteMin();
                if (node.Point.X == end.X && node.Point.Y == end.Y)
                {
                    return(Backtrace(node));
                }
                Follow(h, node, node.Point.X - 1, node.Point.Y - 1);
                Follow(h, node, node.Point.X - 1, node.Point.Y);
                Follow(h, node, node.Point.X - 1, node.Point.Y + 1);
                Follow(h, node, node.Point.X, node.Point.Y + 1);
                Follow(h, node, node.Point.X + 1, node.Point.Y + 1);
                Follow(h, node, node.Point.X + 1, node.Point.Y);
                Follow(h, node, node.Point.X + 1, node.Point.Y - 1);
                Follow(h, node, node.Point.X, node.Point.Y - 1);
            }
            return(new Point[] {});
        }
Exemplo n.º 32
0
        /// <summary>Score items for a given user</summary>
        /// <param name="recommender">the recommender to use</param>
        /// <param name="user_id">the numerical ID of the user</param>
        /// <param name="candidate_items">a collection of numerical IDs of candidate items</param>
        /// <param name="n">number of items to return (optional)</param>
        /// <returns>a list of pairs, each pair consisting of the item ID and the predicted score</returns>
        public static System.Collections.Generic.IList<Pair<int, float>> ScoreItems(this IRecommender recommender, int user_id, System.Collections.Generic.IList<int> candidate_items, int n = -1)
        {
            if (n == -1)
            {
                var result = new Pair<int, float>[candidate_items.Count];
                for (int i = 0; i < candidate_items.Count; i++)
                {
                    int item_id = candidate_items[i];
                    result[i] = new Pair<int, float>(item_id, recommender.Predict(user_id, item_id));
                }
                return result;
            }
            else
            {
                var comparer = new DelegateComparer<Pair<int, float>>( (a, b) => a.Second.CompareTo(b.Second) );
                var heap = new IntervalHeap<Pair<int, float>>(n, comparer);
                float min_relevant_score = float.MinValue;

                foreach (int item_id in candidate_items)
                {
                    float score = recommender.Predict(user_id, item_id);
                    if (score > min_relevant_score)
                    {
                        heap.Add(new Pair<int, float>(item_id, score));
                        if (heap.Count > n)
                        {
                            heap.DeleteMin();
                            min_relevant_score = heap.FindMin().Second;
                        }
                    }
                }

                var result = new Pair<int, float>[heap.Count];
                for (int i = 0; i < result.Length; i++)
                    result[i] = heap.DeleteMax();
                return result;
            }
        }
Exemplo n.º 33
0
        public List<Node> AStarSearch(Vector3 start, Vector3 end)
        {
            var frontier = new IntervalHeap<Node>(new NodeComparer());
            var cameFrom = new Dictionary<string, Node>();
            //var costSoFar = new Dictionary<string, int>();

            var startNode = FindNode(start);
            var endNode = FindNode(end);

            frontier.Add(startNode);
            cameFrom.Add(startNode.ToString(), null);

            while (frontier.Any())
            {
                var currentNode = frontier.FindMin();
                frontier.DeleteMin();

                if (currentNode == endNode)
                    break;

                foreach (var neighbor in currentNode.Neighboors)
                {
                    var neighborName = neighbor.ToString();

                    if (cameFrom.ContainsKey(neighborName))
                        continue;

                    var newCost = Heuristic(endNode, neighbor);

                    neighbor.Cost = newCost;

                    frontier.Add(neighbor);
                    cameFrom.Add(neighborName, currentNode);
                }
            }

            var current = endNode;
            var path = new List<Node> { current };

            if (!cameFrom.ContainsKey(endNode.ToString())) return path;

            while (current != startNode)
            {
                if (!cameFrom.ContainsKey(current.ToString())) continue;

                current = cameFrom[current.ToString()];
                path.Add(current);
            }

            return path;
        }
Exemplo n.º 34
0
        public override void Update(Pose goal)
        {
            bool[,] expanded = new bool[grid.NumColumns, grid.NumRows];
            LinkedList<GridCell>[,] memoized = new LinkedList<GridCell>[grid.NumColumns, grid.NumRows];
            GridCell startCell = grid.PointToCellPosition(goal.Position);
            IntervalHeap<GridCellValue> open = new IntervalHeap<GridCellValue>();

            for (int c = 0; c < grid.NumColumns; c++)
                for (int r = 0; r < grid.NumRows; r++)
                {
                    heuristic[c, r] = float.PositiveInfinity;
                    expanded[c, r] = false;
                }

            heuristic[startCell.C, startCell.R] = 0f;
            open.Add(new GridCellValue(startCell, 0f));

            while (!open.IsEmpty)
            {
                GridCell cell = open.DeleteMin().Position;
                expanded[cell.C, cell.R] = true;

                LinkedList<GridCell> neighbors = memoized[cell.C, cell.R];
                if (neighbors == null)
                {
                    neighbors = grid.Get8Neighbors(cell);
                    memoized[cell.C, cell.R] = neighbors;
                }

                foreach (GridCell n in neighbors)
                {
                    if (expanded[n.C, n.R])
                        continue;

                    if (grid.OccupiedCells[n.C, n.R] > 0)
                        continue;

                    if (grid.GVD.GetObstacleDistance(n) <= Car.HALF_CAR_WIDTH)
                        continue;

                    float dist = cell.C == n.C || cell.R == n.R ? 1f : sqrt2;
                    dist += heuristic[cell.C, cell.R];

                    if (dist < heuristic[n.C, n.R])
                    {
                        heuristic[n.C, n.R] = dist;
                        open.Add(new GridCellValue(n, dist));
                    }
                }
            }
        }
Exemplo n.º 35
0
		///
		public virtual System.Collections.Generic.IList<Tuple<int, float>> Recommend(
			int user_id, int n = -1,
			System.Collections.Generic.ICollection<int> ignore_items = null,
			System.Collections.Generic.ICollection<int> candidate_items = null)
		{
			if (candidate_items == null)
				candidate_items = Enumerable.Range(0, MaxItemID - 1).ToList();
			if (ignore_items == null)
				ignore_items = new int[0];

			System.Collections.Generic.IList<Tuple<int, float>> ordered_items;

			if (n == -1)
			{
				var scored_items = new List<Tuple<int, float>>();
				foreach (int item_id in candidate_items)
					if (!ignore_items.Contains(item_id))
					{
						float score = Predict(user_id, item_id);
						if (score > float.MinValue)
							scored_items.Add(Tuple.Create(item_id, score));
					}
				ordered_items = scored_items.OrderByDescending(x => x.Item2).ToArray();
			}
			else
			{
				var comparer = new DelegateComparer<Tuple<int, float>>( (a, b) => a.Item2.CompareTo(b.Item2) );
				var heap = new IntervalHeap<Tuple<int, float>>(n, comparer);
				float min_relevant_score = float.MinValue;

				foreach (int item_id in candidate_items)
					if (!ignore_items.Contains(item_id))
					{
						float score = Predict(user_id, item_id);
						if (score > min_relevant_score)
						{
							heap.Add(Tuple.Create(item_id, score));
							if (heap.Count > n)
							{
								heap.DeleteMin();
								min_relevant_score = heap.FindMin().Item2;
							}
						}
					}

				ordered_items = new Tuple<int, float>[heap.Count];
				for (int i = 0; i < ordered_items.Count; i++)
					ordered_items[i] = heap.DeleteMax();
			}

			return ordered_items;
		}
        public ArrayList RunTSP(City[] Cities)
        {
            Route = new ArrayList();

            Stopwatch timer = new Stopwatch();
            bAndBTime = new TimeSpan();
            timer.Start();

            Greedy greedyAlgorithm = new Greedy(Cities);
            ArrayList greedyRoute = greedyAlgorithm.RunGreedyTSP();

            double[,] matrix = new double[Cities.Length, Cities.Length];
            //Populate each array item with each respective edge cost
            for (int i = 0; i < Cities.Length; i++)
            {//O(n^2)
                for (int j = 0; j < Cities.Length; j++)
                {
                    if (i == j)
                    {
                        matrix[i, j] = double.PositiveInfinity;
                    }
                    else
                    {
                        matrix[i, j] = Cities[i].costToGetTo(Cities[j]);
                    }
                }
            }
            IntervalHeap<State> queue = new IntervalHeap<State>();

            double bestSolutionSoFar = greedyAlgorithm.BestSolutionSoFar();
            bssfUpdatesAmt = 0;
            prunedAmt = 0;
            State bssfState = null;
            totalStatesCreated = 0;
            //Start with some problem
            State curState = new State(matrix, 0, new Edge(-1, -1));
            totalStatesCreated++;
            //Reduce Matrix
            //O(4n^2)
            curState.Reduce();
            //Let the queue be the set of active subproblems
            //O(log(n))
            queue.Add(curState);
            maxQueueCount = 0;

            bool timesUp = false;
            while (queue.Count > 0)
            {//O(2^n) or O(2^(8n^2 + 9n + 2log(n)))
                if (timer.Elapsed.Seconds >= 30)
                {
                    timesUp = true;
                    break;
                }
                //Choose a subproblem and remove it from the queue
                if (queue.Count > maxQueueCount)
                {
                    maxQueueCount = queue.Count;
                }
                //O(log(n))
                curState = queue.DeleteMin();
                if (curState.Cost() < bestSolutionSoFar)
                {//O(8n^2 + 9n + 2log(n))
                    //For each lowest cost (each 0)
                    double highestScore = double.NegativeInfinity;
                    State[] includeExcludeStates = new State[2];
                    foreach (Edge edge in curState.LowestNums())
                    {//O(8n^2 + 9n)
                        //Include Matrix
                        State includeState = new State(curState, edge); //O(n)
                        totalStatesCreated++;
                        includeState.IncludeMatrix(edge.Row(), edge.Col()); //O(4n^2 + 7n)
                        //Exclude Matrix
                        State excludeState = new State(curState, edge); //O(n)
                        totalStatesCreated++;
                        excludeState.ExcludeMatrix(edge.Row(), edge.Col());//O(4n^2)
                        //Find the score for that edge (Exclude cost - Include cost)
                        double score = excludeState.Cost() - includeState.Cost();
                        if (score > highestScore)
                        {
                            includeExcludeStates[0] = includeState;
                            includeExcludeStates[1] = excludeState;
                            highestScore = score;
                        }
                    }

                    foreach (State subproblemState in includeExcludeStates)
                    {//O(2log(n))
                        //if each P (subproblem) chosen is a complete solution, update the bssf
                        if (subproblemState.CompleteSolution() && subproblemState.Cost() < bestSolutionSoFar)
                        {
                            bestSolutionSoFar = subproblemState.Cost();
                            bssfState = subproblemState;
                            bssfUpdatesAmt++;
                        }
                        //else if lowerBound < bestSolutionSoFar
                        else if (!subproblemState.CompleteSolution() && subproblemState.Cost() < bestSolutionSoFar)
                        {
                            //O(log(n))
                            queue.Add(subproblemState);
                        }
                        else
                        {
                            prunedAmt++;
                        }
                    }
                }
            }

            if (!timesUp) prunedAmt += queue.Count;
            //Call this the best solution so far.  bssf is the route that will be drawn by the Draw method.
            if (bssfState != null)
            {
                int index = bssfState.Exited(0);
                Route.Add(Cities[index]);
                index = bssfState.Exited(bssfState.Exited(0));
                while (index != bssfState.Exited(0))
                {//O(n)
                    Route.Add(Cities[index]);
                    index = bssfState.Exited(index);
                }
            }
            else
            {
                Route = greedyRoute;
            }

            timer.Stop();
            bAndBTime = timer.Elapsed;
            this.count = bssfState.Cost();

            // update the cost of the tour.
            timer.Reset();
            return Route;
        }
Exemplo n.º 37
0
 public void Replace5b()
 {
     for (int size = 0; size < 130; size++)
     {
         IPriorityQueue<double> q = new IntervalHeap<double>();
         IPriorityQueueHandle<double> handle1 = null;
         q.Add(ref handle1, -3.0);
         Assert.AreEqual(-3.0, q.FindMax());
         for (int i = 1; i < size; i++)
             q.Add(-i - 3.0);
         Assert.AreEqual(-3.0, q.FindMax());
         for (int max = -2; max <= 10; max++)
         {
             Assert.AreEqual(max - 1.0, q.Replace(handle1, max));
             Assert.AreEqual(max, q.FindMax());
         }
         Assert.AreEqual(10.0, q.DeleteMax());
         for (int i = 1; i < size; i++)
             Assert.AreEqual(-i - 3.0, q.DeleteMax());
         Assert.IsTrue(q.IsEmpty);
     }
 }
Exemplo n.º 38
0
 public void Replace5a()
 {
     for (int size = 0; size < 130; size++)
     {
         IPriorityQueue<double> q = new IntervalHeap<double>();
         IPriorityQueueHandle<double> handle1 = null;
         q.Add(ref handle1, 3.0);
         Assert.AreEqual(3.0, q.FindMin());
         for (int i = 1; i < size; i++)
             q.Add(i + 3.0);
         Assert.AreEqual(3.0, q.FindMin());
         for (int min = 2; min >= -10; min--)
         {
             Assert.AreEqual(min + 1.0, q.Replace(handle1, min));
             Assert.AreEqual(min, q.FindMin());
         }
         Assert.AreEqual(-10.0, q.DeleteMin());
         for (int i = 1; i < size; i++)
             Assert.AreEqual(i + 3.0, q.DeleteMin());
         Assert.IsTrue(q.IsEmpty);
     }
 }
Exemplo n.º 39
0
 public void Bug20130208Case6b() {
   // Case 6b: both right.first and right.last, not max
   IPriorityQueue<double> q = new IntervalHeap<double>();
   IPriorityQueueHandle<double> topRight = null;
   q.Add(20);
   q.Add(ref topRight, 30);
   q.Add(24);
   q.Add(28);
   q.Add(23);
   q.Add(26);
   q[topRight] = 10;
   Assert.IsTrue(q.Check());
   Assert.IsTrue(q.FindMax() == 28);
 }
Exemplo n.º 40
0
 public void Bug20130208Case3() {
   // Case 3: only left.first
   IPriorityQueue<double> q = new IntervalHeap<double>();
   IPriorityQueueHandle<double> topRight = null;
   q.Add(20);
   q.Add(ref topRight, 30);
   q.Add(25);
   q[topRight] = 10;
   Assert.IsTrue(q.Check());
   Assert.IsTrue(q.FindMax() == 25);
 }
Exemplo n.º 41
0
 public void Bug20130208() {
   IPriorityQueue<double> q = new IntervalHeap<double>();
   IPriorityQueueHandle<double> h0 = null, h2 = null, h4 = null, h7 = null, h5 = null;
   // Add(43, 0);
   q.Add(ref h0, 43);
   // Remove();
   q.DeleteMin();
   // XAddMaxReplace(9, 2);
   q.Add(ref h2, Double.MaxValue);
   q[h2] = 9;
   // XAddMaxReplace(32, 4);
   q.Add(ref h4, Double.MaxValue);
   q[h4] = 32;
   // XAddMaxReplace(44, 7);
   q.Add(ref h7, Double.MaxValue);
   q[h7] = 44;
   // Remove();
   q.DeleteMin();
   // XAddMaxReplace(0, 5);
   q.Add(ref h5, Double.MaxValue);
   q[h5] = 0;
   // Internally inconsistent data structure already now
   Assert.IsTrue(q.Check());
 }
Exemplo n.º 42
0
        public List<Cell> FindPath(Point start, Point end)
        {
            m_open = new IntervalHeap<Cell>(m_capacity, new CellComparer());
            m_closed = new List<Cell>(m_capacity);

            Cell temp;

            // Set parent to a starting point and set its g, h, f values
            Cell parent = this[start.X, start.Y];
            parent.G = 0;
            parent.H = EstimateCost(start, end);
            parent.F = parent.G + parent.H;

            // Add parent to the open list, should be the only cell at this point
            m_open.Add(parent);

            while ( ! m_open.IsEmpty)
            {
                // Find the cell with the lowest f value
                // Pop it off the open and assign the value to parent
                parent = m_open.DeleteMin();

                // If the best cell is the end, we're done
                if (parent.Coord == end)
                {
                    m_closed.Add(parent);
                    return ReconstructReversePath(m_closed);
                }

                // Walk through valid adjacent cells
                foreach (Point p in parent.Adjacent)
                {
                    if (p.X >= 0 && p.Y >= 0 && p.X < m_width && p.Y < m_height)
                    {

                        int g = parent.G + GetCellCost(this[p]);

                        if (g == parent.G)
                            continue;

                        // Check if m_open or m_closed contain a Cell with lower G value
                        if (m_open.Find(n => n.Equals(this[p]), out temp) && temp.G <= g)
                            continue;

                        if (m_closed.Contains(this[p]) && m_closed.Find(n => n.Equals(this[p])).G <= g)
                            continue;

                        this[p].Parent = parent;
                        this[p].G = g;
                        this[p].H = EstimateCost(this[p].Coord, end);
                        this[p].F = this[p].G + this[p].H;

                        m_open.Add(this[p]);

                    }
                }
                m_closed.Add(parent);
            }

            return null;
        }
Exemplo n.º 43
0
        /// <summary>Write item predictions (scores) to a TextWriter object</summary>
        /// <param name="recommender">the <see cref="IRecommender"/> to use for making the predictions</param>
        /// <param name="user_id">ID of the user to make recommendations for</param>
        /// <param name="candidate_items">list of candidate items</param>
        /// <param name="ignore_items">list of items for which no predictions should be made</param>
        /// <param name="num_predictions">the number of items to return per user, -1 if there should be no limit</param>
        /// <param name="writer">the <see cref="TextWriter"/> to write to</param>
        /// <param name="user_mapping">an <see cref="IEntityMapping"/> object for the user IDs</param>
        /// <param name="item_mapping">an <see cref="IEntityMapping"/> object for the item IDs</param>
        public static void WritePredictions(
			this IRecommender recommender,
			int user_id,
			System.Collections.Generic.IList<int> candidate_items,
			System.Collections.Generic.ICollection<int> ignore_items,
			int num_predictions,
			TextWriter writer,
			IEntityMapping user_mapping, IEntityMapping item_mapping)
        {
            System.Collections.Generic.IList<Pair<int, float>> ordered_items;

            if (user_mapping == null)
                user_mapping = new IdentityMapping();
            if (item_mapping == null)
                item_mapping = new IdentityMapping();
            if (num_predictions == -1)
            {
                var scored_items = new List<Pair<int, float>>();
                foreach (int item_id in candidate_items)
                    if (!ignore_items.Contains(item_id))
                    {
                        float score = recommender.Predict(user_id, item_id);
                        if (score > float.MinValue)
                            scored_items.Add(new Pair<int, float>(item_id, score));
                    }
                ordered_items = scored_items.OrderByDescending(x => x.Second).ToArray();
            }
            else {
                var comparer = new DelegateComparer<Pair<int, float>>( (a, b) => a.Second.CompareTo(b.Second) );
                var heap = new IntervalHeap<Pair<int, float>>(num_predictions, comparer);
                float min_relevant_score = float.MinValue;

                foreach (int item_id in candidate_items)
                    if (!ignore_items.Contains(item_id))
                    {
                        float score = recommender.Predict(user_id, item_id);
                        if (score > min_relevant_score)
                        {
                            heap.Add(new Pair<int, float>(item_id, score));
                            if (heap.Count > num_predictions)
                            {
                                heap.DeleteMin();
                                min_relevant_score = heap.FindMin().Second;
                            }
                        }
                    }

                ordered_items = new Pair<int, float>[heap.Count];
                for (int i = 0; i < ordered_items.Count; i++)
                    ordered_items[i] = heap.DeleteMax();
            }

            writer.Write("{0}\t[", user_mapping.ToOriginalID(user_id));
            if (ordered_items.Count > 0)
            {
                writer.Write("{0}:{1}", item_mapping.ToOriginalID(ordered_items[0].First), ordered_items[0].Second.ToString(CultureInfo.InvariantCulture));
                for (int i = 1; i < ordered_items.Count; i++)
                {
                    int item_id = ordered_items[i].First;
                    float score = ordered_items[i].Second;
                    writer.Write(",{0}:{1}", item_mapping.ToOriginalID(item_id), score.ToString(CultureInfo.InvariantCulture));
                }
            }
            writer.WriteLine("]");
        }