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; } }