Introduction and an example

Features of the CPO file format

The CP Optimizer (CPO) file format is a specification for writing constraint programming models suitable for CP Optimizer, together with other information such as parameter settings and search phases. A single model can be contained in one file or span multiple files.

CP Optimizer supports both reading and writing models in the CPO file format. In particular, it is possible to build a model using any supported language or interface such as C++, Java™, C# or OPL and then, instead of solving the model, write it into a "CPO file". This file can be read into another instance of CP Optimizer using the appropriate APIs (possibly on another machine) and solved there. It is possible to write CPO files manually or to generate them programmatically. CPO files are particularly useful for debugging, since one can exactly see the model being solved by the engine, which is more difficult to do when examining source code or OPL models.

CPO file format compared to OPL

The main difference between the CPO file format and OPL is that the CPO file format is used for representing instantiated models: that is, models which already have their data incorporated. By comparison, OPL models generally separate models and data. The CPO file format is also much simpler than the OPL language. There are no user-defined data structures, no scripting, no forall constructs, no database connections and so on.

Although a CPO file tends to be larger than an equivalent model and data files in OPL, CP Optimizer is able to read even large files quickly, which means that CPO files may be a viable option for modeling and solving in two different spaces (languages or machines for example).

Example

Let's start with a simple example. The model below finds a coloring of a map with six countries such that no two neighboring countries have the same color. Up to four colors are allowed.


// Decision variables:
Belgium = intVar(1..4);
Denmark = intVar(1..4);
France = intVar(1..4);
Germany = intVar(1..4);
Luxembourg = intVar(1..4);
Netherlands = intVar(1..4);

/* Constraints: */
Belgium != France;
Belgium != Germany;
Belgium != Netherlands;
Belgium != Luxembourg;
Denmark != Germany;
France != Germany;
France != Luxembourg;
Germany != Luxembourg;
Germany != Netherlands;

parameters {
  SearchType = DepthFirst;
}

There are six integer decision variables (Belgium, Denmark, France, Germany, Luxembourg and Netherlands) with possible values {1, 2, 3, 4}. For every pair of neighboring countries there is a constraint that their color is different (e.g. Belgium != France). Finally, there is section parameters where the parameter SearchType is set to DepthFirst.