Branch and Bound - what to store - optimization

I have read in more than one book (including Wolsey) that when implementing a branch and bound algorithm, one does not need to store the whole tree, just a list of active nodes (leaf nodes, for what I understand).
The thing is, I could not understand how to work out the new bounds after I branch, if I don't have the bounds of every ancestor.
Some clarification on that would be appreciated.

OK, let's work out an example. Let's say you're implementing a fairly naive integer program solver that tries to solve a binary integer program by solving its LP relaxation, and, if it doesn't get an integral solution, branches on some variable. Let's suppose you have a maximisation problem.
Let's consider what happens after exactly one branch. You solved the root subproblem, and suppose it gave you a fractional solution with objective value 10. Then you branched on a variable, giving you a left subproblem with optimal objective value 9 and a right subproblem with optimal objective value 8.
We got a global bound of 10 from the root subproblem. We also know that every integral solution lies in either the left subproblem or the right subproblem, and we know that the left subproblem has no solutions better than 9 and the right subproblem has no subproblems better than 8. Then there are no solutions better than 9 to the root subproblem, even though the root LP relaxation wasn't enough to tell us that.
In general, your best global bound is the worst bound any active subproblem. Fathomed subproblems are irrelevant since they can't contain a feasible solution with better objective value than your incumbent. Subproblems that have been branched are irrelevant because their bounds should be dominated by the weakest of their childrens' bounds.

Related

How does SCIP calculate vanillafullstrongbranching-scores?

I want to do some experiments on branchingrules in SCIP (using the python interface).
To be sure some basics of my code work, I tried to mirror the vanillafullstrongbranching of SCIP using the dive functionality.
This works mostly as expected, but I get weird results for nodes that have at least one infeasible child. I dug through PySCIPOpt and the C-code of SCIP and would have expected a big number as the sb score in case (at least) one child is infeasible, as the LP-solver returns a big number for infeasible problems and SCIP is using the product-score by default. Instead of big numbers I get numbers just big enough to be bigger than the other scores.
My questions is: What am I missing in the code? Where and how does SCIP treat the score for infeasible children differently.
As quite some code is required to reproduce this, I created a gist, that makes use of a set-cover instance I also uploaded to github.
I'm pretty sure the strongbranching score never exceeds the cutoffbound of the lp, so infeasible nodes would get a score of the cutoffbound.

Branching mechanism in B&P using SCIP

I'm implementing a branch and price algorithm in c using SCIP.
Question: To call the branching mechanism, I use the basic BRANCHEXECLP mechanism. How does SCIP know when to branch? When the current relaxation solution has non-integer solutions, right? I don't have to tell SCIP to invoked the branching mechanism for this case, right?
I'm asking because (for the most part) my B&P algorithm is working well. But, at some point it reaches a node corresponding to the dual bound solution. After solving the pricing problem (and no columns are attractive to enter the master problem), the relaxation solution at this node contains non-integer solutions, but the branching mechanism is not invoked. The run just quits. Any idea as to what is going on here?
Thanks,
Rob Curry
I guess you checked during pricing that there are fractional variables in the current LP solution?
And the dual bound at that node equals the global dual bound? Did you mark your objective to only have integral values? In that case, if the dual bound is close enough to the primal bound that rounding it up gives the same number, SCIP will just cut off the node. Perhaps also SCIP found a new solution after your pricing which was immediately proven to be optimal by the current global dual bound? SCIP automatically runs some simple rounding heuristics after each solved LP in the pricing loop.

Finding best path trought strongly connected component

I have a directed graph which is strongly connected and every node have some price(plus or negative). I would like to find best (highest score) path from node A to node B. My solution is some kind of brutal force so it takes ages to find that path. Is any algorithm for this or any idea how can I do it?
Have you tried the A* algorithm?
It's a fairly popular pathfinding algorithm.
The algorithm itself is not to difficult to implement, but there are plenty of implementations available online.
Dijkstra's algorithm is a special case for the A* (in which the heuristic function h(x) = 0).
There are other algorithms who can outperform it, but they usually require graph pre-processing. If the problem is not to complex and you're looking for a quick solution, give it a try.
EDIT:
For graphs containing negative edges, there's the Bellman–Ford algorithm. Detecting the negative cycles comes at the cost of performance, though (worse than the A*). But it still may be better than what you're currently using.
EDIT 2:
User #templatetypedef is right when he says the Bellman-Ford algorithm may not work in here.
The B-F works with graphs where there are edges with negative weight. However, the algorithm stops upon finding a negative cycle. I believe that is a useful behavior. Optimizing the shortest path in a graph that contains a cycle of negative weights will be like going down a Penrose staircase.
What should happen if there's the possibility of reaching a path with "minus infinity cost" depends on the problem.

When to switch from Dynamic Programming (2D table) to Branch & Bound algorithm?

I'm doing a knapsack optimization problem involving dynamic programming and branch & bound. I noticed that when the capacity and the item of the problem gets large, filling up the 2D table for the dynamic programming algorithm will get exponentially slower. At some point I am going to assume that I am suppose to switch algorithm depending on the size of the problem (since lecture have give two types of optimization)?
I've tried to google at what point (what size) should I switch from dynamic programming to branch & bound, but I couldn't get the result that I wanted.
Or, is there another way of looking at the knapsack problem in which I can combine dynamic programming and branch & bound as one algorithm instead of switching algorithm depending of the size of the problem?
Thanks.
Often when you have several algorithms that solve a problem but whose runtimes have different characteristics, you determine (empirically, not theoretically) when one algorithm becomes faster than the other. This is highly implementation- and machine-dependent. So measure both the DP algorithm and the B&B algorithm and figure out which one is better when.
A couple of hints:
You know that DP's runtime is proportional to the number of objects times the size of the knapsack.
You know that B&B's runtime can be as bad as 2# objects, but it's typically much better. Try to figure out the worst case.
Caches and stuff are going to matter for DP, so you'll want to estimate its runtime piecewise. Figure out where the breakpoints are.
DP takes up exorbitant amounts of memory. If it's going to take up too much, you don't really have a choice between DP and B&B.

Determining hopeless branches early in branch-and-bound algorithms

I have to design a branch-and bound algorithm that solves the optimal tour of a graph on the cartesian plane every time. I have been given the hint that identifying hopeless branches earlier in the runtime will compound into a program that runs "a hundred times faster". I had the idea of assuming that the shortest edge connected to the starting/ending node will be either the first or last edge in the tour but a thin diamond shaped graph proves otherwise. Does any one have ideas for how to eliminate these hopeless branches or a reference that talks about this?
Basically, is there a better way to branch to subsets of solutions better than just lexicographically, eg. first branch is including and excluding edge a-b, second branch includes and excludes branch a-c
So somewhere in your branch-and-bound algorithm, you look at possible places to go, and then somehow keep track of them to do later.
To make this more efficient, you can do a couple things:
Write a better bound calculator. In other words, come up with an algorithm that determines the bound more accurately. This will result in less time spent on paths that turn out to be poor.
Instead of using a stack to keep track of things to do, use a queue. Instead of using a queue, use a priority queue (heap) ordered by bound, e.g. the things that seem best are put at the top of the heap, and the things that seem bad are put on the bottom.
Nearest-neighbor is a simple algorithm. Branch-and-Bound is just an optimizing loop and additionally you need a sub-problem solver. I think nearest-neighbor is also a branch-and-bound algorithm. Instead I would look into the simplex algorithm. It's a linear programming algorithm. Also cutting-plane algorithm to solve tsp.