coin-or / Clp

COIN-OR Linear Programming Solver
Other
396 stars 82 forks source link

Refactoring Clp #166

Closed tkralphs closed 2 years ago

tkralphs commented 3 years ago

Although the task list is incomplete, we plan to merge what has been done so far on this long-standing PR on 1/1/2022 in order to encourage broader review and comment from the community (See #219). Work will continue following the merge, but in a separate PR. More details will be provided in an accompanying announcement, which will be linked here once it's made.

Clp is is currently undergoing a major refactoring. Importantly, this refactoring is not expected to affect the performance of the code in any way. The goals only regard improving readability, maintainability, and usability.

This pull request is mainly for the purposes of documenting the changes being made so that other maintainers can review and follow along. It is also a task list that anyone who wants to contribute can consult to see what needs to be done.

See also: coin-or/CoinUtils#139

Here are some of the main goals of this refactoring.

Here is the task list, including what has already been done.

Things to consider

Some details about particular aspects of what has already been done.

Parameter mechanism

There are two main classes and some utilities.

ClpParam

Each parameter has a unique code, which is also its index in the parameter vector stored in the ClpParameters class (described below). The codes are specified in the ClpParamCode enum within the ClpParam class.

Parameters also have a type, which can be queried and is one of

There are different constructors for each type, as well as setup functions for populating an existing parameter object with

For keyword parameters, there is also a mechanism for creating a mapping between keyword value strings and the so-called "mode" value, which is an integer. The value of a keyword parameter can be set or retrieved either as a keyword string or as an integer mode. The modes may also be specified in enums.

There are separate get/set methods for each parameter type, but for convenience, there is also a single setVal() and getVal() method that is overloaded and can set the value of any parameter (the input/output is interpreted based on the known parameter type), e.g.,

param.setVal(0);

Each parameter object also has optional "push" (and "pull") function that can perform actions or populate related data structures upon the setting of a parameter value. The push/pull functions are defined with the ClpParamUtils name space, described below.

None of the methods in the class produce output directly. The get/set methods can optionally populate a string object that is passed in as an optional second argument. This is to allow the calling function to control output by piping the string to a message handler as appropriate or simply ignoring it if printing is not desired. This obviates the need to control printing internal to the functions themselves, which would require a separate parameter.

std::string message;
if (param->setKwdVal(value, &message)){
   messageHandler->message(CLP_GENERAL, generalMessages) << message << CoinMessageEol;
}

ClpParameters

The ClpParameters class serves primarily as a container for a vector of parameters, but can (and will) be used to store other auxiliary information that needs to be accessed by the methods of (soon-to-be) ClpSolver class. The class has methods for setting parameter values, which are pass-throughs to the methods of the ClpParam class. It also defines a [] operator, so that parameter objects contained in the parameter vector, which is a class member, can be directly accessed, e.g.,

  ClpParameters parameters;
  parameters[ClpParam::LOGLEVEL]->setVal(0);

The constructor of the class calls a method, which sets up all the parameters (as described above). It is envisioned that different constructors will eventually be used to obtain different sets of parameters for different purposes.

ClpParamUtils

There are a number of utilities contained in the ClpParamUtils namespace. Mostly, these are the push functions that can extend the functionality of the set methods of the ClpParam class.

Input/Output mechanism

The input/output mechanism is used to pass a sequence of parameters to Clp, including action parameters. This parameter sequence can be set equivalently passed in five different ways.

Regardless of the method, the parameter sequence is stored and accessed as a FIFO queue of strings (inputQueue). This can be passed as an input to what is currently ClpMain1 or constructed within the main while loop by parsing either interactive input, the contents of an environment variable, or the contents of a parameter file.

The main while loop then pops strings off the input queue, looks them up in the parameters list and deals with the result.

CLAassistant commented 3 years ago

CLA assistant check
All committers have signed the CLA.