From 8bf665299a47cd6671b8a460a155f6b5f0678379 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Apitzsch?= Date: Thu, 1 Aug 2024 14:24:17 +0200 Subject: [PATCH 1/5] CoinDenseVector: Replace pointer array by std::vector --- src/CoinDenseVector.cpp | 83 +++++++++++++++++------------------------ src/CoinDenseVector.hpp | 43 +++++++++++---------- 2 files changed, 56 insertions(+), 70 deletions(-) diff --git a/src/CoinDenseVector.cpp b/src/CoinDenseVector.cpp index 43bddaf4..82259c6a 100644 --- a/src/CoinDenseVector.cpp +++ b/src/CoinDenseVector.cpp @@ -16,7 +16,7 @@ template < typename T > void CoinDenseVector< T >::clear() { - memset(elements_, 0, nElements_ * sizeof(T)); + elements_.clear(); } //############################################################################# @@ -36,8 +36,7 @@ CoinDenseVector< T >::operator=(const CoinDenseVector< T > &rhs) template < typename T > void CoinDenseVector< T >::setVector(int size, const T *elems) { - resize(size); - CoinMemcpyN(elems, size, elements_); + elements_ = std::vector(elems, elems + size); } //############################################################################# @@ -53,27 +52,20 @@ void CoinDenseVector< T >::setConstant(int size, T value) //############################################################################# template < typename T > -void CoinDenseVector< T >::resize(int newsize, T value) +void CoinDenseVector< T >::resize(size_t newsize, T value) { - if (newsize != nElements_) { + if (newsize != elements_.size()) { assert(newsize > 0); - T *newarray = new T[newsize]; - int cpysize = std::min(newsize, nElements_); - CoinMemcpyN(elements_, cpysize, newarray); - delete[] elements_; - elements_ = newarray; - nElements_ = newsize; - for (int i = cpysize; i < newsize; i++) - elements_[i] = value; + elements_.resize(newsize, value); } } //############################################################################# template < typename T > -void CoinDenseVector< T >::setElement(int index, T element) +void CoinDenseVector< T >::setElement(size_t index, T element) { - assert(index >= 0 && index < nElements_); + assert(index < elements_.size()); elements_[index] = element; } @@ -82,12 +74,10 @@ void CoinDenseVector< T >::setElement(int index, T element) template < typename T > void CoinDenseVector< T >::append(const CoinDenseVector< T > &caboose) { - const int s = nElements_; const int cs = caboose.getNumElements(); - int newsize = s + cs; - resize(newsize); const T *celem = caboose.getElements(); - CoinDisjointCopyN(celem, cs, elements_ + s); + for (int i = 0; i< cs; ++i) + elements_.push_back(celem[i]); } //############################################################################# @@ -95,7 +85,7 @@ void CoinDenseVector< T >::append(const CoinDenseVector< T > &caboose) template < typename T > void CoinDenseVector< T >::operator+=(T value) { - for (int i = 0; i < nElements_; i++) + for (size_t i = 0; i < elements_.size(); i++) elements_[i] += value; } @@ -104,7 +94,7 @@ void CoinDenseVector< T >::operator+=(T value) template < typename T > void CoinDenseVector< T >::operator-=(T value) { - for (int i = 0; i < nElements_; i++) + for (size_t i = 0; i < elements_.size(); i++) elements_[i] -= value; } @@ -113,7 +103,7 @@ void CoinDenseVector< T >::operator-=(T value) template < typename T > void CoinDenseVector< T >::operator*=(T value) { - for (int i = 0; i < nElements_; i++) + for (size_t i = 0; i < elements_.size(); i++) elements_[i] *= value; } @@ -122,7 +112,7 @@ void CoinDenseVector< T >::operator*=(T value) template < typename T > void CoinDenseVector< T >::operator/=(T value) { - for (int i = 0; i < nElements_; i++) + for (size_t i = 0; i < elements_.size(); i++) elements_[i] /= value; } @@ -130,37 +120,31 @@ void CoinDenseVector< T >::operator/=(T value) template < typename T > CoinDenseVector< T >::CoinDenseVector() - : nElements_(0) - , elements_(NULL) + : elements_() { } //############################################################################# template < typename T > -CoinDenseVector< T >::CoinDenseVector(int size, const T *elems) - : nElements_(0) - , elements_(NULL) +CoinDenseVector< T >::CoinDenseVector(size_t size, const T *elems) + : elements_(elems, elems + size) { - gutsOfSetVector(size, elems); } //----------------------------------------------------------------------------- template < typename T > -CoinDenseVector< T >::CoinDenseVector(int size, T value) - : nElements_(0) - , elements_(NULL) +CoinDenseVector< T >::CoinDenseVector(size_t size, T value) + : elements_(size, value) { - gutsOfSetConstant(size, value); } //----------------------------------------------------------------------------- template < typename T > CoinDenseVector< T >::CoinDenseVector(const CoinDenseVector< T > &rhs) - : nElements_(0) - , elements_(NULL) + : elements_() { setVector(rhs.getNumElements(), rhs.getElements()); } @@ -170,30 +154,25 @@ CoinDenseVector< T >::CoinDenseVector(const CoinDenseVector< T > &rhs) template < typename T > CoinDenseVector< T >::~CoinDenseVector() { - delete[] elements_; } //############################################################################# template < typename T > -void CoinDenseVector< T >::gutsOfSetVector(int size, const T *elems) +void CoinDenseVector< T >::gutsOfSetVector(size_t size, const T *elems) { if (size != 0) { - resize(size); - nElements_ = size; - CoinDisjointCopyN(elems, size, elements_); + elements_= std::vector(elems, elems + size); } } //----------------------------------------------------------------------------- template < typename T > -void CoinDenseVector< T >::gutsOfSetConstant(int size, T value) +void CoinDenseVector< T >::gutsOfSetConstant(size_t size, T value) { if (size != 0) { - resize(size); - nElements_ = size; - CoinFillN(elements_, size, value); + elements_ = std::vector(size, value); } } @@ -201,11 +180,19 @@ void CoinDenseVector< T >::gutsOfSetConstant(int size, T value) /** Access the i'th element of the dense vector. */ template < typename T > T & - CoinDenseVector< T >::operator[](int index) const + CoinDenseVector< T >::operator[](size_t index) +{ + assert(index < elements_.size()); + return elements_[index]; +} + +/** Access the i'th element of the dense vector. */ +template < typename T > +const T & + CoinDenseVector< T >::operator[](size_t index) const { - assert(index >= 0 && index < nElements_); - T *where = elements_ + index; - return *where; + assert(index < elements_.size()); + return elements_[index]; } //############################################################################# diff --git a/src/CoinDenseVector.hpp b/src/CoinDenseVector.hpp index abd4cd84..89082693 100644 --- a/src/CoinDenseVector.hpp +++ b/src/CoinDenseVector.hpp @@ -13,6 +13,8 @@ #include #include #include +#include +#include #include "CoinHelperFunctions.hpp" //############################################################################# @@ -68,22 +70,20 @@ class CoinDenseVector { private: /**@name Private member data */ //@{ - /// Size of element vector - int nElements_; ///Vector elements - T *elements_; + std::vector elements_; //@} public: /**@name Get methods. */ //@{ /// Get the size - inline int getNumElements() const { return nElements_; } - inline int size() const { return nElements_; } + inline int getNumElements() const { return elements_.size(); } + inline int size() const { return elements_.size(); } /// Get element values - inline const T *getElements() const { return elements_; } + inline const T *getElements() const { return elements_.data(); } /// Get element values - inline T *getElements() { return elements_; } + inline T *getElements() { return elements_.data(); } //@} //------------------------------------------------------------------- @@ -96,7 +96,9 @@ class CoinDenseVector { /** Assignment operator */ CoinDenseVector &operator=(const CoinDenseVector &); /** Member of array operator */ - T &operator[](int index) const; + T &operator[](size_t index); + /** Member of array operator */ + const T &operator[](size_t index) const; /** Set vector size, and elements. Size is the length of the elements vector. @@ -110,11 +112,11 @@ class CoinDenseVector { /** Set an existing element in the dense vector The first argument is the "index" into the elements() array */ - void setElement(int index, T element); + void setElement(size_t index, T element); /** Resize the dense vector to be the first newSize elements. If length is decreased, vector is truncated. If increased new entries, set to new default element */ - void resize(int newSize, T fill = T()); + void resize(size_t newSize, T fill = T()); /** Append a dense vector to this dense vector */ void append(const CoinDenseVector &); @@ -126,7 +128,7 @@ class CoinDenseVector { inline T oneNorm() const { T norm = 0; - for (int i = 0; i < nElements_; i++) + for (size_t i = 0; i < elements_.size(); i++) norm += CoinAbs(elements_[i]); return norm; } @@ -134,7 +136,7 @@ class CoinDenseVector { inline double twoNorm() const { double norm = 0.; - for (int i = 0; i < nElements_; i++) + for (size_t i = 0; i < elements_.size(); i++) norm += elements_[i] * elements_[i]; // std namespace removed because it was causing a compile // problem with Microsoft Visual C++ @@ -144,22 +146,19 @@ class CoinDenseVector { inline T infNorm() const { T norm = 0; - for (int i = 0; i < nElements_; i++) + for (size_t i = 0; i < elements_.size(); i++) norm = std::max(norm, CoinAbs(elements_[i])); return norm; } /// sum of vector elements inline T sum() const { - T sume = 0; - for (int i = 0; i < nElements_; i++) - sume += elements_[i]; - return sume; + return std::accumulate(elements_.begin(), elements_.end(), 0); } /// scale vector elements inline void scale(T factor) { - for (int i = 0; i < nElements_; i++) + for (size_t i = 0; i < elements_.size(); i++) elements_[i] *= factor; return; } @@ -182,9 +181,9 @@ class CoinDenseVector { /** Default constructor */ CoinDenseVector(); /** Alternate Constructors - set elements to vector of Ts */ - CoinDenseVector(int size, const T *elems); + CoinDenseVector(size_t size, const T *elems); /** Alternate Constructors - set elements to same scalar value */ - CoinDenseVector(int size, T element = T()); + CoinDenseVector(size_t size, T element = T()); /** Copy constructors */ CoinDenseVector(const CoinDenseVector &); @@ -196,9 +195,9 @@ class CoinDenseVector { /**@name Private methods */ //@{ /// Copy internal data - void gutsOfSetVector(int size, const T *elems); + void gutsOfSetVector(size_t size, const T *elems); /// Set all elements to a given value - void gutsOfSetConstant(int size, T value); + void gutsOfSetConstant(size_t size, T value); //@} }; From eb73752b77b78d882dac37c8670cfbf90e59f0b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Apitzsch?= Date: Thu, 1 Aug 2024 15:09:18 +0200 Subject: [PATCH 2/5] CoinCut: Replace pointer arrays by std::vector --- src/CoinCutPool.cpp | 30 ++++++++---------------------- src/CoinCutPool.hpp | 18 +++++++----------- 2 files changed, 15 insertions(+), 33 deletions(-) diff --git a/src/CoinCutPool.cpp b/src/CoinCutPool.cpp index 983d19af..1881db26 100644 --- a/src/CoinCutPool.cpp +++ b/src/CoinCutPool.cpp @@ -36,7 +36,6 @@ 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; } @@ -48,17 +47,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(nz)) + , coefs_(std::vector(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]; @@ -67,14 +65,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; @@ -425,12 +420,3 @@ static void *xrealloc( void *ptr, const size_t size ) { 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; -} \ No newline at end of file diff --git a/src/CoinCutPool.hpp b/src/CoinCutPool.hpp index 4c994937..b835cbbf 100644 --- a/src/CoinCutPool.hpp +++ b/src/CoinCutPool.hpp @@ -30,6 +30,7 @@ #include "CoinUtilsConfig.h" #include +#include /** * Class for representing a cut. @@ -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 @@ -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. @@ -85,17 +86,12 @@ class COINUTILSLIB_EXPORT CoinCut { /** * indexes of the variables of the cut **/ - int *idxs_; + std::vector idxs_; /** * coefficients of the variables of the cut **/ - double *coefs_; - - /** - * size of the cut - **/ - int nz_; + std::vector coefs_; /** * right-hand side of the cut From 6288250e688a997353814e7bd6e47455dd232a77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Apitzsch?= Date: Thu, 1 Aug 2024 15:39:09 +0200 Subject: [PATCH 3/5] CoinCutPool: Replace pointer arrays by std::vector While at it fix the type of `bestCutByCol_` to support negative values. --- src/CoinCutPool.cpp | 54 +++++++++------------------------------------ src/CoinCutPool.hpp | 25 +++++---------------- 2 files changed, 16 insertions(+), 63 deletions(-) diff --git a/src/CoinCutPool.cpp b/src/CoinCutPool.cpp index 1881db26..18d6e19e 100644 --- a/src/CoinCutPool.cpp +++ b/src/CoinCutPool.cpp @@ -34,9 +34,6 @@ #define CUTPOOL_EPS 1e-8 -static void *xmalloc( const size_t size ); -static void *xrealloc( void *ptr, const size_t size ); - struct CompareIdxs { explicit CompareIdxs(const int *idxs) { this->idxs_ = idxs; } @@ -88,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; @@ -105,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 iv(sizeB, false); if (fabs(rhsA) <= CUTPOOL_EPS) { normConstA = 1.0; @@ -154,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(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(cutsCap_); + cutFrequency_ = std::vector(cutsCap_); + cutFitness_ = std::vector(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) { @@ -272,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() { @@ -328,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; } @@ -400,23 +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; -} - diff --git a/src/CoinCutPool.hpp b/src/CoinCutPool.hpp index b835cbbf..3da276a7 100644 --- a/src/CoinCutPool.hpp +++ b/src/CoinCutPool.hpp @@ -76,11 +76,8 @@ 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: /** @@ -204,7 +201,7 @@ class COINUTILSLIB_EXPORT CoinCutPool { /** * Array of pointers to the cuts stored in the pool. **/ - CoinCut **cuts_; + std::vector cuts_; /** * Number of cuts stored in the pool. @@ -220,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 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 cutFitness_; /** * For each variable, stores the index of the cut * with the best score that contains this variable. **/ - size_t *bestCutByCol_; + std::vector bestCutByCol_; /** * Number of cuts that were deleted from the pool. From fa2bec29de14c8e2bf65fd24ccd7c4ef346b4e7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Apitzsch?= Date: Thu, 1 Aug 2024 15:57:11 +0200 Subject: [PATCH 4/5] CoinNodeHeap: Replace pointer arrays by std::vector --- src/CoinNodeHeap.cpp | 20 +++----------------- src/CoinNodeHeap.hpp | 5 +++-- 2 files changed, 6 insertions(+), 19 deletions(-) diff --git a/src/CoinNodeHeap.cpp b/src/CoinNodeHeap.cpp index d96152c6..24da5298 100644 --- a/src/CoinNodeHeap.cpp +++ b/src/CoinNodeHeap.cpp @@ -31,22 +31,17 @@ // position of the first child node in vector #define childPos(node) ((node * 2) + 1) -static void *xmalloc( const size_t size ); - CoinNodeHeap::CoinNodeHeap(size_t numNodes) { #ifdef DEBUGCG assert(numNodes > 0); #endif numNodes_ = numNodes; - pq_ = (std::pair*)xmalloc(sizeof(std::pair) * numNodes_); - pos_ = (size_t*)xmalloc(sizeof(size_t) * numNodes_); + pq_ = std::vector >(numNodes); + pos_ = std::vector(numNodes); reset(); } -CoinNodeHeap::~CoinNodeHeap() { - free(pq_); - free(pos_); -} +CoinNodeHeap::~CoinNodeHeap() {} void CoinNodeHeap::reset() { for (size_t i = 0; i < numNodes_; i++) { @@ -111,12 +106,3 @@ bool CoinNodeHeap::isEmpty() const { return (pq_[0].second >= NODEHEAP_INFTY); } -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; -} \ No newline at end of file diff --git a/src/CoinNodeHeap.hpp b/src/CoinNodeHeap.hpp index 853765b3..90a3a876 100644 --- a/src/CoinNodeHeap.hpp +++ b/src/CoinNodeHeap.hpp @@ -22,6 +22,7 @@ #include "CoinUtilsConfig.h" #include #include +#include /** * Monotone heap. @@ -68,12 +69,12 @@ class COINUTILSLIB_EXPORT CoinNodeHeap { /** * Priority queue itself **/ - std::pair *pq_; + std::vector > pq_; /** * Indicates the position of each node in pq **/ - size_t *pos_; + std::vector pos_; /** * Number of nodes of the heap. From 268c1427dd641a07eb2b4ae4c296cec2785f574d Mon Sep 17 00:00:00 2001 From: Ted Ralphs Date: Sun, 18 Aug 2024 22:28:00 +0200 Subject: [PATCH 5/5] Fix stupid typo --- src/CoinDenseVector.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CoinDenseVector.hpp b/src/CoinDenseVector.hpp index f4921681..fb8f20e4 100644 --- a/src/CoinDenseVector.hpp +++ b/src/CoinDenseVector.hpp @@ -147,7 +147,7 @@ class CoinDenseVector { { T norm = 0; for (size_t i = 0; i < elements_.size(); i++) - norm = std::max(norm, std:abs(elements_[i])); + norm = std::max(norm, std::abs(elements_[i])); return norm; } /// sum of vector elements