private void WriteSolutionAndData(MinWeightItemGroup requiredValueGroup) { LogFile.WriteLine("Maximum value after choosing {0} of first {1} items at weight {2} is {3}", _knapsack.AllowedItems, _items.Count, _knapsack.Capacity, requiredValueGroup.TotalValue() ); LogFile.WriteLine("No of items: {0}", requiredValueGroup.ItemCount()); LogFile.WriteLine("Item names: {0}", requiredValueGroup.ItemNames()); LogFile.WriteLine("Total weight: {0}", requiredValueGroup.TotalWeight()); LogFile.WriteLine("Total value: {0}", requiredValueGroup.TotalValue()); Console.WriteLine("Maximum value after choosing {0} of first {1} items at weight {2} is {3}", _knapsack.AllowedItems, _items.Count, _knapsack.Capacity, requiredValueGroup.TotalValue() ); Console.WriteLine("No of items: {0}", requiredValueGroup.ItemCount()); Console.WriteLine("Item names: {0}", requiredValueGroup.ItemNames()); Console.WriteLine("Total weight: {0}", requiredValueGroup.TotalWeight()); Console.WriteLine("Total value: {0}", requiredValueGroup.TotalValue()); DumpArrayToLog(m => m.TotalWeight()); //DumpArrayToLog(m => m.ItemCount()); }
public MinWeightItemGroup GetMinWeightValue(int forFirstN, int atProfit) { // value at 0 items and 0 profit is empty collection, initial weight 0, // else at 0 items and profit above zero, initialise to > max weight if (forFirstN == 0) { return(atProfit <= 0 ? new MinWeightItemGroup(0) : new MinWeightItemGroup(_knapsack.Capacity + 1)); } // calculate the previous value if (_minWeightItemGroup[forFirstN - 1, atProfit] is null) { _minWeightItemGroup[forFirstN - 1, atProfit] = GetMinWeightValue(forFirstN - 1, atProfit); } // if current item profit is greater than profit being calculated, use previous value if (_items[forFirstN - 1].Value > atProfit) { _minWeightItemGroup[forFirstN, atProfit] = new MinWeightItemGroup(_minWeightItemGroup[forFirstN - 1, atProfit]); } else { var itemGroupExcludingCurrent = _minWeightItemGroup[forFirstN - 1, atProfit - _items[forFirstN - 1].Value]; // if we haven't calculated max without current item, do it now if (itemGroupExcludingCurrent is null) { itemGroupExcludingCurrent = GetMinWeightValue(forFirstN - 1, atProfit - _items[forFirstN - 1].Value); _minWeightItemGroup[forFirstN - 1, atProfit - _items[forFirstN - 1].Value] = itemGroupExcludingCurrent; } int weightAtProfitExcludingCurrentItem = itemGroupExcludingCurrent.TotalWeight(); int weightOfCurrentItem = _items[forFirstN - 1].Weight; int weightOnPreviousIteration = _minWeightItemGroup[forFirstN - 1, atProfit].TotalWeight(); if (weightAtProfitExcludingCurrentItem + weightOfCurrentItem < weightOnPreviousIteration) { _minWeightItemGroup[forFirstN, atProfit] = (MinWeightItemGroup) new MinWeightItemGroup(itemGroupExcludingCurrent).Add(_items[forFirstN - 1]); } else { _minWeightItemGroup[forFirstN, atProfit] = new MinWeightItemGroup(_minWeightItemGroup[forFirstN - 1, atProfit]); } } return(_minWeightItemGroup[forFirstN, atProfit]); }
public void CalculateNonRecursive() { // Initialise values after 0 items to weight of 0 _minWeightItemGroup[0, 0] = new MinWeightItemGroup(0); for (int p = 1; p <= _minWeightItemGroup.GetUpperBound(1); p++) { // initialise item collection with weight value above capacity _minWeightItemGroup[0, p] = new MinWeightItemGroup(_knapsack.Capacity + 1); } // for each number of items from 1 to numberOfItems for (int i = 1; i <= _minWeightItemGroup.GetUpperBound(0); i++) { // for each profit value from max down to profit of current item for (int profit = _minWeightItemGroup.GetUpperBound(1); profit >= 0; profit--) { // Calculate m[i,j] which is the minimum weight that can be obtained at profit j after looking at first i elements in list // if profit we are calculating at is less than profit of this item, use previous value if (_items[i - 1].Value > profit) { _minWeightItemGroup[i, profit] = new MinWeightItemGroup(_minWeightItemGroup[i - 1, profit]); } else { var itemGroupExcludingCurrent = _minWeightItemGroup[i - 1, profit - _items[i - 1].Value]; int weightAtProfitExcludingCurrentItem = itemGroupExcludingCurrent.TotalWeight(); int weightOfCurrentItem = _items[i - 1].Weight; int weightOnPreviousIteration = _minWeightItemGroup[i - 1, profit].TotalWeight(); // if (weight at profit excluding this item) + weight of this item is less than previous min weight, then include this item if (weightAtProfitExcludingCurrentItem + weightOfCurrentItem < weightOnPreviousIteration) { // maximum value is maximum before we added this item to the list _minWeightItemGroup[i, profit] = (MinWeightItemGroup) new MinWeightItemGroup(itemGroupExcludingCurrent).Add(_items[i - 1]); } else { _minWeightItemGroup[i, profit] = new MinWeightItemGroup(_minWeightItemGroup[i - 1, profit]); } } } } }
public void CalculateRecursive() { // set current profit to highest value var currentProfit = _minWeightItemGroup.GetUpperBound(1); // calculate at this profit value MinWeightItemGroup optimalValueGroup = GetMinWeightValue(_items.Count, currentProfit); // if no solution at this profit value, find next lowest while (optimalValueGroup.TotalWeight() > _knapsack.Capacity) { Console.WriteLine("No solution at profit {0}, calculating at {1}", currentProfit, --currentProfit); optimalValueGroup = GetMinWeightValue(_items.Count, currentProfit); } WriteSolutionAndData(optimalValueGroup); }