static int BranchAndBoundValue(BnBVertex vertex) { if (vertex.Vertices.Count == graph.Size) { return(graph.CalculateRoute(vertex.Vertices)); } else { return(int.MaxValue); } }
static int BranchAndBoundLowerBound(BnBVertex vertex) { if (vertex.LowerBound != int.MaxValue) { return(vertex.LowerBound); } else { int lowerBound = 0; int i, j, iPow2, jPow2, logicAnd; // obliczanie wartości aktualnie zapisanej trasy for (int it = 0; it < vertex.Vertices.Count - 1; it++) { i = vertex.Vertices[it]; j = vertex.Vertices[it + 1]; lowerBound += graph.Matrix[i, j]; } // wyznaczenie minimów wychodzących z wierzchołków, z których jeszcze można wyjść for (i = 0; i < graph.Size; i++) { int min = int.MaxValue; iPow2 = 1 << i; logicAnd = iPow2 & vertex.BitMask; if (logicAnd == 0 || i == vertex.Vertices.Last()) { for (j = 0; j < graph.Size; j++) { jPow2 = 1 << j; logicAnd = jPow2 & vertex.BitMask; if (logicAnd == 0) { int newMin = graph.Matrix[i, j]; if (newMin < min) { min = newMin; } } } lowerBound += min; } } vertex.LowerBound = lowerBound; return(lowerBound); } }
public static IList <int> BranchAndBoundBestFirst(MatrixGraph givenGraph) { graph = givenGraph; var queue = new PriorityQueue <BnBVertex>(); queue.Enqueue(new BnBVertex(0, 0)); int higherBound = int.MaxValue; List <int> bestPermutation = null; int iPow2, logicAnd; while (queue.Count != 0) { var vertexLowestBound = queue.Dequeue(); if (BranchAndBoundLowerBound(vertexLowestBound) < higherBound) { for (int i = 1; i < graph.Size; i++) { iPow2 = 1 << i; logicAnd = iPow2 & vertexLowestBound.BitMask; if (logicAnd == 0) { var childVertex = new BnBVertex(i, vertexLowestBound.BitMask + iPow2, vertexLowestBound); int value = BranchAndBoundValue(childVertex); if (value < higherBound) { higherBound = value; bestPermutation = childVertex.Vertices; } BranchAndBoundLowerBound(childVertex); if (childVertex.LowerBound < higherBound) { queue.Enqueue(childVertex); } } } } } return(bestPermutation); }