Changeset 2473


Ignore:
Timestamp:
Jan 21, 2019 1:15:12 PM (4 weeks ago)
Author:
unxusr
Message:

initial (beta) support for cut callbacks in the CBC C API

Location:
trunk/Cbc
Files:
1 added
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Cbc/src/Cbc_C_Interface.cpp

    r2472 r2473  
    66#include <cmath>
    77#include <cfloat>
     8#include <cctype>
    89
    910#include "CoinPragma.hpp"
     
    1718#include "CoinMessageHandler.hpp"
    1819#include "OsiClpSolverInterface.hpp"
     20#include "CglCutGenerator.hpp"
    1921
    2022//  bobe including extras.h to get strdup()
     
    4244
    4345const int VERBOSE = 0;
     46
     47// cut generator to accept callbacks in CBC
     48//
     49class CglCallback : public CglCutGenerator
     50{
     51    public:
     52        CglCallback();
     53       
     54        cbc_cut_callback cut_callback_;
     55        void *appdata;
     56        //CbcModel *model;
     57
     58        /// Copy constructor
     59        CglCallback(const CglCallback& rhs);
     60
     61        /// Clone
     62        virtual CglCutGenerator * clone() const;
     63
     64        virtual void generateCuts( const OsiSolverInterface & si, OsiCuts & cs,
     65                const CglTreeInfo info = CglTreeInfo() );
     66
     67        virtual ~CglCallback();
     68    private:
     69};
     70
     71
     72CglCallback::CglCallback()
     73    : cut_callback_(NULL),
     74    appdata(NULL)
     75{
     76}
     77
     78CglCallback::CglCallback(const CglCallback& rhs)
     79{
     80    this->cut_callback_ = rhs.cut_callback_;
     81    this->appdata = rhs.appdata;
     82}
     83
     84CglCutGenerator* CglCallback::clone() const
     85{
     86    CglCallback *cglcb = new CglCallback();
     87    cglcb->cut_callback_ = this->cut_callback_;
     88    cglcb->appdata = this->appdata;
     89
     90    return static_cast<CglCutGenerator*>(cglcb);
     91}
     92
     93void CglCallback::generateCuts( const OsiSolverInterface &si, OsiCuts &cs, const CglTreeInfo info )
     94{
     95  this->cut_callback_( (OsiSolverInterface *) &si, &cs, this->appdata );
     96}
     97
     98CglCallback::~CglCallback()
     99{
     100
     101}
    44102
    45103// To allow call backs
     
    803861
    804862  return result;
     863}
     864
     865COINLIBAPI void COINLINKAGE Cbc_addCutCallback(
     866    Cbc_Model *model, cbc_cut_callback cutcb,
     867    const char *name, void *appData )
     868{
     869  assert( model != NULL );
     870  assert( model->model_ != NULL );
     871
     872  CbcModel *cbcModel = model->model_;
     873
     874  CglCallback cglCb;
     875  cglCb.appdata = appData;
     876  cglCb.cut_callback_ = cutcb;
     877
     878  cbcModel->addCutGenerator( &cglCb, 1, name );
    805879}
    806880
     
    14971571}
    14981572
     1573COINLIBAPI int COINLINKAGE
     1574Osi_getNumCols( void *osi )
     1575{
     1576  OsiSolverInterface *osiSolver = (OsiSolverInterface *) osi;
     1577  return osiSolver->getNumCols();
     1578}
     1579
     1580/** @brief Returns column name in OsiSolverInterface object */
     1581COINLIBAPI void COINLINKAGE
     1582Osi_getColName( void *osi, int i, char *name, int maxLen )
     1583{
     1584  OsiSolverInterface *osiSolver = (OsiSolverInterface *) osi;
     1585  strncpy( name, osiSolver->getColName(i).c_str(), maxLen );
     1586}
     1587
     1588/** @brief Returns column lower bounds in OsiSolverInterface object */
     1589COINLIBAPI const double * COINLINKAGE
     1590Osi_getColLower( void *osi )
     1591{
     1592  OsiSolverInterface *osiSolver = (OsiSolverInterface *) osi;
     1593  return osiSolver->getColLower();
     1594}
     1595
     1596/** @brief Returns column upper bounds in OsiSolverInterface object */
     1597COINLIBAPI const double * COINLINKAGE
     1598Osi_getColUpper( void *osi )
     1599{
     1600  OsiSolverInterface *osiSolver = (OsiSolverInterface *) osi;
     1601  return osiSolver->getColUpper();
     1602}
     1603
     1604/** @brief Returns integrality information for columns in OsiSolverInterface object */
     1605COINLIBAPI int COINLINKAGE
     1606Osi_isInteger( void *osi, int col )
     1607{
     1608  OsiSolverInterface *osiSolver = (OsiSolverInterface *) osi;
     1609  return osiSolver->isInteger(col);
     1610}
     1611
     1612/** @brief Returns number of rows in OsiSolverInterface object */
     1613COINLIBAPI int COINLINKAGE
     1614Osi_getNumRows( void *osi )
     1615{
     1616  OsiSolverInterface *osiSolver = (OsiSolverInterface *) osi;
     1617  return osiSolver->getNumRows();
     1618}
     1619
     1620COINLIBAPI int COINLINKAGE
     1621Osi_getRowNz(void *osi, int row)
     1622{
     1623  OsiSolverInterface *osiSolver = (OsiSolverInterface *) osi;
     1624
     1625  const CoinPackedMatrix *cpmRow = osiSolver->getMatrixByRow();
     1626  return cpmRow->getVectorLengths()[row];
     1627}
     1628
     1629/** @brief Indices of variables that appear on a row */
     1630COINLIBAPI const int *COINLINKAGE
     1631Osi_getRowIndices(void *osi, int row)
     1632{
     1633  OsiSolverInterface *osiSolver = (OsiSolverInterface *) osi;
     1634
     1635  const CoinPackedMatrix *cpmRow = osiSolver->getMatrixByRow();
     1636  const CoinBigIndex *starts = cpmRow->getVectorStarts();
     1637  const int *ridx = cpmRow->getIndices() + starts[row];
     1638  return ridx;
     1639}
     1640
     1641/** @brief Coefficients of variables that appear on this row  */
     1642COINLIBAPI const double *COINLINKAGE
     1643Osi_getRowCoeffs(void *osi, int row)
     1644{
     1645  OsiSolverInterface *osiSolver = (OsiSolverInterface *) osi;
     1646
     1647  const CoinPackedMatrix *cpmRow = osiSolver->getMatrixByRow();
     1648  const CoinBigIndex *starts = cpmRow->getVectorStarts();
     1649  const double *rcoef = cpmRow->getElements() + starts[row];
     1650  return rcoef;
     1651}
     1652
     1653/** @brief Right hand side of a row  */
     1654COINLIBAPI double COINLINKAGE
     1655Osi_getRowRHS(void *osi, int row)
     1656{
     1657  OsiSolverInterface *osiSolver = (OsiSolverInterface *) osi;
     1658  return osiSolver->getRightHandSide()[row];
     1659}
     1660
     1661/** @brief Sense a row
     1662     * @param model problem object
     1663     * @param row row index
     1664     * @return row sense: E for =, L for <=, G for >= and R for ranged row
     1665     **/
     1666COINLIBAPI char COINLINKAGE
     1667Osi_getRowSense(void *osi, int row)
     1668{
     1669  OsiSolverInterface *osiSolver = (OsiSolverInterface *) osi;
     1670
     1671  return osiSolver->getRowSense()[row];
     1672}
     1673
     1674/** @brief Returns solution vector in OsiSolverInterface object */
     1675COINLIBAPI const double * COINLINKAGE
     1676Osi_getColSolution( void *osi )
     1677{
     1678  OsiSolverInterface *osiSolver = (OsiSolverInterface *) osi;
     1679
     1680  return osiSolver->getColSolution();
     1681}
     1682
     1683COINLIBAPI void COINLINKAGE
     1684OsiCuts_addRowCut( void *osiCuts, int nz, const int idx[], const double coef[], char sense, double rhs )
     1685{
     1686  sense = toupper(sense);
     1687  OsiCuts *oc = (OsiCuts *) osiCuts;
     1688
     1689  OsiRowCut orc;
     1690  orc.setRow( nz, idx, coef );
     1691
     1692  switch (sense)
     1693  {
     1694    case 'L':
     1695    {
     1696      orc.setLb(-COIN_DBL_MAX);
     1697      orc.setUb(rhs);
     1698      break;
     1699    }
     1700    case 'G':
     1701    {
     1702      orc.setLb(rhs);
     1703      orc.setUb(COIN_DBL_MAX);
     1704      break;
     1705    }
     1706    case 'E':
     1707    {
     1708      orc.setLb(rhs);
     1709      orc.setUb(rhs);
     1710      break;
     1711    }
     1712    default:
     1713    {
     1714      fprintf( stderr, "sense not recognized\n" );
     1715      abort();
     1716    }
     1717  }
     1718
     1719  oc->insert(orc);
     1720}
     1721
    14991722#if defined(__MWERKS__)
    15001723#pragma export off
  • trunk/Cbc/src/Cbc_C_Interface.h

    r2465 r2473  
    432432Cbc_isInteger(Cbc_Model *model, int i);
    433433
     434
    434435//@}
    435436
     
    521522Cbc_registerCallBack(Cbc_Model *model,
    522523  cbc_callback userCallBack);
     524
    523525/** Unset Callback function */
    524526COINLIBAPI void COINLINKAGE
    525527Cbc_clearCallBack(Cbc_Model *model);
     528
     529COINLIBAPI void COINLINKAGE Cbc_addCutCallback(
     530    Cbc_Model *model, cbc_cut_callback cutcb,
     531    const char *name, void *appData );
    526532
    527533/*@}*/
     
    545551COINLIBAPI const double *COINLINKAGE
    546552Cbc_getColSolution(Cbc_Model *model);
     553
    547554
    548555/** @brief Best known bound on the optimal objective value
     
    727734
    728735/*@}*/
     736
     737/** \name OsiSolverInterface related routines (used in callbacks) */
     738//@{
     739
     740/** @brief Returns number of cols in OsiSolverInterface object */
     741COINLIBAPI int COINLINKAGE
     742Osi_getNumCols( void *osi );
     743
     744/** @brief Returns column name in OsiSolverInterface object */
     745COINLIBAPI void COINLINKAGE
     746Osi_getColName( void *osi, int i, char *name, int maxLen );
     747
     748/** @brief Returns column lower bounds in OsiSolverInterface object */
     749COINLIBAPI const double * COINLINKAGE
     750Osi_getColLower( void *osi );
     751
     752/** @brief Returns column upper bounds in OsiSolverInterface object */
     753COINLIBAPI const double * COINLINKAGE
     754Osi_getColUpper( void *osi );
     755
     756/** @brief Returns integrality information for columns in OsiSolverInterface object */
     757COINLIBAPI int COINLINKAGE
     758Osi_isInteger( void *osi, int col );
     759
     760/** @brief Returns number of rows in OsiSolverInterface object */
     761COINLIBAPI int COINLINKAGE
     762Osi_getNumRows( void *osi );
     763
     764COINLIBAPI int COINLINKAGE
     765Osi_getRowNz(void *osi, int row);
     766
     767/** @brief Indices of variables that appear on a row */
     768COINLIBAPI const int *COINLINKAGE
     769Osi_getRowIndices(void *osi, int row);
     770
     771/** @brief Coefficients of variables that appear on this row
     772     *
     773     * @param model problem object
     774     * @param row row index
     775     * @return coefficients of variables that appear on this row
     776     **/
     777COINLIBAPI const double *COINLINKAGE
     778Osi_getRowCoeffs(void *osi, int row);
     779
     780/** @brief Right hand side of a row
     781     *
     782     * @param model problem object
     783     * @param row row index
     784     * @return row right hand side
     785     **/
     786COINLIBAPI double COINLINKAGE
     787Osi_getRowRHS(void *osi, int row);
     788
     789/** @brief Sense a row
     790     * @param model problem object
     791     * @param row row index
     792     * @return row sense: E for =, L for <=, G for >= and R for ranged row
     793     **/
     794COINLIBAPI char COINLINKAGE
     795Osi_getRowSense(void *osi, int row);
     796
     797/** @brief Returns solution vector in OsiSolverInterface object */
     798COINLIBAPI const double * COINLINKAGE
     799Osi_getColSolution( void *osi );
     800
     801/*@}*/
     802
     803/** \name OsiCuts related routines (used in callbacks) */
     804//@{
     805
     806COINLIBAPI void COINLINKAGE
     807OsiCuts_addRowCut( void *osiCuts, int nz, const int idx[], const double coef[], char sense, double rhs );
     808
     809
     810/*@}*/
     811
    729812#ifdef __cplusplus
    730813}
Note: See TracChangeset for help on using the changeset viewer.