public void Solve() { // This method drives the solver algorithms // The Bound Value for the Branch & Bound float BoundValue = 0; // Step 1: an "Improved Greedy First Fit" algorithm is executed and a solution will be found. // This solution will be an Upper Bound value for any further research. if (CheckIfSolutionCanExist()) { // Status Label // Label.Text = "Getting Bound solution"; //Application.DoEvents(); // Collection which is the "Greedy First Fit" solution List<Bin> BoundSolution = new List<Bin>(); BoundSolution = GreedyFirstFit(); // Store the solution in the Dictionary SetOfSolutions.Add("Bound Solution", BoundSolution); // Get the Bound Value for the next step BoundValue = GetSize("Bound Solution"); } else { return; } /* Step 2: try to find a better solution exploring the Branch & Bound with a "Greedy Best Fit" algorithm. * This process can be repeated twice for searching the Best Cost and the Best Size solutions. */ // Get a Branch & Bound List of improving solutions BranchAndBound Branch = new BranchAndBound(ListOfStocks, ListOfItems, TotalItemsSum, BoundValue/*, Label*/); List<BranchAndBound.BranchBound> BranchList = new List<BranchAndBound.BranchBound>(); BranchList = Branch.GetBranchAndBound(); if (BranchList.Count == 0) { // The Branch & Bound is empty. The algorithm stops here and displays only the Bound Solution //PrintSolution(0, 0, SetOfSolutions); return; } // Sort the BranchList Non Decreasing on Cost and pass it to the "Greedy Best Fit" algorithm // only if at least one cost has been inserted NonDecreasingSortOnBranchAndBoundCost soc = new NonDecreasingSortOnBranchAndBoundCost(); BranchList.Sort(soc); float BestCost = BranchList[0].Cost; if (BestCost > 0) { // Status Label //Label.Text = "Searching the Best solution on Cost"; //Application.DoEvents(); SetOfSolutions.Add("Best Cost Solution", GreedyBestFit(BranchList)); } // Sort the BranchList Non Decreasing on Size and pass it to the "Greedy Best Fit" algorithm NonDecreasingSortOnBranchAndBoundSize sos = new NonDecreasingSortOnBranchAndBoundSize(); BranchList.Sort(sos); // Status Label //Label.Text = "Searching the Best solution on Size"; // Application.DoEvents(); // Store the Best Size solution in the Dictionary, even if it's null SetOfSolutions.Add("Best Size Solution", GreedyBestFit(BranchList)); float AbsoluteBestSize = BranchList[0].Size; /* Step 3: now the search is made only to achieve the Absolute Best Size with a "Greedy Next Fit" algorithm * applied to the branches with size equal to AbsoluteBestSize. * If "Best Size Solution" is also "Absolute Best", or if there are too much items to process (12), than this step * is not executed and the results are displayed. */ // Notice that GetSize("Best Size Solution") return 0 if the Best Size Solution doesn't exist float CandidateBestSize = GetSize("Best Size Solution"); if (CandidateBestSize > 0 && AbsoluteBestSize >= CandidateBestSize || ListOfItems.Count > 12) { //PrintSolution(AbsoluteBestSize, BestCost, SetOfSolutions); return; } // Cut all the now useless branches in the BranchList BranchList.RemoveAll(branch => branch.Size > AbsoluteBestSize); for (int i = 1; i <= ListOfItems.Count; ++i) { NumberOfPermutations *= i; } //ExitGreedyNextFit.Visible = true; //ExitGreedyNextFit.Focus(); //ProgressBar.Value = 0; int branchCounter = 0; // Execute the Greedy Next Fit with the hope to find the Absolute Best Size Solution foreach (BranchAndBound.BranchBound bb in BranchList) { ++branchCounter; //ProgressBar.Value = 100 * branchCounter / BranchList.Count; //Application.DoEvents(); GreedyNextFit(bb, branchCounter, BranchList.Count); if (HasFoundAbsoluteBestSolution) { // Store the solution (only if it exists) in the Dictionary SetOfSolutions.Add("Absolute Best Size Solution", GreedyNextFitSolution); break; } } // Display results //PrintSolution(AbsoluteBestSize, BestCost, SetOfSolutions); }
private void InitializeSolution(BranchAndBound.BranchBound branch) { // Clear the GreedyNextFit solution list GreedyNextFitSolution.Clear(); // Create a new GreedyNextFit solution list for (int i = 0; i < branch.SetOfStocks.Length; ++i) { GreedyNextFitSolution.Add(new Bin(branch.SetOfStocks[i], branch.SetOfStocksCost[i])); } }
private void GreedyNextFitProcedure(BranchAndBound.BranchBound branch, int thebranchCounter, int theBranchListCount) { // k indexes the elements in GreedyNextFit solution list int k = 0; foreach (int j in myLexicographicOrder) { //Application.DoEvents(); /*if (ExitGreedyNextFit.Checked) { searchAbsoluteBestSolution = false; return; }*/ if (GreedyNextFitSolution[k].Reject >= ListOfItems[j].Size) { // Assign the current Item to the current solution list element AssignItem(GreedyNextFitSolution[k], ListOfItems[j]); continue; } else if (k <= GreedyNextFitSolution.Count - 2 && GreedyNextFitSolution[k + 1].Reject >= ListOfItems[j].Size) { // Select, if it exists, one more suitable Stock (e.g. it exists and still has enough reject) ++k; // Assign the current Item to the current (the NEXT) solution list element AssignItem(GreedyNextFitSolution[k], ListOfItems[j]); continue; } else if (NextPermutation()) { // The current permutation doesn't fit, so a new one must be processed InitializeSolution(branch); ++myPermutationCounter; if (myPermutationCounter % 100000 == 0) { //Label.Text = "Searching the Absolute Best Solution: Branch " + thebranchCounter.ToString() + " of " + // theBranchListCount.ToString() + // ((double)myPermutationCounter / (double)NumberOfPermutations).ToString(" - #0% "); } return; } else { // All the permutations have been tested and no solution has been found: quit the GreedyNextFitProcedure searchAbsoluteBestSolution = false; return; } } // At this point a solution has been found QualifySolution(GreedyNextFitSolution); HasFoundAbsoluteBestSolution = true; searchAbsoluteBestSolution = false; }
private void GreedyNextFit(BranchAndBound.BranchBound branch, int mybranchCounter, int myBranchListCount) { // Sort Non Decreasing the Set Of Stocks Array.Sort(branch.SetOfStocks); // Sort Non Decreasing the ListOfItems NonDecreasingSortOnItemSize ndsItems = new NonDecreasingSortOnItemSize(); ListOfItems.Sort(ndsItems); // If with this branch a solution could exist it must be ItemSize max <= StockSize max if (ListOfItems[ListOfItems.Count - 1].Size > branch.SetOfStocks[branch.SetOfStocks.Length - 1]) { return; } InitializeLexicographicArray(); InitializeSolution(branch); // Reset the counter of permutations tested myPermutationCounter = 1; searchAbsoluteBestSolution = true; while (searchAbsoluteBestSolution) { GreedyNextFitProcedure(branch, mybranchCounter, myBranchListCount); if (GreedyNextFitSolution == null) { searchAbsoluteBestSolution = false; } } return; }