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