Gurobi Tutorial - C++ API Overview

C++ API overview

  This section introduces the Gurobi C++ interface. This manual begins with a brief overview of the classes exposed in the interface and the most important methods in these classes. It then continues with a comprehensive introduction to all available classes and methods.

  If you are new to Gurobi Optimizer, we recommend starting with the Quick Start Guide or the sample tutorials. These documents provide specific examples of how to use the classes and methods described here.

EnvironmentEnvironments

  The first step in using the Gurobi C++ interface is to create an environment object. Use the GRBEnv class to represent the environment. An environment acts as a container for all data related to a set of optimization runs. You usually only need one environment object in your program.

  For more advanced use cases, you can create an uninitialized environment with an empty environment and then programmatically set all the required options for your specific requirements. See the Environment section for details.

Models

  You can create one or more optimization models in the environment. Each model is represented as an object of the GRBModel class. A model consists of a set of decision variables (objects of class GRBVar), linear or quadratic objective functions for these variables (specified using GRBModel::setObjective), and a set of constraints on these variables (objects of class GRBConstr, GRBQConstr, GRBSOS, or GRBGenConstr) . Each variable has an associated lower limit, upper limit, and type (continuous, binary, etc.). Each linear or quadratic constraint has an associated meaning (less than or equal to, greater than or equal to, or equal to) and a right-hand side value. See this section for more information about variables, constraints, and goals.

  Linear constraints are specified by constructing linear expressions (objects of class GRBLinExpr) and then specifying relationships between these expressions (for example, requiring one expression to be equal to another). Quadratic constraints are constructed in a similar way, but using quadratic expressions (objects of class GRBQuadExpr).

  You can specify an optimization model by loading it all at once from a file (using the appropriate GRBModel constructor), or add additional variables by first constructing an empty object of the GRBModel class and then calling GRBModel::addVar or GRBModel::addVars, GRBModel::addConstr, GRBModel: :addQConstr, GRBModel::addSOS or any GRBModel::addGenConstrXxx method to add constraints. Models are dynamic entities; you can always add or remove variables or constraints.

  We often refer to classes that optimize models. A model with a linear objective function, linear constraints, and continuous variables is a linear programming (LP). If the objective is quadratic, the model is quadratic programming (QP). If any constraints are quadratic, the model is a quadratic constraint procedure (QCP). We sometimes mention some special cases of QCP: QCP with convex constraints, QCP with non-convex constraints, bilinear programming, and second-order cone programming (SOCP). A model is a mixed integer program (MIP) if it contains any integer variables, semicontinuous variables, semiinteger variables, special ordered set (SOS) constraints, or general constraints. We also sometimes discuss special cases of MIP, including mixed integer linear programming (MILP), mixed integer quadratic programming (MIQP), mixed integer quadratic constrained programming (MIQCP), and mixed integer second-order cone programming (MISOCP) . The Gurobi optimizer handles all these model classes.

Solving a Model Solving a Model

  After building the model, you can call GRBModel::optimize to calculate the solution. By default, optimize will use the concurrent optimizer to solve LP models, the barrier algorithm to solve QP models with convex objectives and QCP models with convex constraints, and otherwise use the branch-and-cut algorithm. The solution is stored in a set of properties of the model. These properties can be queried using a set of property query methods on the GRBModel, GRBVar, GRBConstr, GRBQConstr, GRBSOS, and GRBGenConstr classes.

  The Gurobi algorithm carefully tracks the state of the model, so calls to GRBModel::optimize will only perform further optimization if relevant data has changed since the model was last optimized. If you want to discard previously calculated solution information and start optimization from scratch without changing the model, you can call GRBModel::reset.

  After solving the MIP model, you can call GRBModel::fixedModel to calculate the associated fixed model. This model is identical to the original model, except that the integer variables are fixed to their values ​​in the MIP solution. If your model contains SOS constraints, some of the continuous variables appearing in these constraints may also be fixed. In some applications, it may be useful to compute information about this fixed model (e.g., dual variables, sensitivity information, etc.), although you should be careful how you interpret this information.

Multiple Solutions, Objectives, and Scenarios

  By default, the Gurobi optimizer assumes that your goal is to find a proven optimal solution for a single model with a single objective function. Gurobi provides the following features that allow you to relax these assumptions:

  • Solution Pool: Allows you to find more solutions.
  • Multiple Scenarios: Allows you to find solutions for multiple related models.
  • Multiple Objectives: Allows you to specify multiple objective functions and control the trade-offs between them.

Infeasible Models

  If you find that your model is not feasible, you have several options. You can try to diagnose the cause of the inoperability, try to fix the inoperability, or both. To obtain information that can be used to diagnose the cause of infeasibility, call GRBModel::computeIIS to compute the irreducibly inconsistent subsystem (IIS). This method can be used with both continuous and MIP models, but you should be aware that the MIP version can be very expensive. This method populates a set of IIS properties.

  To attempt to fix infeasibility, call GRBModel::feasRelax to compute the model's feasibility relaxation. This relaxation allows you to find a solution that minimizes the magnitude of the constraint violation.

Querying and Modifying AttributesQuerying and Modifying Attributes

  Most of the information related to Gurobi models is stored in a set of properties. Some properties are associated with the variables of the model, some with the constraints of the model, and some with the model itself. As a simple example, solving an optimization model will cause the X variable attribute to be populated. Properties such as X calculated by the Gurobi optimizer cannot be modified directly by the user, while other properties such as the variable lower bound (LB property) can.

  Use GRBVar::get, GRBConstr::get, GRBQConstr::get, GRBSOS::get, GRBGenConstr::get or GRBModel::get to query attributes, and use GRBVar::set, GRBConstr::set, GRBQConstr to modify: : set, GRBGenConstr::set or GRBModel::set. Attributes are grouped by type into a set of enumerations (GRB_CharAttr, GRB_DoubleAttr, GRB_IntAttr, GRB_StringAttr). The get() and set() methods are overloaded, so the type of the property determines the type of the return value. Therefore, constr.get(GRB.DoubleAttr.RHS) returns a double, while constr.get(GRB.CharAttr.Sense) returns a character.

  If you wish to retrieve the property values ​​of a set of variables or constraints, it is usually more efficient to use the array methods on the associated GRBModel object. The method GRBModel::get includes a signature that allows you to query or modify the property values ​​of a variable or constraint array.

A complete list of properties can be found in the properties section Additional Model Modification Information

  Most modifications to existing models are done through the property interface (e.g., changing variable bounds, right-hand side of constraints, etc.). The main exceptions are modifications to the constraint matrix and objective function.

  The constraint matrix can be modified in several ways. The first is to call the chgCoeffs method on the GRBModel object to change individual matrix coefficients. This method can be used to modify an existing non-zero value, set an existing non-zero value to zero, or create a new non-zero value. When you remove variables or constraints from the model (via the GRBModel::remove method), the constraint matrix is ​​also modified. Nonzero values ​​associated with a deleted constraint or variable are deleted along with the constraint or variable itself.

  The model objective function can also be modified in several ways. The simplest method is to construct an expression (GRBLinExpr or GRBQuadExpr object) that captures the target function, and then pass the expression to the method GRBModel::setObjective. If you want to modify the target, you can simply call setObjective again with a new GRBLinExpr or GRBQuadExpr object.

  For linear objective functions, an alternative to setObjective is to use the Obj variable property to modify the individual linear objective coefficients.

  If your variables have piecewise linear objectives, you can specify them using the GRBModel::setPWLObj method. This method is called once for each relevant variable. The Gurobi simplex solver includes algorithmic support for convex piecewise linear objective functions, so for continuous models you should see significant performance improvements using this feature. To clear a previously specified piecewise linear objective function, simply set the Obj property of the corresponding variable to 0.

Lazy Updates Lazy Updates

  An important thing to note about model modifications in the Gurobi optimizer is that it is performed in a lazy manner, meaning modifications do not affect the model immediately. Instead, they are queued and applied later. If your program simply creates a model and solves it, you may never notice this behavior. However, the details of the delayed update method may be relevant to you if you are asking about information about the model before applying the modifications.

  As we just mentioned, model modifications (binding changes, right-side changes, target changes, etc.) are placed in a queue. These queued modifications can be applied to the model in three different ways. The first is by explicitly calling GRBModel::update. The second is to call GRBModel::optimize. The third one is to call GRBModel::write to write out the model. The first case gives you fine-grained control over when modifications are applied. The second and third assume that you want to apply all pending modifications before optimizing the model or writing it to disk.

  Why does the Gurobi interface behave this way? There are several reasons. The first is that this approach makes it easier to perform multiple modifications to the model, since the model remains unchanged between modifications. The second is that handling model modifications can be expensive, especially in a compute server environment where modifications require communication between machines. Therefore, it is useful to know exactly when to apply these modifications. Generally speaking, if your program requires multiple modifications to the model, you should do it in stages, where you make a set of modifications, then update, then make more modifications, then update again, and so on. Updating modifications after everyone can be very expensive.

  Your program won't crash if you forget to call update. Your query will only return the value of the data requested when it was last updated. If the object you are trying to query does not exist, you will get a NOT_IN_MODEL exception.

  The semantics of deferred updates have changed since early Gurobi versions. Although the vast majority of programs are not affected by this change, if you encounter problems, you can use the UpdateMode parameter to revert to earlier behavior.

Managing ParametersManaging Parameters

  The Gurobi optimizer provides a set of parameters that allow you to control many details of the optimization process. Factors such as feasibility and optimality tolerances, algorithm selection, and strategies for exploring the MIP search tree can be controlled by modifying the Gurobi parameters before starting the optimization. The parameter type can be int, double or string.

  The simplest way to set parameters is through the GRBModel::set method on the model object. Similarly, parameter values ​​can be queried using GRBModel::get.

  You can also use GRBEnv::set to set parameters on the Gurobi environment object. Note that each model gets its own copy of the environment when created, so parameter changes to the original environment have no impact on existing models.

  You can use GRBEnv::readParams to read a set of parameter settings from a file, or use GRBEnv::writeParams to write a set of changed parameters.

  We also include an automatic parameter tuning tool that explores many different sets of parameter changes to find the set that improves performance. You can call GRBModel::tune to invoke tuning tools on the model. See the Parameter Tuning Tools section for details.

  The complete list of Gurobi parameters can be found in the Parameters section.

Memory ManagementMemory Management

  Memory management must always be considered in C++ programs. In particular, the Gurobi library and user programs share the same C++ heap, so users must understand some aspects of how the Gurobi library uses the heap. The basic rules for managing memory when using the Gurobi optimizer are as follows:

  • Like other dynamically allocated C++ objects, a GRBEnv or GRBModel object should be released using the associated destructor. In other words, given a GRBModel object m, you should call delete m when you no longer use m.
  • Objects associated with the model, such as GRBConstr, GRBQConstr, GRBSOS, GRBGenConstr, and GRBVar objects, are managed by the model. In particular, deleting a model will delete all associated objects. Likewise, removing an object from the model (using GRBModel::remove) also deletes the object.
  • Some Gurobi methods return an object or array of values. For example, GRBModel::addVars returns an array of GRBVar objects. It is the user's responsibility to free the returned array (use delete[]). The reference manual indicates when a method returns a heap-allocated result.

  One consequence of these rules is that you must be careful not to use an object once it has been freed. This is certainly very clear for environments and models where the destructor is called explicitly, but perhaps less clear for constraints and variables, as they are implicitly deleted when the associated model is deleted.

Monitoring Progress - Logging and CallbacksMonitoring Progress - Logging and Callbacks

  The progress of optimization can be recorded through Gurobi logs. By default, Gurobi sends output to the screen. Some simple controls are available to modify the default logging behavior. If you want to direct output to a file as well as the screen, specify the log file name in the GRBEnv constructor. If you want to redirect the logs to a different file after creating the environment object, you can modify the LogFile parameter. You can use the DisplayInterval parameter to control how often output is logged, and you can use the OutputFlag parameter to turn off logging entirely. A detailed description of Gurobi log files can be found in the Logs section.

  More detailed progress monitoring can be accomplished through the GRBCallback class. The GRBModel::setCallback method allows you to receive periodic callbacks from the Gurobi optimizer. To do this, you can subclass the GRBCallback abstract class and write your own callback() method on the class. You can call GRBCallback::getDoubleInfo, GRBCallback::getIntInfo, GRBCallback::getStringInfo, or GRBCallback::getSolution in the callback to get additional information about the optimization status.

Modifying Solver Behavior - Callbacks Modifying Solver Behavior - Callbacks

  Callbacks can also be used to modify the behavior of the Gurobi optimizer. The simplest control callback is GRBCallback::abort, which requires the optimizer to terminate at the earliest convenient point. The method GRBCallback::setSolution allows you to inject a feasible solution (or partial solution) during the solution of the MIP model. The methods GRBCallback::addCut and GRBCallback::addLazy allow you to add cutting planes and lazy constraints respectively during MIP optimization. The method GRBCallback::stopOneMultiObj allows you to interrupt the optimization process of one of the optimization steps in a multi-objective MIP problem without stopping the hierarchical optimization process.

Batch Optimization

  Gurobi Compute Server enables programs to offload optimization calculations to dedicated servers. Gurobi Cluster Manager builds on this foundation and adds many additional features. An important, batch optimization, allows you to use your client program to build an optimization model, submit it to a cluster of compute servers (via the cluster manager), and then check the status of the model and retrieve its solution. You can use the Batch object to process batches more easily. For more information about batches, see the Batch Optimization section.

Error Handling

  All methods in the Gurobi C++ library can throw exceptions of type GRBException. When an exception occurs, you can obtain additional information about the error by retrieving the error code (using the method GRBException::getErrorCode) or retrieving the exception message (using the method GRBException::getMessage). A list of possible error return codes can be found in the Error Codes section.

Guess you like

Origin blog.csdn.net/qq_16775293/article/details/122707172