示例#1
0
        public T this[long rowIndex, long colIndex]
        {
            get
            {
                TwoDimensionalSparseMatrix <T> selectedMatrix = GetMatrixForQuadrantAtCoordinate(rowIndex, colIndex);
                if (selectedMatrix == null)
                {
                    return(default(T));
                }

                return(selectedMatrix[rowIndex, colIndex]);
            }
            set
            {
                TwoDimensionalSparseMatrix <T> selectedMatrix = GetMatrixForQuadrantAtCoordinate(rowIndex, colIndex);
                if (selectedMatrix == null)
                {
                    Tuple <int, int> quadrant = GetQuadrant(rowIndex, colIndex);
                    selectedMatrix = new TwoDimensionalSparseMatrix <T>();
                    _matrixQuadrants.Add(quadrant, selectedMatrix);
                }

                selectedMatrix[rowIndex, colIndex] = value;
            }
        }
        /// <summary>
        /// Packages the specified item list.
        /// </summary>
        /// <param name="itemList">The item list.</param>
        /// <param name="keepMatrix">The keep matrix.</param>
        /// <param name="maxWeight">The maximum weight.</param>
        /// <returns>The items packed up into a knapsack</returns>
        private static IEnumerable <IItem> Package(
            IList <IItem> itemList,
            TwoDimensionalSparseMatrix <bool> keepMatrix,
            long maxWeight)
        {
            int  itemCount            = itemList.Count;
            var  knapsackItems        = Enumerable.Empty <IItem>();
            long currentWeightToCheck = maxWeight;

            while (true)
            {
                bool foundItem = false;
                for (int itemIndex = 0; itemIndex < itemList.Count; itemIndex++)
                {
                    if (keepMatrix[itemIndex, currentWeightToCheck])
                    {
                        IItem itemToTake = itemList[itemIndex];
                        knapsackItems         = knapsackItems.Append(itemToTake);
                        currentWeightToCheck -= itemToTake.Weight;
                        foundItem             = true;
                        break;
                    }
                }

                if (foundItem == false)
                {
                    break;
                }
            }

            return(knapsackItems);
        }
        /// <summary>
        /// Solves the Knapsack problem
        /// </summary>
        /// <param name="items">The items to put into the knapsack</param>
        /// <param name="maxWeight">The maximum weight the knapsack can hold</param>
        /// <returns>
        /// The items to put into the knapsack
        /// </returns>
        public IEnumerable <IItem> Solve(IEnumerable <IItem> items, long maxWeight)
        {
            IList <IItem> itemList = items.ToList();

            var smallerSolutionList  = new OneDimensionalSparseArray <long>();
            var intermediateSolution = new OneDimensionalSparseArray <long>();
            var memoList             = new OneDimensionalSparseArray <long>();
            var keepMatrix           = new TwoDimensionalSparseMatrix <bool>();

            SolveUnboundedKnapsack(maxWeight, itemList, ref smallerSolutionList, ref intermediateSolution, ref memoList, ref keepMatrix);

            return(Package(itemList, keepMatrix, maxWeight));
        }
        /// <summary>
        /// Solves the unbounded knapsack.
        /// </summary>
        /// <param name="maxWeight">The maximum weight.</param>
        /// <param name="itemList">The item list.</param>
        /// <param name="smallerSolutionList">The smaller solution list.</param>
        /// <param name="intermediateSolutionList">The intermediate solution list.</param>
        /// <param name="memoList">The memo list.</param>
        /// <param name="keepMatrix">The keep matrix.</param>
        private static void SolveUnboundedKnapsack(
            long maxWeight,
            IList <IItem> itemList,
            ref OneDimensionalSparseArray <long> smallerSolutionList,
            ref OneDimensionalSparseArray <long> intermediateSolutionList,
            ref OneDimensionalSparseArray <long> memoList,
            ref TwoDimensionalSparseMatrix <bool> keepMatrix)
        {
            for (long weight = 1; weight <= maxWeight; weight++)
            {
                for (int itemIndex = 0; itemIndex < itemList.Count; itemIndex++)
                {
                    IItem currentItem = itemList[itemIndex];
                    if (weight >= currentItem.Weight)
                    {
                        smallerSolutionList[itemIndex] = memoList[weight - currentItem.Weight];
                    }
                    else
                    {
                        smallerSolutionList[itemIndex] = 0;
                    }
                }

                for (int itemIndex = 0; itemIndex < itemList.Count; itemIndex++)
                {
                    IItem currentItem = itemList[itemIndex];
                    if (weight >= currentItem.Weight)
                    {
                        intermediateSolutionList[itemIndex] = smallerSolutionList[itemIndex] + currentItem.Value;
                    }
                    else
                    {
                        intermediateSolutionList[itemIndex] = 0;
                    }
                }

                long fileIndexOfMaxValue = 0;
                memoList[weight] = intermediateSolutionList[0];

                for (int itemIndex = 1; itemIndex < itemList.Count; itemIndex++)
                {
                    if (intermediateSolutionList[itemIndex] > memoList[weight])
                    {
                        memoList[weight]    = intermediateSolutionList[itemIndex];
                        fileIndexOfMaxValue = itemIndex;
                    }
                }

                keepMatrix[fileIndexOfMaxValue, weight] = true;
            }
        }