This chapter is about the customization of the search. What stategy(ies) to use to branch, i.e. what variables to select and what value(s) to assign to them? How to use nested searches, i.e. searches in subtrees? And so on.
The or-tools CP solver is quite flexible and comes with several tools (Decisions, DecisionBuilders, ...) that we call search primitives. Some are predefined and can be used right out of the box while others can be customized thanks to callbacks. You can also combine different search strategies. If needed, you can define your own search primitive classes by inheriting from base classes.
To efficiently use your tools, you need to know them a little and this chapter introduces you in a gentle manner to the inner working of the solver. The covered material is enough for you to understand how you can customize your search primitives without being drowned in the often tedious details of the implementation[1].
To illustrate the customization of the search, we try to solve the n-Queen Problem that we have introduced in the chapter Introduction to constraint programming.
Overview:
We first discuss the n-Queen Problem and present a basic model to solve it. To go one step further and devise a search algorithm to solve this problem, we present a little bit the inner working of the solver. Specifically, we show how it traverses and constructs the search tree. We even can visualize the search thanks to the wonderful cpviz framework that we introduce next. Equipped with this knowledge and visualization capacity, we can better understand out of the box and customized primitives and apply them to solve the n-Queen Problem. We end this chapter with a relatively advanced feature: SymmetryBreakers that allow to break symmetries during the search (on the fly).
Prerequisites:
Classes under scrutiny:
Decision, DecisionBuilder, DecisionVisitor, SearchMonitor, TreeMonitor.
Files:
The files used in this chapter are:
Content:
[1] | If you take a look at the source code, we hope you will enjoy the clarity (?) of our code. We believe that the most efficient code should remain simple and allow for more complicated but more efficient specializations when needed. |