|
Overview
This is an example of using SCIP to solve the TSP problem on undirected graphs. Here is the CIP model that we use: Given: a graph Variables: Constraints:
Semantics of constraints:
A few remarks to the model and the implementation (references to code lines might not be up to date): As one can see, the TSP-Model consists of SCIP_CALL( SCIPcreateVar(scip, &var, varname.str().c_str(), 0.0, 1.0, edge->length, SCIP_VARTYPE_BINARY, TRUE, FALSE, NULL, NULL, NULL, NULL, NULL) ); SCIP_CALL( SCIPaddVar(scip, var) ); SCIP_CALL( addVarToEdges(scip, edge, var) ); A pointer to each variable is stored in the data structure of the corresponding edge (i.e., in SCIP_CALL( SCIPcreateConsLinear(scip, &cons, consname.str().c_str(), 0, NULL, NULL, 2.0, 2.0, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE) ); The data for the linear degree constraints are the coefficients (for each FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE ) ); Now the problem instance is defined, and the "only" thing left is to implement the semantics of the "subtour" constraint. This is of course done in the subtour constraint handler ConshdlrSubtour.cpp. The main task of a constraint handler is to decide whether a given solution is feasible for all constraints of the constraint handler's type (i.e., for example, for all linear constraint in the instance, for all knapsack constraints in the instance, for all subtour constraints in the instance, ...). This is performed in the scip_enfolp(), scip_enfops(), and scip_check() methods. To implement these three methods and the scip_lock() method (called the "fundamental callback methods" in the SCIP documentation) is already enough to obtain a correct algorithm, which means that the solver will find (after waiting long enough) the optimal solution. The remaining methods are only needed to speed up the solving process (for example, cutting plane separation and domain propagation). As there is only one subtour constraint in a TSP instance, all the loops for( int i = 0; i < nconss; ++i ) ... in ConshdlrSubtour.cpp are a bit ridiculous, since Additionally, this example contains two well known combinatorial heuristics for the TSP, namely a farthest insert heuristic and a 2-opt heuristic, and a rounding heuristic for TSPs. The idea of the latter one is to take an LP solution and construct a hamiltonian cycle in the following way: If |