public SolutionCandidate Clone() { SolutionCandidate Clone = new SolutionCandidate() { LowerBound = this.LowerBound, Assignments = this.Assignments }; return(Clone); }
public void EvaluateCost() { BuildMinimumCostTable(NumberOfAgents, NumberOFTasks); SolutionCandidate currentSolution = new SolutionCandidate(); currentSolution.Assignments = new System.Collections.Generic.List <int>(); for (int i = 0; i < NumberOfAgents; i++) { currentSolution.Assignments.Add(i); currentSolution.LowerBound += this.CostMatrix[NumberOfAgents, NumberOfAgents]; } SolutionCandidatePriorityQueue.Add(new SolutionCandidate() { Assignments = new System.Collections.Generic.List <int>() }); while (!SolutionCandidatePriorityQueue.IsEmpty) { // Get next candidate. If a priority queue is used, the "next" candidate is the // most promising (with lowest lower bound): var candidate = SolutionCandidatePriorityQueue.DeleteMin(); // Branch out: for (int i = 0; i < NumberOFTasks; i++) { // Only create the branch if the current task is not already taken by an agent: if (!candidate.Assignments.Contains(i)) { var branch = (SolutionCandidate)candidate.Clone(); branch.Assignments.Add(i); branch.LowerBound = CalculateLowerBound(branch); // Only use the generated branch if its lower bound is strictly better than // the currently found solution cost. // This is the "bound" part in "Branch and Bound": if (currentSolution.LowerBound < branch.LowerBound) { continue; } if (branch.Assignments.Count == NumberOfAgents) { currentSolution = branch; } else { this.SolutionCandidatePriorityQueue.Add(branch); } } } } }
private int CalculateLowerBound(SolutionCandidate candidate) { int lowerBound = 0; int Agent = 0; // Add the costs for the already fixed agents: for (; Agent < candidate.Assignments.Count; Agent++) { var task = candidate.Assignments[Agent]; lowerBound += this.CostMatrix[Agent, task]; } for (int j = Agent; j < MinimumCosts.Length; j++) { lowerBound += MinimumCosts[j]; } return(lowerBound); }