/// <summary> /// Searches for best solution using branch and bound strategy. /// </summary> private static void BranchAndBound() { SolutionCandidate candidate = GetMostPromisingCandidate(); while (candidate != null) { SolutionCandidate branch = candidate.GetBranch(); while (branch != null) { CalculateBound(branch); if (branch.UpperBound < _currentSolution.UpperBound) { branch.IsPromising = false; } else if (branch.IsComplete && branch.UpperBound > _currentSolution.UpperBound) { _currentSolution = branch; MarkNotPromisingCandidates(); } _candidates.Add(branch); branch = candidate.GetBranch(); } _candidates.Remove(candidate); candidate = GetMostPromisingCandidate(); } }
/// <summary> /// Calculates solution candidate branch upper bound. /// </summary> /// <param name="branch">Branch.</param> private static void CalculateBound(SolutionCandidate branch) { for (int i = 0; i < branch.Assignements.Length; i++) { branch.UpperBound += _costTable[i, branch.Assignements[i]]; } for (int i = branch.Assignements.Length; i < N; i++) { branch.UpperBound += _maxValues[i]; } }
/// <summary> /// Creates initial solution. /// </summary> /// <returns>Initial solution.</returns> private static SolutionCandidate CreateInitialSolution() { SolutionCandidate initialSolution = new SolutionCandidate(N, new int[N]); for (int i = 0; i < N; i++) { initialSolution.Assignements[i] = i; initialSolution.UpperBound += _costTable[i, i]; } return(initialSolution); }
/// <summary> /// Prepares variables for solving. /// </summary> private static void Prepare() { _currentSolution = CreateInitialSolution(); _candidates = new List <SolutionCandidate>(); _candidates.Add(new SolutionCandidate(N)); _maxValues = new int[N]; for (int i = 0; i < N; i++) { _maxValues[i] = GetMaxValue(i); } }
/// <summary> /// Gets most promising solution candidate from currently found solution candidates. /// </summary> /// <returns>Most promising solution candidate; null, if no such candidate exists.</returns> private static SolutionCandidate GetMostPromisingCandidate() { SolutionCandidate bestCandidate = null; foreach (SolutionCandidate candidate in _candidates) { if (!candidate.IsComplete && candidate.IsPromising && (bestCandidate == null || candidate.UpperBound > bestCandidate.UpperBound)) { bestCandidate = candidate; } } return(bestCandidate); }