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 }); }
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); }
//Performs a random bit-flip public bool Try(SimulatedAnnealingSolver solverInstance, ref KnapsackConfiguration currentConfiguration) { var bitToFlip = random.Next(0, solverInstance.Instance.ItemCount - 1); var triedConfiguration = new KnapsackConfiguration(currentConfiguration); triedConfiguration.ItemVector[bitToFlip] = !triedConfiguration.ItemVector[bitToFlip]; if (triedConfiguration.ItemVector[bitToFlip]) { triedConfiguration.Price += solverInstance.Instance.Items[bitToFlip].Price; triedConfiguration.Weight += solverInstance.Instance.Items[bitToFlip].Weight; } else { triedConfiguration.Price -= solverInstance.Instance.Items[bitToFlip].Price; triedConfiguration.Weight -= solverInstance.Instance.Items[bitToFlip].Weight; } triedConfiguration.Cost = solverInstance.Options.ScoreStrategy.Cost(triedConfiguration, solverInstance); if (triedConfiguration.Cost >= currentConfiguration.Cost) { currentConfiguration = triedConfiguration; return(true); } var delta = triedConfiguration.Cost - currentConfiguration.Cost; if (random.NextDouble() < Math.Exp(delta / solverInstance.CurrentTemperature)) { currentConfiguration = triedConfiguration; return(true); } return(false); }
public int Cost(KnapsackConfiguration configuration, SimulatedAnnealingSolver solver) { int score = configuration.Price; if (configuration.Weight > solver.Instance.KnapsackSize) { var weightOverrun = configuration.Weight - solver.Instance.KnapsackSize; score -= (int)Math.Round(weightOverrun * solver.Options.PenaltyMultiplier); } return(score); }
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); }
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 }); }
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); }
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); }
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); }
public KnapsackConfiguration GetStartingPosition(SimulatedAnnealingSolver solverInstance) { var configuration = new KnapsackConfiguration { Price = 0, Weight = 0 }; var itemVector = new List <bool>(); foreach (var item in solverInstance.Instance.Items) { var added = Convert.ToBoolean(random.Next(0, 1)); itemVector.Add(added); if (added) { configuration.Price += item.Price; configuration.Weight += item.Weight; } } configuration.ItemVector = itemVector; return(configuration); }
public KnapsackResult Solve() { var movesHistory = new List <DataPoint>(); currentConfiguration = Options.StartingPositionStrategy.GetStartingPosition(this); BestConfiguration = currentConfiguration; CurrentTemperature = Options.BaseStartingTemperature; while (!Options.FrozenStrategy.Frozen(this)) { AcceptedDuringEquilibrium = 0; EquilibriumSteps = 0; while (Options.EquilibriumStrategy.Equilibrium(this)) { EquilibriumSteps++; movesHistory.Add(new DataPoint((int)NumberOfSteps + EquilibriumSteps, currentConfiguration.Price)); //Try to accept a new state if (Options.TryStrategy.Try(this, ref currentConfiguration)) { AcceptedDuringEquilibrium++; } //Check if new maximum has been found if (currentConfiguration.Price > BestConfiguration.Price && currentConfiguration.Weight <= Instance.KnapsackSize) { BestConfiguration = currentConfiguration; } } CurrentTemperature = Options.CoolStrategy.Cool(this); NumberOfSteps += (ulong)EquilibriumSteps; } return(new KnapsackResult { Configuration = BestConfiguration, KnapsackInstance = Instance, NumberOfSteps = NumberOfSteps, MovesHistory = movesHistory }); }