MibS Quick Start
Versions
MibS
uses semantic versioning (major.minor.patch). There are three major
versions of MibS
currently under development.
- Versions with major number 1 are recommended for most users. This is the original solver, which is focused on solution of deterministic mixed integer bilevel linear optimization problems (MIBLPs). The latest minor version in this series is 1.2 and the most recent release is .
- The version in the master branch will become major version 2 and can additionally solve stochastic MIBLPs. Once released, this version will subsume all capabilities of version 1 and version 1 will be deprecated. It has not yet had a release, but is well tested.
- There is also a major verion 3 of
MibS
under development that incorporates the ability to solve MIBLPs under the assumption of bounded rationality.
Building and Installing
For information on building and installing MibS
on different platforms, see
the README for the appropriate version, e.g.,
here
(procedure is similar for all versions), or the more detailed COIN-OR User
Guide.
Using
To understand how to use MibS
, it helps to know that MibS
is built on top of
the BLIS MILP solver, which is in
turn implemented using the (COIN-OR High-Performance Parallel Search (CHiPPS)
Framework and more specifically with the [Abstract Library for Parallel Search
ALPS, a library of abstract base
classes for implementing parallel search algorithms. You can find a detailed
description of the algorithms and the important parameters of major version 1
of MibS
here.
Modelling Systems
MibS has interfaces to the following modelling systems that allow the user to conveniently build the bilevel model in a high-level modelling language and pass the model to MibS through the interface for solution.
- Pyomo (Python) through the PAO package, see here
- JuMP (Julia) through the BilevelJuMP package, see here for an example.
Basic Command-line Usage
The command-line interface on all platforms consists of the executable name mibs
followed by a list of pairs of parameters and values. Parameter names should always be preceded
by a -
. Some of the parameters are MibS
parameters, but parameters of ALPS and BLIS may also
be necessary.
Version 1
To solve a deterministic mixed integer bilevel linear optimization problem
with MibS
version 1, you must provide both an MPS, LP, or GMPL/AMPL file and
an auxiliary information file that specifies which variables and constraints
are associated with the each level (see here). Then call mibs
like this:
mibs -instance file.mps -auxiliaryInfoFile file.aux
Note that specifying the name and location of the auxiliary is unnecessary if it has the same base name and is in the same folder.
MibS
has many additional parameters, many of which are documented
here. See the example parameter file
mibs.par
and the
header file MibParams.hpp
for additional information. It is also possible to specify additional settings in a parameter file with, e.g.,
mibs -param MibS/src/mibs.par
Version 2
Major version 2 ofMibS
is additionally capable of solving two-stage mixed
integer stochastic bilevel linear optimization problems. There are two
different ways to specify such problems to MibS
.
- Provide an MPS file, a time file and a stoch file in the same way as the
SMPS
format. The second-stage objective coefficients should be defined at the
end of the time file (see
here).
For this instance format, call
mibs
like this:dist/bin/mibs -Alps_instance file.mps -MibS_auxiliaryTimFile file.tim -MibS_auxiliaryStoFile file.sto -MibS_stochasticityType stochasticWithoutSAA -MibS_isSMPSFormat 1 -MibS_isA2Random 1
The parameter
MibS_isA2Random
should be set to 0 in case the coefficients of the first-stage variables in the second-stage problem are not random variables. - Provide an MPS file and an auxiliary information file in the same way as
deterministic bilevel problems. In this case, the probability
distributions of the random variables must also be specified by setting
the values of corresponding parameters (
MibS
currently supports only the discrete uniform distribution). For a sample parameter file, see [https://github.com/coin-or/MibS/blob/master/src/mibsStochastic.par.in].
The C++ API
Major versions 1 and 2 both have a C++ class library that can be used to link
to the MibS from another application. The main class user interact with is the
MibSModel
class. Below is a short code snippet showing how to pass instance
data to MibS in memory from another application. As described above, MibS is
ultimately built on the abstract base classes of
ALPS and hence the solve call is
actually invoked by calling the search
method of the AlpsKnowledgeBroker
object. (In the future, we plan to wrap all of this in order to make
invocation simpler to understand).
#include <iostream>
#include "OsiSolverInterface.hpp"
#include "OsiClpSolverInterface.hpp"
#include "MibSConfig.hpp"
#include "MibSModel.hpp"
#include "AlpsKnowledgeBrokerSerial.h"
int main(int argc, char* argv[])
{
/** Set up lp solver **/
OsiClpSolverInterface lpSolver;
lpSolver.messageHandler()->setLogLevel(0);
/** Create MibS model **/
MibSModel model;
model.setSolver(&lpSolver);
/****************************************************************/
/* */
/* Add code here that fills in the data structures needed for */
/* the functions below. */
/* */
/****************************************************************/
/* The auxiliary data describes which rows and variables in the */
/* upper level and which are in the lower level, as well as */
/* specifying the lower-level objective function */
model.loadAuxiliaryData(lowerColNum, lowerRowNum, lowerColInd,
lowerRowInd, 1.0, lObjCoeff,
upperColNum, upperRowNum, upperColInd,
upperRowInd, structRowNum, structRowInd,
0, NULL, lColLbInLProb, lColUbInLProb);
/* The problem data itself is passed in as a CoinPackedMatrix, */
/* vectors of upper and lower bounds, etc., as usual for an */
/* MILP solver */
model.loadProblemData(*newMatrix, varLB, varUB, objCoef, conLB,
conUB, colType, 1, mps->getInfinity(),
rowSense);
int argc = 1;
char** argv = new char* [1];
argv[0] = "mibs";
/* Create the knowledge broker to do the actual search. argc */
/* argv are passed in to parse the arguments */
AlpsKnowledgeBrokerSerial broker(argc, argv, model);
/** This is the function that does the solve **/
broker.search(model);
/** Get the solution **/
if (model->getNumSolutions() == 0){
std::cout << "MibS did not find any bilevel feasible solutions. "
<< std::endl;
abort();
}
MibSSolution *solution = dynamic_cast<MibSSolution* >
(broker.getBestKnowledge(AlpsKnowledgeTypeSolution).first);
double *y = new double[upperColNum];
for (j = lowerColNum; j < numTotalCols; j++){
y[j - lowerColNum] = floor(solution->getValues()[j] + 0.5);
}
}
There are also function in MibSModel
for directly parsing MPS/LP/AMPL/GMPL
files, as well as axiliary files if thoe are to be read directly. See
MibSModel.hpp.