Ejemplo n.º 1
0
        KnapsackResult GreedyResult(KnapsackInstance instance, IOrderedEnumerable <KnapsackItem> sortedItems)
        {
            var addedItemsVector = new bool[instance.ItemCount];
            var currentWeight    = 0;
            var currentPrice     = 0;

            foreach (var item in sortedItems)
            {
                if (currentWeight + item.Weight > instance.KnapsackSize)
                {
                    break;
                }
                currentPrice             += item.Price;
                currentWeight            += item.Weight;
                addedItemsVector[item.Id] = true;
            }

            return(new KnapsackResult
            {
                KnapsackInstance = instance,
                Configuration = new KnapsackConfiguration
                {
                    ItemVector = addedItemsVector.ToList(),
                    Price = currentPrice,
                    Weight = currentWeight
                }
            });
        }
Ejemplo n.º 2
0
        public override ConstructiveResult Solve(KnapsackInstance instance)
        {
            if (instance.ItemCount == 0)
            {
                return new ConstructiveResult
                       {
                           KnapsackInstance = instance,
                           Configuration    = new KnapsackConfiguration {
                               ItemVector = new List <bool>(), Price = 0, Weight = 0
                           }
                       }
            }
            ;
            FillTable(instance);
            int bestPrice;
            var bestCell   = FindBestCell(instance, out bestPrice);
            var itemVector = GetItemVector(bestCell);

            var knapsackConfiguration = new KnapsackConfiguration
            {
                ItemVector = itemVector,
                Price      = bestPrice
            };

            return(new ConstructiveResult
            {
                KnapsackInstance = instance,
                Configuration = knapsackConfiguration
            });
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Because some items might be removed from the knapsack before reaching the DP algorithm
        /// (due to being single-handedly too big for the knapsack), the item vector needs to be expanded
        /// to include these removed items (they will always be a 0 in the vector)
        /// </summary>
        /// <param name="result"></param>
        /// <param name="originalInstance"></param>
        /// <returns></returns>
        List <bool> ConvertItemVector(IList <bool> itemVector, KnapsackInstance originalInstance)
        {
            //No items were removed
            if (itemVector.Count == originalInstance.ItemCount)
            {
                return(itemVector.ToList());
            }

            var updatedSolutionVector = new List <bool>();
            var solutionVectorIndex   = 0;

            //Go through every item in the original instance
            foreach (var item in originalInstance.Items)
            {
                //This item was removed, add it into the item vector
                if (item.Weight > originalInstance.KnapsackSize)
                {
                    updatedSolutionVector.Add(false);
                }
                //This item was not removed, just copy the result
                else
                {
                    updatedSolutionVector.Add(itemVector[solutionVectorIndex]);
                    solutionVectorIndex++;
                }
            }
            return(updatedSolutionVector);
        }
Ejemplo n.º 4
0
        private KnapsackConfiguration GetOptimalConfiguration(KnapsackInstance instance)
        {
            var branchAndBoundSolver = new BranchBoundSolver();
            var optimalSolution      = branchAndBoundSolver.Solve(instance);

            return(optimalSolution.Configuration);
        }
Ejemplo n.º 5
0
        public override ConstructiveResult Solve(KnapsackInstance instance)
        {
            //Make a shallow copy of instances list in order to not affect next possible execution
            var sorted = new List <KnapsackItem>(instance.Items);

            sorted.OrderByDescending(i => i.Price / i.Weight);
            var addedItemsVector = new bool[instance.ItemCount];

            var currentWeight = 0;
            var currentPrice  = 0;

            foreach (var item in sorted)
            {
                if (currentWeight + item.Weight > instance.KnapsackSize)
                {
                    break;
                }
                currentPrice             += item.Price;
                currentWeight            += item.Weight;
                addedItemsVector[item.Id] = true;
            }

            return(new ConstructiveResult
            {
                KnapsackInstance = instance,
                Configuration = new KnapsackConfiguration
                {
                    ItemVector = addedItemsVector.ToList(),
                    Price = currentPrice,
                    Weight = currentWeight
                }
            });
        }
Ejemplo n.º 6
0
        public KnapsackResult Solve(KnapsackInstance instance)
        {
            var sorted       = instance.Items.OrderByDescending(i => i.Price / i.Weight);
            var greedyResult = GreedyResult(instance, sorted);

            var biggestLegalItem = sorted.FirstOrDefault(i => i.Weight <= instance.KnapsackSize);
            var addedItemsVector = new bool[instance.ItemCount];

            if (biggestLegalItem == null || biggestLegalItem.Price <= greedyResult.Configuration.Price)
            {
                return(greedyResult);
            }

            addedItemsVector[biggestLegalItem.Id] = true;
            return(new KnapsackResult
            {
                KnapsackInstance = instance,
                Configuration = new KnapsackConfiguration
                {
                    ItemVector = addedItemsVector.ToList(),
                    Price = biggestLegalItem.Price,
                    Weight = biggestLegalItem.Weight
                }
            });
        }
Ejemplo n.º 7
0
 private DPCell FindBestCell(KnapsackInstance instance, out int bestPrice)
 {
     bestPrice = toVisit.Dequeue();
     foreach (var priceIndex in toVisit)
     {
         if (priceIndex > bestPrice)
         {
             bestPrice = priceIndex;
         }
     }
     return(memoryTable[bestPrice, instance.ItemCount - 1]);
 }
Ejemplo n.º 8
0
 private ConstructiveResult EmptyResult(KnapsackInstance instance)
 {
     return(new ConstructiveResult
     {
         KnapsackInstance = instance,
         Configuration = new KnapsackConfiguration
         {
             ItemVector = instance.Items.Select(i => false).ToList(),
             Price = 0,
             Weight = 0
         },
         Strategy = $"fptas (epsilon:{instance.ApproximationAccuracy})"
     });
 }
Ejemplo n.º 9
0
        private DPCell FindBestCell(KnapsackInstance instance)
        {
            DPCell bestCell = memoryTable[toVisit.Dequeue(), instance.ItemCount - 1];

            foreach (var weightIndex in toVisit)
            {
                var currentCell = memoryTable[weightIndex, instance.ItemCount - 1];
                if (currentCell.Value > bestCell.Value)
                {
                    bestCell = currentCell;
                }
            }
            return(bestCell);
        }
Ejemplo n.º 10
0
        public override ConstructiveResult Solve(KnapsackInstance instance)
        {
            //Select only the items that can fit into the backcpack and make a copy of them
            var modifiedItems = instance.Items
                                .Where(i => i.Weight <= instance.KnapsackSize)
                                .Select(i => new KnapsackItem {
                Price = i.Price, Weight = i.Weight
            })
                                .ToList();

            if (modifiedItems.Count() == 0)
            {
                return(EmptyResult(instance));
            }

            //Calculate the divider based on the desired accuracy and input instance
            double divider = instance.ApproximationAccuracy * (double)modifiedItems.Max(i => i.Price) / modifiedItems.Count();

            //Convert the price of each item
            foreach (var item in modifiedItems)
            {
                item.Price = (int)Math.Floor(item.Price / divider);
            }

            //Create a new instance for the DP solver
            var newKnapsackInstance = new KnapsackInstance
            {
                ApproximationAccuracy = instance.ApproximationAccuracy,
                Id           = instance.Id,
                Items        = modifiedItems,
                KnapsackSize = instance.KnapsackSize
            };

            var dpPriceStrategy = new ConstructiveDPPrice();
            var solution        = dpPriceStrategy.Solve(newKnapsackInstance);

            //Include the removed items in the result item vector
            solution.Configuration.ItemVector = ConvertItemVector(solution.Configuration.ItemVector, instance);
            solution.KnapsackInstance         = instance;

            //Calculate the total price using the solution item vector and the original item prices
            var solutionPrice = instance.Items.Aggregate(0,
                                                         (acc, item) => acc + item.Price * Convert.ToInt32(solution.Configuration.ItemVector[item.Id]));

            solution.Configuration.Price = solutionPrice;
            solution.Strategy            = $"fptas (epsilon:{instance.ApproximationAccuracy})";

            return(solution);
        }
Ejemplo n.º 11
0
        public override ConstructiveResult Solve(KnapsackInstance instance)
        {
            ConstructiveStrategy strategy;

            if (instance.KnapsackSize < instance.GetPriceOfAllItems())
            {
                strategy = new ConstructiveDPCapacity();
            }
            else
            {
                strategy = new ConstructiveDPPrice();
            }

            return(strategy.Solve(instance));
        }
Ejemplo n.º 12
0
        protected void FillTable(KnapsackInstance instance)
        {
            InitializeTable(instance);

            for (int itemIndex = 0; itemIndex < instance.ItemCount - 1; itemIndex++)
            {
                var toVisitNext = new Queue <int>();
                //Only visit the cells that have been added in the previous go
                foreach (var weight in toVisit)
                {
                    //do not add item
                    TryAddCell(weight, itemIndex, instance.KnapsackSize, toVisitNext);
                    //add item
                    TryAddCell(weight, itemIndex, instance.KnapsackSize, toVisitNext, instance.Items[itemIndex + 1]);
                }
                toVisit = toVisitNext;
            }
        }
Ejemplo n.º 13
0
        public KnapsackResult Solve(KnapsackInstance instance)
        {
            BestConfiguration = new KnapsackConfiguration {
                Price = 0, Weight = 0, ItemVector = new bool[instance.ItemCount].ToList()
            };

            FindBestConfiguration(0, new KnapsackConfiguration {
                Price = 0, Weight = 0, ItemVector = new List <bool>()
            }, instance.GetPriceOfAllItems(), instance);

            var result = new KnapsackResult
            {
                KnapsackInstance = instance,
                Configuration    = BestConfiguration
            };

            return(result);
        }
Ejemplo n.º 14
0
        public override ConstructiveResult Solve(KnapsackInstance instance)
        {
            FillTable(instance);
            var bestCell   = FindBestCell(instance);
            var itemVector = GetItemVector(bestCell);

            var knapsackConfiguration = new KnapsackConfiguration
            {
                ItemVector = itemVector,
                Price      = bestCell.Value
            };

            return(new ConstructiveResult
            {
                KnapsackInstance = instance,
                Configuration = knapsackConfiguration
            });
        }
Ejemplo n.º 15
0
        public override ConstructiveResult Solve(KnapsackInstance instance)
        {
            BestConfiguration = new KnapsackConfiguration {
                Price = int.MinValue, Weight = 0, ItemVector = CreateEmptySolution(instance.ItemCount)
            };

            FindBestConfiguration(0, new KnapsackConfiguration {
                Price = 0, Weight = 0, ItemVector = new List <bool>()
            }, instance.GetPriceOfAllItems(), instance);

            var result = new ConstructiveResult
            {
                KnapsackInstance = instance,
                NumberOfSteps    = numberOfSteps,
                Configuration    = BestConfiguration
            };

            return(result);
        }
Ejemplo n.º 16
0
        protected override void InitializeTable(KnapsackInstance instance)
        {
            memoryTable = new DPCell[instance.KnapsackSize + 1, instance.ItemCount];
            toVisit     = new Queue <int>();

            toVisit.Enqueue(0);
            memoryTable[0, 0] = new DPCell {
                AddedItem = false, Value = 0
            };
            var firstItem = instance.Items.First();

            if (firstItem.Weight <= instance.KnapsackSize)
            {
                toVisit.Enqueue(firstItem.Weight);
                memoryTable[firstItem.Weight, 0] = new DPCell {
                    AddedItem = true, Value = firstItem.Price
                };
            }
        }
Ejemplo n.º 17
0
        public override ConstructiveResult Solve(KnapsackInstance instance)
        {
            BestConfiguration = new KnapsackConfiguration {
                Price = int.MinValue, Weight = 0, ItemVector = new List <bool>()
            };
            numberOfSteps = 0;

            FindBestConfiguration(0, new KnapsackConfiguration {
                Price = 0, Weight = 0, ItemVector = new List <bool>()
            }, instance);

            var result = new ConstructiveResult
            {
                KnapsackInstance = instance,
                NumberOfSteps    = numberOfSteps,
                Configuration    = BestConfiguration
            };

            return(result);
        }
Ejemplo n.º 18
0
        public override ConstructiveResult Solve(KnapsackInstance instance)
        {
            var greedyStrategy = new ConstructiveGreedy();
            var greedySolution = greedyStrategy.Solve(instance);

            var sorted = new List <KnapsackItem>(instance.Items);

            sorted.OrderByDescending(i => i.Price);
            var addedItemsVector = new bool[instance.ItemCount];
            var currentPrice     = 0;
            var currentWeight    = 0;

            foreach (var item in sorted)
            {
                if (item.Weight <= instance.KnapsackSize)
                {
                    currentPrice              = item.Price;
                    currentWeight             = item.Weight;
                    addedItemsVector[item.Id] = true;
                }
            }

            if (currentPrice <= greedySolution.Configuration.Price)
            {
                return(greedySolution);
            }
            return(new ConstructiveResult
            {
                KnapsackInstance = instance,
                Configuration = new KnapsackConfiguration
                {
                    ItemVector = addedItemsVector.ToList(),
                    Price = currentPrice,
                    Weight = currentWeight
                }
            });
        }
 public SimulatedAnnealingSolver(KnapsackInstance instance, AnnealingOptions options)
 {
     Instance      = instance;
     Options       = options;
     NumberOfSteps = 0;
 }
Ejemplo n.º 20
0
        private void FindBestConfiguration(int itemIndex, KnapsackConfiguration currentConfiguration, KnapsackInstance instance)
        {
            numberOfSteps++;
            if (itemIndex > instance.ItemCount - 1)
            {
                if (currentConfiguration.Weight <= instance.KnapsackSize && currentConfiguration.Price > BestConfiguration.Price)
                {
                    BestConfiguration = currentConfiguration;
                }
                return;
            }
            var currentItem = instance.Items[itemIndex];

            var leftConfiguration = new KnapsackConfiguration
            {
                Price      = currentConfiguration.Price,
                Weight     = currentConfiguration.Weight,
                ItemVector = new List <bool>(currentConfiguration.ItemVector)
            };

            leftConfiguration.ItemVector.Add(false);

            var rightConfiguration = new KnapsackConfiguration
            {
                Price      = currentConfiguration.Price + currentItem.Price,
                Weight     = currentConfiguration.Weight + currentItem.Weight,
                ItemVector = new List <bool>(currentConfiguration.ItemVector)
            };

            rightConfiguration.ItemVector.Add(true);

            FindBestConfiguration(itemIndex + 1, leftConfiguration, instance);
            FindBestConfiguration(itemIndex + 1, rightConfiguration, instance);
        }
Ejemplo n.º 21
0
 protected abstract void InitializeTable(KnapsackInstance instance);
Ejemplo n.º 22
0
        private void FindBestConfiguration(int itemIndex, KnapsackConfiguration currentConfiguration, int remainingItemsPrice, KnapsackInstance instance)
        {
            numberOfSteps++;

            //Check for a leaf node
            if (itemIndex > instance.ItemCount - 1)
            {
                if (currentConfiguration.Weight <= instance.KnapsackSize && currentConfiguration.Price > BestConfiguration.Price)
                {
                    BestConfiguration = currentConfiguration;
                }
                return;
            }
            //Check for price bound
            if (currentConfiguration.Price + remainingItemsPrice <= BestConfiguration.Price)
            {
                return;
            }
            //Check for weight overload
            if (currentConfiguration.Weight > instance.KnapsackSize)
            {
                return;
            }

            var currentItem = instance.Items[itemIndex];

            var leftConfiguration = new KnapsackConfiguration
            {
                Price      = currentConfiguration.Price,
                Weight     = currentConfiguration.Weight,
                ItemVector = new List <bool>(currentConfiguration.ItemVector)
            };

            leftConfiguration.ItemVector.Add(false);

            var rightConfiguration = new KnapsackConfiguration
            {
                Price      = currentConfiguration.Price + currentItem.Price,
                Weight     = currentConfiguration.Weight + currentItem.Weight,
                ItemVector = new List <bool>(currentConfiguration.ItemVector)
            };

            rightConfiguration.ItemVector.Add(true);

            FindBestConfiguration(itemIndex + 1, leftConfiguration, remainingItemsPrice - currentItem.Price, instance);
            FindBestConfiguration(itemIndex + 1, rightConfiguration, remainingItemsPrice - currentItem.Price, instance);
        }