Advertisement
Guest User

ASTAR

a guest
Apr 11th, 2017
148
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 24.59 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4. using System.Drawing;
  5. using System.Linq;
  6. using System.Runtime.InteropServices;
  7. using System.Drawing;
  8. using System.Text;
  9.  
  10. namespace A
  11. {
  12.     internal class AStar
  13.     {
  14.         private readonly HashSet<GameBoard> _closed = new HashSet<GameBoard>();
  15.         private readonly HashSet<GameBoard> _open = new HashSet<GameBoard>();
  16.         private GameBoard _startBoard;
  17.         private GameBoard _goal;
  18.         private readonly Dictionary<GameBoard, int> _gScore = new Dictionary<GameBoard, int>();
  19.         private readonly Dictionary<GameBoard, int> _fScore = new Dictionary<GameBoard, int>();
  20.         private readonly Dictionary<GameBoard, KeyValuePair<GameBoard, GameBoard.MoveDirection>> _cameFrom = new Dictionary<GameBoard, KeyValuePair<GameBoard, GameBoard.MoveDirection>>(); // node, parent
  21.         private readonly PriorityQueue<GameBoard, int> _sortedFScore = new PriorityQueue<GameBoard, int>(Comparer<int>.Create((a, b) =>
  22.             a > b ? -1 : a < b ? 1 : 0));
  23.  
  24.         public List<KeyValuePair<GameBoard, GameBoard.MoveDirection>> Search(GameBoard startBoard, GameBoard goal)
  25.         {
  26.             InitSearch(startBoard, goal);
  27.             while (_open.Count > 0)
  28.             {
  29.                 GameBoard current = LowestFScoreInOpen();
  30.                 if (current.Equals(_goal))
  31.                 {
  32.                     return ReconstructPath(current);
  33.                 }
  34.  
  35.                 _open.Remove(current);
  36.                 _closed.Add(current);
  37.  
  38.                 foreach (GameBoard.MoveDirection direction in Enum.GetValues(typeof(GameBoard.MoveDirection)))
  39.                 {
  40.                     GameBoard neighbor = current.MoveAndCopy(direction);
  41.                    
  42.                     if (neighbor == null) continue;  // invalid direction
  43.                     if(_closed.Contains(neighbor)) continue;
  44.  
  45.                     int tentativeScore = _gScore[current] + 1;
  46.                     if (!_open.Contains(neighbor))
  47.                     {
  48.                         _open.Add(neighbor);
  49.                     }
  50.                     else if (tentativeScore >= _gScore[neighbor])
  51.                     {
  52.                         continue; // already in _open and this is not a better path
  53.                     }
  54.  
  55.                     // best path so far
  56.                     _cameFrom[neighbor] = new KeyValuePair<GameBoard, GameBoard.MoveDirection>(current, direction);
  57.                     _gScore[neighbor] = tentativeScore;
  58.                     int fscore = tentativeScore + Heuristic(neighbor);
  59.                     _fScore[neighbor] = fscore;
  60.                     _sortedFScore.Enqueue(new PriorityQueueItem<GameBoard, int>(neighbor, fscore));
  61.                 }
  62.             }
  63.  
  64.             return null; // no path found
  65.         }
  66.  
  67.  
  68.         private int Heuristic(GameBoard gameBoard)
  69.         {
  70.             return Manhaten(gameBoard);
  71.         }
  72.  
  73.         private int Manhaten(GameBoard gameBoard)
  74.         {
  75.             int sum = 0;
  76.             for (int i = 0; i < gameBoard.Board.GetLength(0); i++)
  77.             {
  78.                 for (int j = 0; j < gameBoard.Board.GetLength(1); j++)
  79.                 {
  80.                     if (gameBoard.Board[i, j] == 0) continue;
  81.                     Point locationOfValueInGoal = ValueGoalLocation(gameBoard, gameBoard.Board[i, j]);
  82.                     int distance = Math.Abs(locationOfValueInGoal.X - i) + Math.Abs(locationOfValueInGoal.Y - j);
  83.                     sum += distance;
  84.                 }
  85.             }
  86.  
  87.             return sum;
  88.         }
  89.  
  90.         private Point ValueGoalLocation(GameBoard gameBoard, int pointValue)
  91.         {
  92.             for (int i = 0; i < gameBoard.Board.GetLength(0); i++)
  93.             {
  94.                 for (int j = 0; j < gameBoard.Board.GetLength(1); j++)
  95.                 {
  96.                     if (_goal.Board[i, j] == pointValue)
  97.                     {
  98.                         return new Point(i, j);
  99.                     }
  100.                 }
  101.             }
  102.  
  103.             throw new ArgumentException("Didn't find the value in goal");
  104.         }
  105.  
  106.         private GameBoard LowestFScoreInOpen()
  107.         {
  108.             var min = _open.First();
  109.             PriorityQueueItem<GameBoard, int> minFScore = default(PriorityQueueItem<GameBoard, int>);
  110.             if (_sortedFScore.Count > 0)
  111.             {
  112.                 for (int i = 0; i < _open.Count; i++)
  113.                 {
  114.                     minFScore = _sortedFScore.Peek();
  115.                     if (_open.Contains(minFScore.Value))
  116.                     {
  117.                         break;
  118.                     }
  119.                     _sortedFScore.Dequeue();
  120.                 }
  121.  
  122.                 foreach (var board in _open)
  123.                 {
  124.  
  125.                     if (minFScore.Priority == _fScore[board])
  126.                     {
  127.                         min = board;
  128.                         break;
  129.                     }
  130.                 }
  131.             }
  132.             else
  133.             {
  134.                 foreach (var board in _open)
  135.                 {
  136.  
  137.                     if (_fScore[board] < _fScore[min])
  138.                     {
  139.                         min = board;
  140.                     }
  141.                 }
  142.             }
  143.  
  144.             return min;
  145.         }
  146.  
  147.         public List<KeyValuePair<GameBoard, GameBoard.MoveDirection>> ReconstructPath(GameBoard current)
  148.         {
  149.             List<KeyValuePair<GameBoard, GameBoard.MoveDirection>> movesList = new List<KeyValuePair<GameBoard, GameBoard.MoveDirection>>();
  150.             if (_cameFrom.Count == 0)
  151.             {
  152.                 return movesList;
  153.             }
  154.  
  155.             movesList.Add(_cameFrom[current]);
  156.             while (_cameFrom.ContainsKey(current))
  157.             {
  158.                 current = _cameFrom[current].Key;
  159.  
  160.                 if (_cameFrom.ContainsKey(current))
  161.                 {
  162.                     movesList.Add(_cameFrom[current]);
  163.                 }
  164.             }
  165.             movesList.Reverse(0, movesList.Count);
  166.             return movesList;
  167.         }
  168.  
  169.         private void InitSearch(GameBoard startBoard, GameBoard goal)
  170.         {
  171.             _closed.Clear();
  172.             _open.Clear();
  173.             _gScore.Clear();
  174.             _fScore.Clear();
  175.             this._startBoard = startBoard;
  176.             this._goal = goal;
  177.             _open.Add(_startBoard);
  178.             _gScore[_startBoard] = 0;
  179.             _fScore[_startBoard] = Heuristic(_startBoard);
  180.         }
  181.  
  182.         public static void Main(string[] args)
  183.         {
  184.             GameBoard boardA = new GameBoard(new int[,]
  185.             {
  186.                 {4, 7, 8},
  187.                 {6, 3, 2},
  188.                 {0, 5, 1},
  189.             });
  190.  
  191.             GameBoard boardB = new GameBoard(new int[,]
  192.             {
  193.                 {1, 4, 7},
  194.                 {2, 5, 8},
  195.                 {3, 6, 0},
  196.             });
  197.  
  198.             GameBoard boardC = new GameBoard(new int[,]
  199.             {
  200.                 {8, 3, 5},
  201.                 {1, 0, 2},
  202.                 {6, 7, 4},
  203.             });
  204.  
  205.             GameBoard goal = new GameBoard(new int[,]
  206.             {
  207.                 {1, 2, 3},
  208.                 {8, 0, 4},
  209.                 {7, 6, 5},
  210.             });
  211.  
  212.             AStar aStar = new AStar();
  213.             //Console.WriteLine("A");
  214.             //SearchAndPrint(boardA, goal, aStar);
  215.             //Console.WriteLine("B");
  216.             //SearchAndPrint(boardB, goal, aStar);
  217.             Console.WriteLine("C");
  218.             SearchAndPrint(boardC, goal, aStar);
  219.             Console.ReadKey();
  220.         }
  221.  
  222.         private static void SearchAndPrint(GameBoard board, GameBoard goal, AStar aStar)
  223.         {
  224.             var sol = aStar.Search(board, goal);
  225.  
  226.             foreach (var boardDirectionPair in sol)
  227.             {
  228.                 //boardDirectionPair.Key.PrintBoard();
  229.                 Console.WriteLine(GameBoard.EnumName(boardDirectionPair.Value));
  230.                 //Console.WriteLine();
  231.             }
  232.         }
  233.     }
  234.    
  235.    
  236.    
  237.    
  238.     //////////////////GameBoard.cs
  239.    
  240.       internal class GameBoard : IEqualityComparer<GameBoard>, IEquatable<GameBoard>
  241.     {
  242.         public enum MoveDirection
  243.         {
  244.             Up,
  245.             Down,
  246.             Left,
  247.             Right,
  248.         }
  249.  
  250.         private static readonly Dictionary<MoveDirection, string> DirectionsStrings = new Dictionary<MoveDirection, string>
  251.         {
  252.             {MoveDirection.Up, "^"},
  253.             {MoveDirection.Down, "v"},
  254.             {MoveDirection.Left, "<"},
  255.             {MoveDirection.Right, ">"}
  256.         };
  257.  
  258.         public static string EnumName(MoveDirection direction)
  259.         {
  260.             return DirectionsStrings[direction];
  261.         }
  262.  
  263.         public int[,] Board { get; }
  264.         private string _flatten;
  265.  
  266.         public GameBoard(int[,] board)
  267.         {
  268.             this.Board = board.Clone() as int[,];
  269.             _flatten = FlattenToString(this);
  270.         }
  271.  
  272.         public void PrintBoard()
  273.         {
  274.             for (int i = 0; i < Board.GetLength(0); i++)
  275.             {
  276.                 Console.Write(" ");
  277.                 for (int j = 0; j < Board.GetLength(1); j++)
  278.                 {
  279.                     Console.Write(Board[i,j]);
  280.                     Console.Write(" ");
  281.                 }
  282.                 Console.WriteLine();
  283.             }
  284.  
  285.             //Console.SetCursorPosition(0, 0);
  286.         }
  287.  
  288.         public GameBoard MoveAndCopy(MoveDirection direction)
  289.         {
  290.             GameBoard newGameBoard = new GameBoard(this.Board);
  291.             bool movePossible = newGameBoard.Move(direction);
  292.             newGameBoard._flatten = FlattenToString(newGameBoard);
  293.             return movePossible ? newGameBoard : null;
  294.         }
  295.  
  296.         private bool Move(MoveDirection direction)
  297.         {
  298.             Point  emptySpot = FindEmptySpot();
  299.             int tmp;
  300.  
  301.             switch (direction)
  302.             {
  303.                 case MoveDirection.Up:      // we swap with the one below the empty
  304.                     if (Board.GetLength(0) <= emptySpot.X + 1)
  305.                     {
  306.                         return false; // move not possible
  307.                     }
  308.  
  309.                     tmp = Board[emptySpot.X + 1, emptySpot.Y];
  310.                     Board[emptySpot.X + 1, emptySpot.Y] = 0;
  311.                     Board[emptySpot.X, emptySpot.Y] = tmp;
  312.                     break;
  313.                 case MoveDirection.Down:    // we swap with the one above the empty
  314.                     if (0 > emptySpot.X - 1)
  315.                     {
  316.                         return false; // move not possible
  317.                     }
  318.  
  319.                     tmp = Board[emptySpot.X - 1, emptySpot.Y];
  320.                     Board[emptySpot.X - 1, emptySpot.Y] = 0;
  321.                     Board[emptySpot.X, emptySpot.Y] = tmp;
  322.                     break;
  323.                 case MoveDirection.Right:
  324.                     if (0 > emptySpot.Y - 1)
  325.                     {
  326.                         return false; // move not possible
  327.                     }
  328.  
  329.                     tmp = Board[emptySpot.X, emptySpot.Y - 1];
  330.                     Board[emptySpot.X, emptySpot.Y - 1] = 0;
  331.                     Board[emptySpot.X, emptySpot.Y] = tmp;
  332.                     break;
  333.                 case MoveDirection.Left:
  334.                     if (Board.GetLength(1) <= emptySpot.Y + 1)
  335.                     {
  336.                         return false; // move not possible
  337.                     }
  338.  
  339.                     tmp = Board[emptySpot.X, emptySpot.Y + 1];
  340.                     Board[emptySpot.X, emptySpot.Y + 1] = 0;
  341.                     Board[emptySpot.X, emptySpot.Y] = tmp;
  342.                     break;
  343.                 default:
  344.                     throw new ArgumentOutOfRangeException(nameof(direction), direction, null);
  345.             }
  346.  
  347.             return true;
  348.         }
  349.  
  350.         private Point FindEmptySpot()
  351.         {
  352.             for (int i = 0; i < this.Board.GetLength(0); i++)
  353.             {
  354.                 for (int j = 0; j < Board.GetLength(1); j++)
  355.                 {
  356.                     if (Board[i, j] == 0)
  357.                     {
  358.                         return new Point(i, j);
  359.                     }
  360.                 }
  361.             }
  362.  
  363.             throw new Exception("didn't find zero");
  364.         }
  365.  
  366.         public bool Equals(GameBoard x, GameBoard y)
  367.         {
  368.             return Equals(x.Board, y.Board);
  369.         }
  370.  
  371.         public bool Equals(int[,] x, int[,] y)
  372.         {
  373.             for (int i = 0; i < x.GetLength(0); i++)
  374.             {
  375.                 for (int j = 0; j < x.GetLength(1); j++)
  376.                 {
  377.                     if (x[i, j] != y[i, j])
  378.                     {
  379.                         return false;
  380.                     }
  381.                 }
  382.             }
  383.  
  384.             return true;
  385.         }
  386.  
  387.         public int GetHashCode(GameBoard obj)
  388.         {
  389.             return obj._flatten.GetHashCode();
  390.         }
  391.  
  392.         private static string FlattenToString(GameBoard obj)
  393.         {
  394.             StringBuilder str = new StringBuilder(obj.Board.Length);
  395.             for (int i = 0; i < obj.Board.GetLength(0); i++)
  396.             {
  397.                 for (int j = 0; j < obj.Board.GetLength(1); j++)
  398.                 {
  399.                     str.Append(obj.Board[i, j]);
  400.                 }
  401.             }
  402.             return str.ToString();
  403.         }
  404.  
  405.         public override int GetHashCode()
  406.         {
  407.             return Board.GetHashCode();
  408.         }
  409.  
  410.         public bool Equals(GameBoard other)
  411.         {
  412.             if (ReferenceEquals(null, other)) return false;
  413.             if (ReferenceEquals(this, other)) return true;
  414.             return Equals(Board, other.Board);
  415.         }
  416.  
  417.         public override bool Equals(object obj)
  418.         {
  419.             if (ReferenceEquals(null, obj)) return false;
  420.             if (ReferenceEquals(this, obj)) return true;
  421.             if (obj.GetType() != this.GetType()) return false;
  422.             return Equals((GameBoard) obj);
  423.         }
  424.     }
  425.    
  426.    
  427.    
  428. // PriorityQueue.cs
  429. //
  430. // Jim Mischel
  431.    
  432.      [Serializable]
  433.     [ComVisible(false)]
  434.     public struct PriorityQueueItem<TValue, TPriority>
  435.     {
  436.         private TValue _value;
  437.         public TValue Value
  438.         {
  439.             get { return _value; }
  440.         }
  441.  
  442.         private TPriority _priority;
  443.         public TPriority Priority
  444.         {
  445.             get { return _priority; }
  446.         }
  447.  
  448.         internal PriorityQueueItem(TValue val, TPriority pri)
  449.         {
  450.             this._value = val;
  451.             this._priority = pri;
  452.         }
  453.     }
  454.  
  455.     [Serializable]
  456.     [ComVisible(false)]
  457.     public class PriorityQueue<TValue, TPriority> : ICollection,
  458.         IEnumerable<PriorityQueueItem<TValue, TPriority>>
  459.     {
  460.         private PriorityQueueItem<TValue, TPriority>[] items;
  461.  
  462.         private const Int32 DefaultCapacity = 16;
  463.         private Int32 capacity;
  464.         private Int32 numItems;
  465.  
  466.         private Comparison<TPriority> compareFunc;
  467.  
  468.         /// <summary>
  469.         /// Initializes a new instance of the PriorityQueue class that is empty,
  470.         /// has the default initial capacity, and uses the default IComparer.
  471.         /// </summary>
  472.         public PriorityQueue()
  473.             : this(DefaultCapacity, Comparer<TPriority>.Default)
  474.         {
  475.         }
  476.  
  477.         public PriorityQueue(Int32 initialCapacity)
  478.             : this(initialCapacity, Comparer<TPriority>.Default)
  479.         {
  480.         }
  481.  
  482.         public PriorityQueue(IComparer<TPriority> comparer)
  483.             : this(DefaultCapacity, comparer)
  484.         {
  485.         }
  486.  
  487.         public PriorityQueue(int initialCapacity, IComparer<TPriority> comparer)
  488.         {
  489.             Init(initialCapacity, new Comparison<TPriority>(comparer.Compare));
  490.         }
  491.  
  492.         public PriorityQueue(Comparison<TPriority> comparison)
  493.             : this(DefaultCapacity, comparison)
  494.         {
  495.         }
  496.  
  497.         public PriorityQueue(int initialCapacity, Comparison<TPriority> comparison)
  498.         {
  499.             Init(initialCapacity, comparison);
  500.         }
  501.  
  502.         private void Init(int initialCapacity, Comparison<TPriority> comparison)
  503.         {
  504.             numItems = 0;
  505.             compareFunc = comparison;
  506.             SetCapacity(initialCapacity);
  507.         }
  508.  
  509.         public int Count
  510.         {
  511.             get { return numItems; }
  512.         }
  513.  
  514.         public int Capacity
  515.         {
  516.             get { return items.Length; }
  517.             set { SetCapacity(value); }
  518.         }
  519.  
  520.         private void SetCapacity(int newCapacity)
  521.         {
  522.             int newCap = newCapacity;
  523.             if (newCap < DefaultCapacity)
  524.                 newCap = DefaultCapacity;
  525.  
  526.             // throw exception if newCapacity < NumItems
  527.             if (newCap < numItems)
  528.                 throw new ArgumentOutOfRangeException("newCapacity", "New capacity is less than Count");
  529.  
  530.             this.capacity = newCap;
  531.             if (items == null)
  532.             {
  533.                 items = new PriorityQueueItem<TValue, TPriority>[newCap];
  534.                 return;
  535.             }
  536.  
  537.             // Resize the array.
  538.             Array.Resize<PriorityQueueItem<TValue, TPriority>>(ref items, newCap);
  539.         }
  540.  
  541.         public void Enqueue(PriorityQueueItem<TValue, TPriority> newItem)
  542.         {
  543.             if (numItems == capacity)
  544.             {
  545.                 // need to increase capacity
  546.                 // grow by 50 percent
  547.                 SetCapacity((3 * Capacity) / 2);
  548.             }
  549.  
  550.             int i = numItems;
  551.             ++numItems;
  552.             while ((i > 0) && (compareFunc(items[(i - 1) / 2].Priority, newItem.Priority) < 0))
  553.             {
  554.                 items[i] = items[(i - 1) / 2];
  555.                 i = (i - 1) / 2;
  556.             }
  557.             items[i] = newItem;
  558.             //if (!VerifyQueue())
  559.             //{
  560.             //    Console.WriteLine("ERROR: Queue out of order!");
  561.             //}
  562.         }
  563.  
  564.         public void Enqueue(TValue value, TPriority priority)
  565.         {
  566.             Enqueue(new PriorityQueueItem<TValue, TPriority>(value, priority));
  567.         }
  568.  
  569.         private PriorityQueueItem<TValue, TPriority> RemoveAt(Int32 index)
  570.         {
  571.             PriorityQueueItem<TValue, TPriority> o = items[index];
  572.             --numItems;
  573.             // move the last item to fill the hole
  574.             PriorityQueueItem<TValue, TPriority> tmp = items[numItems];
  575.             // If you forget to clear this, you have a potential memory leak.
  576.             items[numItems] = default(PriorityQueueItem<TValue, TPriority>);
  577.             if (numItems > 0 && index != numItems)
  578.             {
  579.                 // If the new item is greater than its parent, bubble up.
  580.                 int i = index;
  581.                 int parent = (i - 1) / 2;
  582.                 while (compareFunc(tmp.Priority, items[parent].Priority) > 0)
  583.                 {
  584.                     items[i] = items[parent];
  585.                     i = parent;
  586.                     parent = (i - 1) / 2;
  587.                 }
  588.  
  589.                 // if i == index, then we didn't move the item up
  590.                 if (i == index)
  591.                 {
  592.                     // bubble down ...
  593.                     while (i < (numItems) / 2)
  594.                     {
  595.                         int j = (2 * i) + 1;
  596.                         if ((j < numItems - 1) && (compareFunc(items[j].Priority, items[j + 1].Priority) < 0))
  597.                         {
  598.                             ++j;
  599.                         }
  600.                         if (compareFunc(items[j].Priority, tmp.Priority) <= 0)
  601.                         {
  602.                             break;
  603.                         }
  604.                         items[i] = items[j];
  605.                         i = j;
  606.                     }
  607.                 }
  608.                 // Be sure to store the item in its place.
  609.                 items[i] = tmp;
  610.             }
  611.             //if (!VerifyQueue())
  612.             //{
  613.             //    Console.WriteLine("ERROR: Queue out of order!");
  614.             //}
  615.             return o;
  616.         }
  617.  
  618.         // Function to check that the queue is coherent.
  619.         public bool VerifyQueue()
  620.         {
  621.             int i = 0;
  622.             while (i < numItems / 2)
  623.             {
  624.                 int leftChild = (2 * i) + 1;
  625.                 int rightChild = leftChild + 1;
  626.                 if (compareFunc(items[i].Priority, items[leftChild].Priority) < 0)
  627.                 {
  628.                     return false;
  629.                 }
  630.                 if (rightChild < numItems && compareFunc(items[i].Priority, items[rightChild].Priority) < 0)
  631.                 {
  632.                     return false;
  633.                 }
  634.                 ++i;
  635.             }
  636.             return true;
  637.         }
  638.  
  639.         public PriorityQueueItem<TValue, TPriority> Dequeue()
  640.         {
  641.             if (Count == 0)
  642.                 throw new InvalidOperationException("The queue is empty");
  643.             return RemoveAt(0);
  644.         }
  645.  
  646.         /// <summary>
  647.         /// Removes the item with the specified value from the queue.
  648.         /// The passed equality comparison is used.
  649.         /// </summary>
  650.         /// <param name="item">The item to be removed.</param>
  651.         /// <param name="comp">An object that implements the IEqualityComparer interface
  652.         /// for the type of item in the collection.</param>
  653.         public void Remove(TValue item, IEqualityComparer comparer)
  654.         {
  655.             // need to find the PriorityQueueItem that has the Data value of o
  656.             for (int index = 0; index < numItems; ++index)
  657.             {
  658.                 if (comparer.Equals(item, items[index].Value))
  659.                 {
  660.                     RemoveAt(index);
  661.                     return;
  662.                 }
  663.             }
  664.             throw new ApplicationException("The specified itemm is not in the queue.");
  665.         }
  666.  
  667.         /// <summary>
  668.         /// Removes the item with the specified value from the queue.
  669.         /// The default type comparison function is used.
  670.         /// </summary>
  671.         /// <param name="item">The item to be removed.</param>
  672.         public void Remove(TValue item)
  673.         {
  674.             Remove(item, EqualityComparer<TValue>.Default);
  675.         }
  676.  
  677.         public PriorityQueueItem<TValue, TPriority> Peek()
  678.         {
  679.             if (Count == 0)
  680.                 throw new InvalidOperationException("The queue is empty");
  681.             return items[0];
  682.         }
  683.  
  684.         // Clear
  685.         public void Clear()
  686.         {
  687.             for (int i = 0; i < numItems; ++i)
  688.             {
  689.                 items[i] = default(PriorityQueueItem<TValue, TPriority>);
  690.             }
  691.             numItems = 0;
  692.             TrimExcess();
  693.         }
  694.  
  695.         /// <summary>
  696.         /// Set the capacity to the actual number of items, if the current
  697.         /// number of items is less than 90 percent of the current capacity.
  698.         /// </summary>
  699.         public void TrimExcess()
  700.         {
  701.             if (numItems < (float)0.9 * capacity)
  702.             {
  703.                 SetCapacity(numItems);
  704.             }
  705.         }
  706.  
  707.         // Contains
  708.         public  bool Contains(TValue o)
  709.         {
  710.             foreach (PriorityQueueItem<TValue, TPriority> x in items)
  711.             {
  712.                 if (x.Value.Equals(o))
  713.                     return true;
  714.             }
  715.             return false;
  716.         }
  717.  
  718.         public void CopyTo(PriorityQueueItem<TValue, TPriority>[] array, int arrayIndex)
  719.         {
  720.             if (array == null)
  721.                 throw new ArgumentNullException("array");
  722.             if (arrayIndex < 0)
  723.                 throw new ArgumentOutOfRangeException("arrayIndex", "arrayIndex is less than 0.");
  724.             if (array.Rank > 1)
  725.                 throw new ArgumentException("array is multidimensional.");
  726.             if (numItems == 0)
  727.                 return;
  728.             if (arrayIndex >= array.Length)
  729.                 throw new ArgumentException("arrayIndex is equal to or greater than the length of the array.");
  730.             if (numItems > (array.Length - arrayIndex))
  731.                 throw new ArgumentException("The number of elements in the source ICollection is greater than the available space from arrayIndex to the end of the destination array.");
  732.  
  733.             for (int i = 0; i < numItems; i++)
  734.             {
  735.                 array[arrayIndex + i] = items[i];
  736.             }
  737.         }
  738.  
  739.         #region ICollection Members
  740.  
  741.         public void CopyTo(Array array, int index)
  742.         {
  743.             this.CopyTo((PriorityQueueItem<TValue, TPriority>[])array, index);
  744.         }
  745.  
  746.         public bool IsSynchronized
  747.         {
  748.             get { return false; }
  749.         }
  750.  
  751.         public object SyncRoot
  752.         {
  753.             get { return items.SyncRoot; }
  754.         }
  755.  
  756.         #endregion
  757.  
  758.         #region IEnumerable<PriorityQueueItem<TValue,TPriority>> Members
  759.  
  760.         public IEnumerator<PriorityQueueItem<TValue, TPriority>> GetEnumerator()
  761.         {
  762.             for (int i = 0; i < numItems; i++)
  763.             {
  764.                 yield return items[i];
  765.             }
  766.         }
  767.  
  768.         #endregion
  769.  
  770.         #region IEnumerable Members
  771.  
  772.         IEnumerator IEnumerable.GetEnumerator()
  773.         {
  774.             return GetEnumerator();
  775.         }
  776.  
  777.         #endregion
  778.     }
  779.    
  780. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement