Skip to content

Commit

Permalink
Merge pull request #236 from a-andre/pointer_array
Browse files Browse the repository at this point in the history
Replace some pointer arrays by std::vector
  • Loading branch information
tkralphs authored Aug 18, 2024
2 parents ecfbe38 + 268c142 commit 4b930fe
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 185 deletions.
84 changes: 19 additions & 65 deletions src/CoinCutPool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,6 @@

#define CUTPOOL_EPS 1e-8

static void *xmalloc( const size_t size );
static void *xrealloc( void *ptr, const size_t size );
static void *xcalloc( const size_t elements, const size_t size );

struct CompareIdxs {
explicit CompareIdxs(const int *idxs) { this->idxs_ = idxs; }

Expand All @@ -48,17 +44,16 @@ struct CompareIdxs {
const int *idxs_;
};

CoinCut::CoinCut(const int *idxs, const double *coefs, int nz, double rhs) {
nz_ = nz;
rhs_ = rhs;
idxs_ = (int*)xmalloc(sizeof(int) * nz_);
coefs_ = (double*)xmalloc(sizeof(double) * nz_);

CoinCut::CoinCut(const int *idxs, const double *coefs, size_t nz, double rhs)
: idxs_(std::vector<int>(nz))
, coefs_(std::vector<double>(nz))
, rhs_(rhs)
{
for (size_t i = 0; i < nz; i++) {
idxs_[i] = i;
}

std::sort(idxs_, idxs_ + nz_, CompareIdxs(idxs));
std::sort(idxs_.begin(), idxs_.end(), CompareIdxs(idxs));

for (size_t i = 0; i < nz; i++) {
const int pos = idxs_[i];
Expand All @@ -67,14 +62,11 @@ CoinCut::CoinCut(const int *idxs, const double *coefs, int nz, double rhs) {
}

#ifdef DEBUGCG
assert(std::is_sorted(idxs_, idxs_ + nz_));
assert(std::is_sorted(idxs_.begin(), idxs_.end()));
#endif
}

CoinCut::~CoinCut() {
free(idxs_);
free(coefs_);
}
CoinCut::~CoinCut() {}

int binarySearch(const int *v, const int n, const int x) {
int mid, left = 0, right = n - 1;
Expand All @@ -93,7 +85,7 @@ int binarySearch(const int *v, const int n, const int x) {
return -1;
}

bool CoinCut::dominates(const CoinCut *other, bool *iv) const {
bool CoinCut::dominates(const CoinCut *other) const {
/* thisRHS == 0 && otherRHS < 0 */
if (fabs(this->rhs()) <= CUTPOOL_EPS && other->rhs() <= -CUTPOOL_EPS) {
return false;
Expand All @@ -110,7 +102,7 @@ bool CoinCut::dominates(const CoinCut *other, bool *iv) const {
const double rhsA = this->rhs(), rhsB = other->rhs();
double normConstA, normConstB;

std::fill(iv, iv + sizeB, false);
std::vector<bool> iv(sizeB, false);

if (fabs(rhsA) <= CUTPOOL_EPS) {
normConstA = 1.0;
Expand Down Expand Up @@ -159,30 +151,21 @@ bool CoinCut::dominates(const CoinCut *other, bool *iv) const {

CoinCutPool::CoinCutPool(const double *x, int numCols) {
x_ = x;
nCols_ = numCols;
nullCuts_ = 0;

bestCutByCol_ = (size_t*)xmalloc(sizeof(size_t) * nCols_);
std::fill(bestCutByCol_, bestCutByCol_ + nCols_, -1);
bestCutByCol_ = std::vector<int>(numCols, -1);

nCuts_ = 0;
cutsCap_ = 1024;
cuts_ = (CoinCut**)xmalloc(sizeof(CoinCut*) * cutsCap_);
cutFrequency_ = (size_t*)xmalloc(sizeof(size_t) * cutsCap_);
cutFitness_ = (double*)xmalloc(sizeof(double) * cutsCap_);
iv_ = (bool*)xmalloc(sizeof(iv_) * nCols_);
cuts_ = std::vector<CoinCut*>(cutsCap_);
cutFrequency_ = std::vector<size_t>(cutsCap_);
cutFitness_ = std::vector<double>(cutsCap_);
}

CoinCutPool::~CoinCutPool() {
for (size_t i = 0; i < nCuts_; i++) {
delete cuts_[i];
}

free(bestCutByCol_);
free(cuts_);
free(cutFrequency_);
free(cutFitness_);
free(iv_);
}

bool CoinCutPool::add(const int *idxs, const double *coefs, int nz, double rhs) {
Expand Down Expand Up @@ -277,9 +260,9 @@ void CoinCutPool::checkMemory() {
}

cutsCap_ *= 2;
cuts_ = (CoinCut**)xrealloc(cuts_, sizeof(CoinCut*) * cutsCap_);
cutFrequency_ = (size_t*)xrealloc(cutFrequency_, sizeof(size_t) * cutsCap_);
cutFitness_ = (double*)xrealloc(cutFitness_, sizeof(double) * cutsCap_);
cuts_.resize(cutsCap_);
cutFrequency_.resize(cutsCap_);
cutFitness_.resize(cutsCap_);
}

void CoinCutPool::removeDominated() {
Expand Down Expand Up @@ -333,12 +316,12 @@ int CoinCutPool::checkCutDomination(size_t idxA, size_t idxB) {
const CoinCut *cutB = cuts_[idxB];

/* checks if cutA dominates cutB */
if (cutA->dominates(cutB, iv_)) {
if (cutA->dominates(cutB)) {
return 0;
}

/* checks if cutB dominates cutA */
if (cutB->dominates(cutA, iv_)) {
if (cutB->dominates(cutA)) {
return 1;
}

Expand Down Expand Up @@ -405,32 +388,3 @@ void CoinCutPool::removeNullCuts() {
}
}

static void *xmalloc( const size_t size ) {
void *result = malloc( size );
if (!result) {
fprintf(stderr, "No more memory available. Trying to allocate %zu bytes.", size);
abort();
}

return result;
}

static void *xrealloc( void *ptr, const size_t size ) {
void * res = realloc( ptr, size );
if (!res) {
fprintf(stderr, "No more memory available. Trying to allocate %zu bytes in CoinCliqueList", size);
abort();
}

return res;
}

static void *xcalloc( const size_t elements, const size_t size ) {
void *result = calloc( elements, size );
if (!result) {
fprintf(stderr, "No more memory available. Trying to callocate %zu bytes.", size * elements);
abort();
}

return result;
}
43 changes: 12 additions & 31 deletions src/CoinCutPool.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@

#include "CoinUtilsConfig.h"
#include <cstddef>
#include <vector>

/**
* Class for representing a cut.
Expand All @@ -44,7 +45,7 @@ class COINUTILSLIB_EXPORT CoinCut {
* @param nz size of the cut
* @param rhs right-hand side of the cut
**/
CoinCut(const int *idxs, const double *coefs, int nz, double rhs);
CoinCut(const int *idxs, const double *coefs, size_t nz, double rhs);

/**
* Destructor
Expand All @@ -54,17 +55,17 @@ class COINUTILSLIB_EXPORT CoinCut {
/**
* Return the indexes of the variables of the cut.
**/
const int* idxs() const { return idxs_; }
const int* idxs() const { return idxs_.data(); }

/**
* Return the coefficients of the variables of the cut.
**/
const double* coefs() const { return coefs_; }
const double* coefs() const { return coefs_.data(); }

/**
* Return the size of the cut.
**/
int size() const { return nz_; }
int size() const { return idxs_.size(); }

/**
* Return the right-hand side of the cut.
Expand All @@ -75,27 +76,19 @@ class COINUTILSLIB_EXPORT CoinCut {
* Check if the cut dominates another one.
*
* @param other cut to be checked.
* @param iv incidence array with size equal to the
* number of cols of the MILP. All entries must be
* initialized as false.
**/
bool dominates(const CoinCut *other, bool *iv) const;
bool dominates(const CoinCut *other) const;

private:
/**
* indexes of the variables of the cut
**/
int *idxs_;
std::vector<int> idxs_;

/**
* coefficients of the variables of the cut
**/
double *coefs_;

/**
* size of the cut
**/
int nz_;
std::vector<double> coefs_;

/**
* right-hand side of the cut
Expand Down Expand Up @@ -208,7 +201,7 @@ class COINUTILSLIB_EXPORT CoinCutPool {
/**
* Array of pointers to the cuts stored in the pool.
**/
CoinCut **cuts_;
std::vector<CoinCut *> cuts_;

/**
* Number of cuts stored in the pool.
Expand All @@ -224,30 +217,18 @@ class COINUTILSLIB_EXPORT CoinCutPool {
* For each cut, stores the number of variables in
* which it has the best score.
**/
size_t *cutFrequency_;
std::vector<size_t> cutFrequency_;

/**
* Score of each cut
**/
double *cutFitness_;

/**
* Incidence array used in the method
* that checks the dominance between two cuts.
**/
bool *iv_;

/**
* Number of variables of the MILP associated
* with the cuts.
**/
int nCols_;
std::vector<double> cutFitness_;

/**
* For each variable, stores the index of the cut
* with the best score that contains this variable.
**/
size_t *bestCutByCol_;
std::vector<int> bestCutByCol_;

/**
* Number of cuts that were deleted from the pool.
Expand Down
Loading

0 comments on commit 4b930fe

Please sign in to comment.