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); }
public override ConstructiveResult Solve(KnapsackInstance instance) { ConstructiveStrategy strategy; if (instance.KnapsackSize < instance.GetPriceOfAllItems()) { strategy = new ConstructiveDPCapacity(); } else { strategy = new ConstructiveDPPrice(); } return(strategy.Solve(instance)); }