/// <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; } }
/// <summary> /// Initializes a new instance of the <see cref="Enumerator"/> class. /// </summary> /// <param name="parent">The parent.</param> public Enumerator(OneDimensionalSparseArray <T> parent) { _parent = parent; }