コード例 #1
0
        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());
        }
コード例 #2
0
        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]);
        }
コード例 #3
0
        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]);
                        }
                    }
                }
            }
        }
コード例 #4
0
        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);
        }