Scippy

SCIP

Solving Constraint Integer Programs

How to add display columns

While solving a constraint integer program, SCIP displays status information in a column-like fashion. The current number of processed branching tree nodes, the solving time, and the relative gap between primal and dual bound are examples of such display columns. There already exists a wide variety of display columns which can be activated or deactivated on demand, see src/scip/disp_default.c. Additionally, the user can implement his/her own display columns in order to track problem or algorithm specific values.
A complete list of all displays contained in this release can be found here.

We now explain how users can add their own display columns. We give the explanation for creating your own source file for each additional display column. Of course, you can collect different additional display columns in one source file. Take src/scip/disp_default.c, where all default display columns are collected, as an example. As all other default plugins, the default display column plugins and the display column template are written in C. C++ users can easily adapt the code by using the scip::ObjDisp wrapper base class and implement the scip_...() virtual methods instead of the SCIP_DECL_DISP... callback methods.

Additional documentation for the callback methods of a display column can be found in the file type_disp.h.

Here is what you have to do to implement a display column (assuming your display column is named "mydisplaycolumn"):

  1. Copy the template files src/scip/disp_xyz.c and src/scip/disp_xyz.h into files named "disp_mydisplaycolumn.c" and "disp_mydisplaycolumn.h".
    Make sure to adjust your build system such that these files are compiled and linked to your project.
    If you are adding a new default plugin, this means updating the src/CMakeLists.txt and Makefile files in the SCIP distribution.
  2. Use SCIPincludeDispMydisplaycolumn() in order to include the display column into your SCIP instance, e.g., in the main file of your project (see, e.g., src/cmain.c in the Binpacking example).
    If you are adding a new default plugin, this include function must be added to src/scipdefplugins.c.
  3. Open the new files with a text editor and replace all occurrences of "xyz" by "mydisplaycolumn".
  4. Adjust the properties of the display column.
  5. Define the display column data. This is optional.
  6. Implement the interface methods.
  7. Implement the fundamental callback methods.
  8. Implement the additional callback methods. This is optional.

Properties of a Display Column

At the top of the new file "disp_mydisplaycolumn.c" you can find the display column properties. These are given as compiler defines. In the C++ wrapper class, you have to provide the display column properties by calling the constructor of the abstract base class scip::ObjDisp from within your constructor. The properties you have to set have the following meaning:

DISP_NAME: the name of the display column.
This name is used in the interactive shell to address the display column. Additionally, if you are searching for a display column with SCIPfindDisp(), this name is looked up. Names have to be unique: no two display columns may have the same name.
DISP_DESC: the description of the display column.
This string is printed as a description of the display column in the interactive shell.
DISP_HEADER: the header of the display column.
This string is printed as the header of the display column in the status information display.
DISP_WIDTH: the width of the display column.
This parameter defines the width (number of characters) of the display column. The value of the parameter has to be greater than or equal to the number of characters in the header string.
DISP_PRIORITY: the priority of the display column.
The total width of status information lines is bounded by the parameter "display width". The display columns actually contained in the status information display are selected in decreasing order of their priority. Furthermore, the user can force columns to be displayed or not to be displayed in the status information display. For that, (s)he has to switch the value of the display column's parameter "active" from "auto" (its default value) to "on" or "off", respectively.
DISP_POSITION: the relative position of the display column.
In the status information display, the display columns are arranged from left to right in increasing order of their relative position.
DISP_STRIPLINE: the default for whether the display column should be separated with a line from its right neighbor.
This parameter states whether the display column should be separated with the string "|" from its right neighbor. In so doing, the clearness of the status information display may improve.

Display Column Data

Below the header "Data structures" you can find a struct which is called "struct SCIP_DispData". In this data structure, you can store the data of your display column. For example, you should store the adjustable parameters of the display column in this data structure. If you are using C++, you can add display column data as usual as object variables to your class.
Defining display column data is optional. You can leave the struct empty.

Interface Methods

At the bottom of "disp_mydisplaycolumn.c" you can find the interface method SCIPincludeDispMydisplaycolumn(), which also appears in "disp_mydisplaycolumn.h".
This method only has to be adjusted slightly. It is responsible for notifying SCIP of the presence of the display column by calling the method SCIPincludeDisp().

The interface method is called by the user, if (s)he wants to include the display column, i.e., if (s)he wants to use the display column in his application.

If you are using display column data, you have to allocate the memory for the data at this point. You can do this by calling:

#define SCIP_CALL(x)
Definition: def.h:373
#define SCIPallocBlockMemory(scip, ptr)
Definition: scip_mem.h:89

You also have to initialize the fields in struct SCIP_DispData afterwards.

Although this is very uncommon, you may also add user parameters for your display column, see the method SCIPincludeConshdlrKnapsack() in the knapsack constraint handler for an example.

Fundamental Callback Methods of a Display Column

Display column plugins have only one fundamental callback method, namely the DISPOUTPUT method. This method has to be implemented for every display column; the other callback methods are optional. In the C++ wrapper class scip::ObjDisp, the scip_output() method (which corresponds to the DISPOUTPUT callback) is a virtual abstract member function. You have to implement it in order to be able to construct an object of your display column class.

Additional documentation for the callback methods can be found in type_disp.h.

DISPOUTPUT

The DISPOUTPUT callback is called after each pricing loop during node processing and after a node has been processed. In addition, at the root node, the callback is executed after each iteration of the price-and-cut loop. It should write the display column information for the current node to a given output file stream.

Typical methods called by a display column are, for example, SCIPdispLongint(), SCIPdispInt(), SCIPdispTime(), and SCIPinfoMessage().

Additional Callback Methods of a Display Column

The additional callback methods do not need to be implemented in every case. They can be used, for example, to initialize and free private data.

DISPCOPY

The DISPCOPY callback is executed when a SCIP instance is copied, e.g. to solve a sub-SCIP. By defining this callback as NULL the user disables the execution of the specified column. In general it is probably not needed to implement that callback since the output of the copied instance is usually suppressed. In the other case or for debugging the callback should be implement.

DISPFREE

If you are using display column data, you have to implement this method in order to free the display column data. This can be done by the following procedure:

static
SCIP_DECL_DISPFREE(dispFreeMydisplaycolumn)
{
SCIP_DISPDATA* dispdata;
dispdata = SCIPdispGetData(disp);
assert(dispdata != NULL);
SCIPfreeMemory(scip, &dispdata);
return SCIP_OKAY;
}
#define NULL
Definition: def.h:266
void SCIPdispSetData(SCIP_DISP *disp, SCIP_DISPDATA *dispdata)
Definition: disp.c:324
SCIP_DISPDATA * SCIPdispGetData(SCIP_DISP *disp)
Definition: disp.c:314
#define SCIPfreeMemory(scip, ptr)
Definition: scip_mem.h:78
struct SCIP_DispData SCIP_DISPDATA
Definition: type_disp.h:76
#define SCIP_DECL_DISPFREE(x)
Definition: type_disp.h:93
@ SCIP_OKAY
Definition: type_retcode.h:42

If you have allocated memory for fields in your display column data, remember to free this memory before freeing the display column data itself. If you are using the C++ wrapper class, this method is not available. Instead, just use the destructor of your class to free the member variables of your class.

DISPINIT

The DISPINIT callback is executed after the problem is transformed. The display column may, e.g., use this call to initialize its display column data.

DISPEXIT

The DISPEXIT callback is executed before the transformed problem is freed. In this method, the display column should free all resources that have been allocated for the solving process in DISPINIT.

DISPINITSOL

The DISPINITSOL callback is executed when the presolving is finished and the branch-and-bound process is about to begin. The display column may use this call to initialize its branch-and-bound specific data.

DISPEXITSOL

The DISPEXITSOL callback is executed before the branch-and-bound process is freed. The display column should use this call to clean up its branch-and-bound specific data.